mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-13 05:07:43 +02:00
TSK-810 Rename Team -> Project, Project -> Component (#2756)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
+84
-79
@@ -64,13 +64,13 @@ import {
|
||||
IssueStatusCategory,
|
||||
IssueTemplate,
|
||||
IssueTemplateChild,
|
||||
Project,
|
||||
ProjectStatus,
|
||||
Component,
|
||||
ComponentStatus,
|
||||
Scrum,
|
||||
ScrumRecord,
|
||||
Sprint,
|
||||
SprintStatus,
|
||||
Team,
|
||||
Project,
|
||||
TimeReportDayType,
|
||||
TimeSpendReport,
|
||||
trackerId,
|
||||
@@ -132,8 +132,8 @@ export class TTypeIssuePriority extends TType {}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function TypeProjectStatus (): Type<ProjectStatus> {
|
||||
return { _class: tracker.class.TypeProjectStatus, label: 'TypeProjectStatus' as IntlString }
|
||||
export function TypeComponentStatus (): Type<ComponentStatus> {
|
||||
return { _class: tracker.class.TypeComponentStatus, label: 'TypeComponentStatus' as IntlString }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,8 +146,8 @@ export function TypeSprintStatus (): Type<SprintStatus> {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.TypeProjectStatus, core.class.Type, DOMAIN_MODEL)
|
||||
export class TTypeProjectStatus extends TType {}
|
||||
@Model(tracker.class.TypeComponentStatus, core.class.Type, DOMAIN_MODEL)
|
||||
export class TTypeComponentStatus extends TType {}
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -158,9 +158,9 @@ export class TTypeSprintStatus extends TType {}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.Team, core.class.Space, DOMAIN_SPACE)
|
||||
@UX(tracker.string.Team, tracker.icon.Team, 'TEAM')
|
||||
export class TTeam extends TSpace implements Team {
|
||||
@Model(tracker.class.Project, core.class.Space, DOMAIN_SPACE)
|
||||
@UX(tracker.string.Project, tracker.icon.Project, 'Project')
|
||||
export class TProject extends TSpace implements Project {
|
||||
@Prop(TypeString(), tracker.string.Title)
|
||||
@Index(IndexKind.FullText)
|
||||
reamLogo!: IntlString
|
||||
@@ -226,9 +226,9 @@ export class TIssue extends TAttachedDoc implements Issue {
|
||||
@Index(IndexKind.Indexed)
|
||||
assignee!: Ref<Employee> | null
|
||||
|
||||
@Prop(TypeRef(tracker.class.Project), tracker.string.Project)
|
||||
@Prop(TypeRef(tracker.class.Component), tracker.string.Component)
|
||||
@Index(IndexKind.Indexed)
|
||||
project!: Ref<Project> | null
|
||||
component!: Ref<Component> | null
|
||||
|
||||
@Prop(Collection(tracker.class.Issue), tracker.string.SubIssues)
|
||||
subIssues!: number
|
||||
@@ -250,7 +250,7 @@ export class TIssue extends TAttachedDoc implements Issue {
|
||||
@Prop(Collection(tags.class.TagReference), tracker.string.Labels)
|
||||
labels?: number
|
||||
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
|
||||
@Prop(TypeDate(DateRangeMode.DATETIME), tracker.string.DueDate)
|
||||
dueDate!: Timestamp | null
|
||||
@@ -296,13 +296,13 @@ export class TIssueTemplate extends TDoc implements IssueTemplate {
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.Assignee)
|
||||
assignee!: Ref<Employee> | null
|
||||
|
||||
@Prop(TypeRef(tracker.class.Project), tracker.string.Project)
|
||||
project!: Ref<Project> | null
|
||||
@Prop(TypeRef(tracker.class.Component), tracker.string.Component)
|
||||
component!: Ref<Component> | null
|
||||
|
||||
@Prop(ArrOf(TypeRef(tags.class.TagElement)), tracker.string.Labels)
|
||||
labels?: Ref<TagElement>[]
|
||||
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
|
||||
@Prop(TypeDate(DateRangeMode.DATETIME), tracker.string.DueDate)
|
||||
dueDate!: Timestamp | null
|
||||
@@ -351,9 +351,9 @@ export class TTimeSpendReport extends TAttachedDoc implements TimeSpendReport {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@Model(tracker.class.Project, core.class.Doc, DOMAIN_TRACKER)
|
||||
@UX(tracker.string.Project, tracker.icon.Project, 'PROJECT')
|
||||
export class TProject extends TDoc implements Project {
|
||||
@Model(tracker.class.Component, core.class.Doc, DOMAIN_TRACKER)
|
||||
@UX(tracker.string.Component, tracker.icon.Component, 'COMPONENT')
|
||||
export class TComponent extends TDoc implements Component {
|
||||
@Prop(TypeString(), tracker.string.Title)
|
||||
// @Index(IndexKind.FullText)
|
||||
label!: string
|
||||
@@ -364,10 +364,10 @@ export class TProject extends TDoc implements Project {
|
||||
@Prop(TypeString(), tracker.string.AssetLabel)
|
||||
icon!: Asset
|
||||
|
||||
@Prop(TypeProjectStatus(), tracker.string.Status)
|
||||
status!: ProjectStatus
|
||||
@Prop(TypeComponentStatus(), tracker.string.Status)
|
||||
status!: ComponentStatus
|
||||
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.ProjectLead)
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.ComponentLead)
|
||||
lead!: Ref<Employee> | null
|
||||
|
||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), tracker.string.Members)
|
||||
@@ -385,7 +385,7 @@ export class TProject extends TDoc implements Project {
|
||||
@Prop(TypeDate(DateRangeMode.DATETIME), tracker.string.TargetDate)
|
||||
targetDate!: Timestamp | null
|
||||
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,7 +405,7 @@ export class TSprint extends TDoc implements Sprint {
|
||||
@Index(IndexKind.Indexed)
|
||||
status!: SprintStatus
|
||||
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.ProjectLead)
|
||||
@Prop(TypeRef(contact.class.Employee), tracker.string.ComponentLead)
|
||||
lead!: Ref<Employee> | null
|
||||
|
||||
@Prop(ArrOf(TypeRef(contact.class.Employee)), tracker.string.Members)
|
||||
@@ -423,14 +423,14 @@ export class TSprint extends TDoc implements Sprint {
|
||||
@Prop(TypeDate(), tracker.string.TargetDate)
|
||||
targetDate!: Timestamp
|
||||
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
|
||||
@Prop(TypeNumber(), tracker.string.Capacity)
|
||||
capacity!: number
|
||||
|
||||
@Prop(TypeRef(tracker.class.Project), tracker.string.Project)
|
||||
@Prop(TypeRef(tracker.class.Component), tracker.string.Component)
|
||||
@Index(IndexKind.Indexed)
|
||||
project!: Ref<Project>
|
||||
component!: Ref<Component>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,7 +460,7 @@ export class TScrum extends TDoc implements Scrum {
|
||||
@Prop(TypeDate(DateRangeMode.TIME), tracker.string.ScrumEndTime)
|
||||
endTime!: Timestamp
|
||||
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,7 +485,7 @@ export class TScrumRecord extends TAttachedDoc implements ScrumRecord {
|
||||
attachments!: number
|
||||
|
||||
declare attachedTo: Ref<Scrum>
|
||||
declare space: Ref<Team>
|
||||
declare space: Ref<Project>
|
||||
declare scrumRecorder: Ref<EmployeeAccount>
|
||||
}
|
||||
|
||||
@@ -495,14 +495,14 @@ export class TTypeReportedTime extends TType {}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(
|
||||
TTeam,
|
||||
TProject,
|
||||
TComponent,
|
||||
TIssue,
|
||||
TIssueTemplate,
|
||||
TIssueStatus,
|
||||
TIssueStatusCategory,
|
||||
TTypeIssuePriority,
|
||||
TTypeProjectStatus,
|
||||
TTypeComponentStatus,
|
||||
TSprint,
|
||||
TScrum,
|
||||
TScrumRecord,
|
||||
@@ -512,7 +512,7 @@ export function createModel (builder: Builder): void {
|
||||
)
|
||||
|
||||
const issuesOptions: ViewOptionsModel = {
|
||||
groupBy: ['status', 'assignee', 'priority', 'project', 'sprint'],
|
||||
groupBy: ['status', 'assignee', 'priority', 'component', 'sprint'],
|
||||
orderBy: [
|
||||
['status', SortingOrder.Ascending],
|
||||
['priority', SortingOrder.Ascending],
|
||||
@@ -574,14 +574,14 @@ export function createModel (builder: Builder): void {
|
||||
{ key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } },
|
||||
{
|
||||
key: '',
|
||||
presenter: tracker.component.ProjectEditor,
|
||||
presenter: tracker.component.ComponentEditor,
|
||||
props: {
|
||||
kind: 'list',
|
||||
size: 'small',
|
||||
shape: 'round',
|
||||
shouldShowPlaceholder: false,
|
||||
listProps: {
|
||||
excludeByKey: 'project',
|
||||
excludeByKey: 'component',
|
||||
optional: true
|
||||
}
|
||||
}
|
||||
@@ -702,7 +702,7 @@ export function createModel (builder: Builder): void {
|
||||
attachTo: tracker.class.IssueTemplate,
|
||||
descriptor: view.viewlet.List,
|
||||
viewOptions: {
|
||||
groupBy: ['assignee', 'priority', 'project', 'sprint'],
|
||||
groupBy: ['assignee', 'priority', 'component', 'sprint'],
|
||||
orderBy: [
|
||||
['priority', SortingOrder.Ascending],
|
||||
['modifiedOn', SortingOrder.Descending],
|
||||
@@ -722,7 +722,7 @@ export function createModel (builder: Builder): void {
|
||||
// { key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } },
|
||||
{
|
||||
key: '',
|
||||
presenter: tracker.component.ProjectEditor,
|
||||
presenter: tracker.component.ComponentEditor,
|
||||
props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false }
|
||||
},
|
||||
{
|
||||
@@ -841,7 +841,7 @@ export function createModel (builder: Builder): void {
|
||||
const activeId = 'active'
|
||||
const backlogId = 'backlog'
|
||||
const boardId = 'board'
|
||||
const projectsId = 'projects'
|
||||
const componentsId = 'components'
|
||||
const sprintsId = 'sprints'
|
||||
const templatesId = 'templates'
|
||||
// const scrumsId = 'scrums'
|
||||
@@ -902,18 +902,23 @@ export function createModel (builder: Builder): void {
|
||||
presenter: tracker.component.PriorityRefPresenter
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Component, core.class.Class, view.mixin.ObjectPresenter, {
|
||||
presenter: tracker.component.ComponentPresenter
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Project, core.class.Class, view.mixin.ObjectPresenter, {
|
||||
presenter: tracker.component.ProjectPresenter
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Team, core.class.Class, view.mixin.ObjectPresenter, {
|
||||
presenter: tracker.component.TeamPresenter
|
||||
})
|
||||
classPresenter(
|
||||
builder,
|
||||
tracker.class.Component,
|
||||
tracker.component.ComponentSelector,
|
||||
tracker.component.ComponentSelector
|
||||
)
|
||||
|
||||
classPresenter(builder, tracker.class.Project, tracker.component.ProjectSelector, tracker.component.ProjectSelector)
|
||||
|
||||
builder.mixin(tracker.class.Project, core.class.Class, view.mixin.AttributeEditor, {
|
||||
inlineEditor: tracker.component.ProjectSelector
|
||||
builder.mixin(tracker.class.Component, core.class.Class, view.mixin.AttributeEditor, {
|
||||
inlineEditor: tracker.component.ComponentSelector
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Sprint, core.class.Class, view.mixin.ObjectPresenter, {
|
||||
@@ -928,8 +933,8 @@ export function createModel (builder: Builder): void {
|
||||
value: true
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.TypeProjectStatus, core.class.Class, view.mixin.AttributeEditor, {
|
||||
inlineEditor: tracker.component.ProjectStatusEditor
|
||||
builder.mixin(tracker.class.TypeComponentStatus, core.class.Class, view.mixin.AttributeEditor, {
|
||||
inlineEditor: tracker.component.ComponentStatusEditor
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Issue, core.class.Class, notification.mixin.LastViewAttached, {})
|
||||
@@ -945,8 +950,8 @@ export function createModel (builder: Builder): void {
|
||||
func: tracker.function.GetAllPriority
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Project, core.class.Class, view.mixin.AllValuesFunc, {
|
||||
func: tracker.function.GetAllProjects
|
||||
builder.mixin(tracker.class.Component, core.class.Class, view.mixin.AllValuesFunc, {
|
||||
func: tracker.function.GetAllComponents
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Sprint, core.class.Class, view.mixin.AllValuesFunc, {
|
||||
@@ -1001,16 +1006,16 @@ export function createModel (builder: Builder): void {
|
||||
id: 'roadmap',
|
||||
position: 'top',
|
||||
label: tracker.string.Roadmap,
|
||||
icon: tracker.icon.Projects,
|
||||
icon: tracker.icon.Components,
|
||||
component: tracker.component.Roadmap
|
||||
}
|
||||
],
|
||||
spaces: [
|
||||
{
|
||||
label: tracker.string.Teams,
|
||||
spaceClass: tracker.class.Team,
|
||||
addSpaceLabel: tracker.string.CreateTeam,
|
||||
createComponent: tracker.component.CreateTeam,
|
||||
label: tracker.string.Projects,
|
||||
spaceClass: tracker.class.Project,
|
||||
addSpaceLabel: tracker.string.CreateProject,
|
||||
createComponent: tracker.component.CreateProject,
|
||||
icon: tracker.icon.Home,
|
||||
specials: [
|
||||
{
|
||||
@@ -1032,10 +1037,10 @@ export function createModel (builder: Builder): void {
|
||||
component: tracker.component.Backlog
|
||||
},
|
||||
{
|
||||
id: projectsId,
|
||||
label: tracker.string.Projects,
|
||||
icon: tracker.icon.Projects,
|
||||
component: tracker.component.TeamProjects
|
||||
id: componentsId,
|
||||
label: tracker.string.Components,
|
||||
icon: tracker.icon.Components,
|
||||
component: tracker.component.ProjectComponents
|
||||
},
|
||||
{
|
||||
id: sprintsId,
|
||||
@@ -1069,7 +1074,7 @@ export function createModel (builder: Builder): void {
|
||||
application: trackerId,
|
||||
mode: 'space',
|
||||
spaceSpecial: id,
|
||||
spaceClass: tracker.class.Team
|
||||
spaceClass: tracker.class.Project
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1077,7 +1082,7 @@ export function createModel (builder: Builder): void {
|
||||
createGotoSpecialAction(builder, activeId, 'g->a', tracker.string.GotoActive)
|
||||
createGotoSpecialAction(builder, backlogId, 'g->b', tracker.string.GotoBacklog)
|
||||
createGotoSpecialAction(builder, boardId, 'g->d', tracker.string.GotoBoard)
|
||||
createGotoSpecialAction(builder, projectsId, 'g->p', tracker.string.GotoProjects)
|
||||
createGotoSpecialAction(builder, componentsId, 'g->c', tracker.string.GotoComponents)
|
||||
|
||||
createAction(builder, {
|
||||
action: workbench.actionImpl.Navigate,
|
||||
@@ -1103,7 +1108,7 @@ export function createModel (builder: Builder): void {
|
||||
icon: view.icon.Statuses,
|
||||
input: 'focus',
|
||||
category: tracker.category.Tracker,
|
||||
target: tracker.class.Team,
|
||||
target: tracker.class.Project,
|
||||
query: {
|
||||
archived: false
|
||||
},
|
||||
@@ -1118,12 +1123,12 @@ export function createModel (builder: Builder): void {
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: tracker.actionImpl.EditTeam,
|
||||
label: tracker.string.EditTeam,
|
||||
action: tracker.actionImpl.EditProject,
|
||||
label: tracker.string.EditProject,
|
||||
icon: contact.icon.Edit,
|
||||
input: 'focus',
|
||||
category: tracker.category.Tracker,
|
||||
target: tracker.class.Team,
|
||||
target: tracker.class.Project,
|
||||
query: {
|
||||
archived: false
|
||||
},
|
||||
@@ -1132,18 +1137,18 @@ export function createModel (builder: Builder): void {
|
||||
group: 'edit'
|
||||
}
|
||||
},
|
||||
tracker.action.EditTeam
|
||||
tracker.action.EditProject
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: tracker.actionImpl.DeleteTeam,
|
||||
label: tracker.string.DeleteTeam,
|
||||
action: tracker.actionImpl.DeleteProject,
|
||||
label: tracker.string.DeleteProject,
|
||||
icon: view.icon.Delete,
|
||||
input: 'focus',
|
||||
category: tracker.category.Tracker,
|
||||
target: tracker.class.Team,
|
||||
target: tracker.class.Project,
|
||||
query: {
|
||||
archived: false
|
||||
},
|
||||
@@ -1152,7 +1157,7 @@ export function createModel (builder: Builder): void {
|
||||
group: 'edit'
|
||||
}
|
||||
},
|
||||
tracker.action.DeleteTeam
|
||||
tracker.action.DeleteProject
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
@@ -1449,15 +1454,15 @@ export function createModel (builder: Builder): void {
|
||||
action: view.actionImpl.ValueSelector,
|
||||
actionPopup: view.component.ValueSelector,
|
||||
actionProps: {
|
||||
attribute: 'project',
|
||||
_class: tracker.class.Project,
|
||||
attribute: 'component',
|
||||
_class: tracker.class.Component,
|
||||
query: {},
|
||||
searchField: 'label',
|
||||
placeholder: tracker.string.Project
|
||||
placeholder: tracker.string.Component
|
||||
},
|
||||
label: tracker.string.Project,
|
||||
icon: tracker.icon.Project,
|
||||
keyBinding: ['keyP->keyP'],
|
||||
label: tracker.string.Component,
|
||||
icon: tracker.icon.Component,
|
||||
keyBinding: ['keyC'],
|
||||
input: 'any',
|
||||
category: tracker.category.Tracker,
|
||||
target: tracker.class.Issue,
|
||||
@@ -1467,7 +1472,7 @@ export function createModel (builder: Builder): void {
|
||||
group: 'edit'
|
||||
}
|
||||
},
|
||||
tracker.action.SetProject
|
||||
tracker.action.SetComponent
|
||||
)
|
||||
|
||||
createAction(
|
||||
@@ -1596,7 +1601,7 @@ export function createModel (builder: Builder): void {
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.Move,
|
||||
label: tracker.string.MoveToTeam,
|
||||
label: tracker.string.MoveToProject,
|
||||
icon: view.icon.Move,
|
||||
keyBinding: [],
|
||||
input: 'any',
|
||||
@@ -1608,7 +1613,7 @@ export function createModel (builder: Builder): void {
|
||||
group: 'associate'
|
||||
}
|
||||
},
|
||||
tracker.action.MoveToTeam
|
||||
tracker.action.MoveToProject
|
||||
)
|
||||
// TODO: fix icon
|
||||
createAction(
|
||||
@@ -1687,7 +1692,7 @@ export function createModel (builder: Builder): void {
|
||||
)
|
||||
|
||||
const sprintOptions: ViewOptionsModel = {
|
||||
groupBy: ['project', 'lead'],
|
||||
groupBy: ['component', 'lead'],
|
||||
orderBy: [
|
||||
['startDate', SortingOrder.Descending],
|
||||
['modifiedOn', SortingOrder.Descending],
|
||||
@@ -1712,7 +1717,7 @@ export function createModel (builder: Builder): void {
|
||||
},
|
||||
{ key: '', presenter: tracker.component.SprintPresenter, props: { shouldUseMargin: true } },
|
||||
{ key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } },
|
||||
{ key: '', presenter: tracker.component.SprintProjectEditor, props: { kind: 'list' } },
|
||||
{ key: '', presenter: tracker.component.SprintComponentEditor, props: { kind: 'list' } },
|
||||
{
|
||||
key: '',
|
||||
presenter: contact.component.MembersPresenter,
|
||||
|
||||
+327
-51
@@ -14,16 +14,20 @@
|
||||
//
|
||||
|
||||
import core, {
|
||||
Class,
|
||||
Doc,
|
||||
DocumentUpdate,
|
||||
DOMAIN_TX,
|
||||
generateId,
|
||||
Ref,
|
||||
SortingOrder,
|
||||
TxCreateDoc,
|
||||
TxOperations,
|
||||
TxResult
|
||||
TxResult,
|
||||
TxUpdateDoc
|
||||
} from '@hcengineering/core'
|
||||
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
||||
import { DOMAIN_SPACE } from '@hcengineering/model-core'
|
||||
import tags from '@hcengineering/tags'
|
||||
import {
|
||||
calcRank,
|
||||
@@ -31,7 +35,9 @@ import {
|
||||
Issue,
|
||||
IssueStatus,
|
||||
IssueStatusCategory,
|
||||
Team,
|
||||
IssueTemplate,
|
||||
IssueTemplateChild,
|
||||
Project,
|
||||
TimeReportDayType,
|
||||
WorkDayLength
|
||||
} from '@hcengineering/tracker'
|
||||
@@ -46,9 +52,9 @@ enum DeprecatedIssueStatus {
|
||||
Canceled
|
||||
}
|
||||
|
||||
interface CreateTeamIssueStatusesArgs {
|
||||
interface CreateProjectIssueStatusesArgs {
|
||||
tx: TxOperations
|
||||
teamId: Ref<Team>
|
||||
projectId: Ref<Project>
|
||||
categories: IssueStatusCategory[]
|
||||
defaultStatusId?: Ref<IssueStatus>
|
||||
defaultCategoryId?: Ref<IssueStatusCategory>
|
||||
@@ -62,13 +68,13 @@ const categoryByDeprecatedIssueStatus = {
|
||||
[DeprecatedIssueStatus.Canceled]: tracker.issueStatusCategory.Canceled
|
||||
} as const
|
||||
|
||||
async function createTeamIssueStatuses ({
|
||||
async function createProjectIssueStatuses ({
|
||||
tx,
|
||||
teamId: attachedTo,
|
||||
projectId: attachedTo,
|
||||
categories,
|
||||
defaultStatusId,
|
||||
defaultCategoryId = tracker.issueStatusCategory.Backlog
|
||||
}: CreateTeamIssueStatusesArgs): Promise<void> {
|
||||
}: CreateProjectIssueStatusesArgs): Promise<void> {
|
||||
const issueStatusRanks = [...genRanks(categories.length)]
|
||||
|
||||
for (const [i, statusCategory] of categories.entries()) {
|
||||
@@ -79,7 +85,7 @@ async function createTeamIssueStatuses ({
|
||||
tracker.class.IssueStatus,
|
||||
attachedTo,
|
||||
attachedTo,
|
||||
tracker.class.Team,
|
||||
tracker.class.Project,
|
||||
'issueStatuses',
|
||||
{ name: defaultStatusName, category, rank },
|
||||
category === defaultCategoryId ? defaultStatusId : undefined
|
||||
@@ -87,13 +93,13 @@ async function createTeamIssueStatuses ({
|
||||
}
|
||||
}
|
||||
|
||||
async function createDefaultTeam (tx: TxOperations): Promise<void> {
|
||||
const current = await tx.findOne(tracker.class.Team, {
|
||||
_id: tracker.team.DefaultTeam
|
||||
async function createDefaultProject (tx: TxOperations): Promise<void> {
|
||||
const current = await tx.findOne(tracker.class.Project, {
|
||||
_id: tracker.project.DefaultProject
|
||||
})
|
||||
|
||||
const currentDeleted = await tx.findOne(core.class.TxRemoveDoc, {
|
||||
objectId: tracker.team.DefaultTeam
|
||||
objectId: tracker.project.DefaultProject
|
||||
})
|
||||
|
||||
// Create new if not deleted by customers.
|
||||
@@ -105,12 +111,12 @@ async function createDefaultTeam (tx: TxOperations): Promise<void> {
|
||||
{ sort: { order: SortingOrder.Ascending } }
|
||||
)
|
||||
|
||||
await tx.createDoc<Team>(
|
||||
tracker.class.Team,
|
||||
await tx.createDoc<Project>(
|
||||
tracker.class.Project,
|
||||
core.space.Space,
|
||||
{
|
||||
name: 'Default',
|
||||
description: 'Default team',
|
||||
description: 'Default project',
|
||||
private: false,
|
||||
members: [],
|
||||
archived: false,
|
||||
@@ -122,16 +128,16 @@ async function createDefaultTeam (tx: TxOperations): Promise<void> {
|
||||
defaultAssignee: undefined,
|
||||
workDayLength: WorkDayLength.EIGHT_HOURS
|
||||
},
|
||||
tracker.team.DefaultTeam
|
||||
tracker.project.DefaultProject
|
||||
)
|
||||
await createTeamIssueStatuses({ tx, teamId: tracker.team.DefaultTeam, categories, defaultStatusId })
|
||||
await createProjectIssueStatuses({ tx, projectId: tracker.project.DefaultProject, categories, defaultStatusId })
|
||||
}
|
||||
}
|
||||
|
||||
async function fixTeamIssueStatusesOrder (tx: TxOperations, team: Team): Promise<TxResult> {
|
||||
async function fixProjectIssueStatusesOrder (tx: TxOperations, project: Project): Promise<TxResult> {
|
||||
const statuses = await tx.findAll(
|
||||
tracker.class.IssueStatus,
|
||||
{ attachedTo: team._id },
|
||||
{ attachedTo: project._id },
|
||||
{ lookup: { category: tracker.class.IssueStatusCategory } }
|
||||
)
|
||||
statuses.sort((a, b) => (a.$lookup?.category?.order ?? 0) - (b.$lookup?.category?.order ?? 0))
|
||||
@@ -143,19 +149,19 @@ async function fixTeamIssueStatusesOrder (tx: TxOperations, team: Team): Promise
|
||||
})
|
||||
}
|
||||
|
||||
async function fixTeamsIssueStatusesOrder (tx: TxOperations): Promise<void> {
|
||||
const teams = await tx.findAll(tracker.class.Team, {})
|
||||
await Promise.all(teams.map((team) => fixTeamIssueStatusesOrder(tx, team)))
|
||||
async function fixProjectsIssueStatusesOrder (tx: TxOperations): Promise<void> {
|
||||
const projects = await tx.findAll(tracker.class.Project, {})
|
||||
await Promise.all(projects.map((project) => fixProjectIssueStatusesOrder(tx, project)))
|
||||
}
|
||||
|
||||
async function upgradeTeamSettings (tx: TxOperations): Promise<void> {
|
||||
const teams = await tx.findAll(tracker.class.Team, {
|
||||
async function upgradeProjectSettings (tx: TxOperations): Promise<void> {
|
||||
const projects = await tx.findAll(tracker.class.Project, {
|
||||
defaultTimeReportDay: { $exists: false },
|
||||
workDayLength: { $exists: false }
|
||||
})
|
||||
await Promise.all(
|
||||
teams.map((team) =>
|
||||
tx.update(team, {
|
||||
projects.map((project) =>
|
||||
tx.update(project, {
|
||||
defaultTimeReportDay: TimeReportDayType.PreviousWorkDay,
|
||||
workDayLength: WorkDayLength.EIGHT_HOURS
|
||||
})
|
||||
@@ -163,21 +169,21 @@ async function upgradeTeamSettings (tx: TxOperations): Promise<void> {
|
||||
)
|
||||
}
|
||||
|
||||
async function upgradeTeamIssueStatuses (tx: TxOperations): Promise<void> {
|
||||
const teams = await tx.findAll(tracker.class.Team, { issueStatuses: undefined })
|
||||
async function upgradeProjectIssueStatuses (tx: TxOperations): Promise<void> {
|
||||
const projects = await tx.findAll(tracker.class.Project, { issueStatuses: undefined })
|
||||
|
||||
if (teams.length > 0) {
|
||||
if (projects.length > 0) {
|
||||
const categories = await tx.findAll(
|
||||
tracker.class.IssueStatusCategory,
|
||||
{},
|
||||
{ sort: { order: SortingOrder.Ascending } }
|
||||
)
|
||||
|
||||
for (const team of teams) {
|
||||
for (const project of projects) {
|
||||
const defaultStatusId: Ref<IssueStatus> = generateId()
|
||||
|
||||
await tx.update(team, { issueStatuses: 0, defaultIssueStatus: defaultStatusId })
|
||||
await createTeamIssueStatuses({ tx, teamId: team._id, categories, defaultStatusId })
|
||||
await tx.update(project, { issueStatuses: 0, defaultIssueStatus: defaultStatusId })
|
||||
await createProjectIssueStatuses({ tx, projectId: project._id, categories, defaultStatusId })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,38 +297,38 @@ async function migrateIssueParentInfo (client: MigrationClient): Promise<void> {
|
||||
await updateIssueParentInfo(client, null)
|
||||
}
|
||||
|
||||
async function migrateIssueProjects (client: MigrationClient): Promise<void> {
|
||||
const issues = await client.find(DOMAIN_TRACKER, { _class: tracker.class.Issue, project: { $exists: false } })
|
||||
async function migrateIssueComponents (client: MigrationClient): Promise<void> {
|
||||
const issues = await client.find(DOMAIN_TRACKER, { _class: tracker.class.Issue, component: { $exists: false } })
|
||||
|
||||
if (issues.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const issue of issues) {
|
||||
await client.update(DOMAIN_TRACKER, { _id: issue._id }, { project: null })
|
||||
await client.update(DOMAIN_TRACKER, { _id: issue._id }, { component: null })
|
||||
}
|
||||
}
|
||||
|
||||
async function upgradeProjectIcons (tx: TxOperations): Promise<void> {
|
||||
const projects = await tx.findAll(tracker.class.Project, {})
|
||||
async function upgradeComponentIcons (tx: TxOperations): Promise<void> {
|
||||
const components = await tx.findAll(tracker.class.Component, {})
|
||||
|
||||
if (projects.length === 0) {
|
||||
if (components.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const project of projects) {
|
||||
const icon = project.icon as unknown
|
||||
for (const component of components) {
|
||||
const icon = component.icon as unknown
|
||||
|
||||
if (icon !== undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
await tx.update(project, { icon: tracker.icon.Projects })
|
||||
await tx.update(component, { icon: tracker.icon.Components })
|
||||
}
|
||||
}
|
||||
|
||||
async function createDefaults (tx: TxOperations): Promise<void> {
|
||||
await createDefaultTeam(tx)
|
||||
await createDefaultProject(tx)
|
||||
await createOrUpdate(
|
||||
tx,
|
||||
tags.class.TagCategory,
|
||||
@@ -377,10 +383,10 @@ async function fillRank (client: MigrationClient): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function upgradeTeams (tx: TxOperations): Promise<void> {
|
||||
await upgradeTeamIssueStatuses(tx)
|
||||
await fixTeamsIssueStatusesOrder(tx)
|
||||
await upgradeTeamSettings(tx)
|
||||
async function upgradeProjects (tx: TxOperations): Promise<void> {
|
||||
await upgradeProjectIssueStatuses(tx)
|
||||
await fixProjectsIssueStatusesOrder(tx)
|
||||
await upgradeProjectSettings(tx)
|
||||
}
|
||||
|
||||
async function upgradeIssues (tx: TxOperations): Promise<void> {
|
||||
@@ -408,8 +414,277 @@ async function upgradeIssues (tx: TxOperations): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function upgradeProjects (tx: TxOperations): Promise<void> {
|
||||
await upgradeProjectIcons(tx)
|
||||
async function upgradeComponents (tx: TxOperations): Promise<void> {
|
||||
await upgradeComponentIcons(tx)
|
||||
}
|
||||
|
||||
async function renameProject (client: MigrationClient): Promise<void> {
|
||||
await client.update(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
_class: { $in: [tracker.class.Issue, tracker.class.Sprint] },
|
||||
project: { $exists: true }
|
||||
},
|
||||
{
|
||||
$rename: { project: 'component' }
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_class: core.class.TxCollectionCUD,
|
||||
'tx._class': core.class.TxCreateDoc,
|
||||
'tx.objectClass': tracker.class.Issue,
|
||||
'tx.attributes.project': { $exists: true }
|
||||
},
|
||||
{
|
||||
$rename: { 'tx.attributes.project': 'tx.attributes.component' }
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_class: core.class.TxCollectionCUD,
|
||||
'tx._class': core.class.TxUpdateDoc,
|
||||
'tx.objectClass': tracker.class.Issue,
|
||||
'tx.operations.project': { $exists: true }
|
||||
},
|
||||
{
|
||||
$rename: { 'tx.operations.project': 'tx.operations.component' }
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
objectClass: tracker.class.Sprint,
|
||||
_class: core.class.TxCreateDoc,
|
||||
'attributes.project': { $exists: true }
|
||||
},
|
||||
{
|
||||
$rename: { 'attributes.project': 'attributes.component' }
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
objectClass: { $in: [tracker.class.Issue, tracker.class.Sprint] },
|
||||
_class: core.class.TxUpdateDoc,
|
||||
'operations.project': { $exists: true }
|
||||
},
|
||||
{
|
||||
$rename: { 'operations.project': 'operations.component' }
|
||||
}
|
||||
)
|
||||
|
||||
const templates = await client.find<IssueTemplate>(DOMAIN_TRACKER, {
|
||||
_class: tracker.class.IssueTemplate,
|
||||
project: { $exists: true }
|
||||
})
|
||||
for (const template of templates) {
|
||||
const children: IssueTemplateChild[] = template.children.map((p) => {
|
||||
const res = {
|
||||
...p,
|
||||
component: p.component
|
||||
}
|
||||
delete (res as any).project
|
||||
return res
|
||||
})
|
||||
await client.update<IssueTemplate>(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
_id: template._id
|
||||
},
|
||||
{
|
||||
children
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
_id: template._id
|
||||
},
|
||||
{
|
||||
$rename: { project: 'component' }
|
||||
}
|
||||
)
|
||||
const createTxes = await client.find<TxCreateDoc<IssueTemplate>>(DOMAIN_TX, {
|
||||
objectId: template._id,
|
||||
_class: core.class.TxCreateDoc
|
||||
})
|
||||
for (const createTx of createTxes) {
|
||||
const children: IssueTemplateChild[] = createTx.attributes.children.map((p) => {
|
||||
const res = {
|
||||
...p,
|
||||
component: p.component
|
||||
}
|
||||
delete (res as any).project
|
||||
return res
|
||||
})
|
||||
await client.update<TxCreateDoc<IssueTemplate>>(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_id: createTx._id
|
||||
},
|
||||
{
|
||||
children
|
||||
}
|
||||
)
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_id: createTx._id
|
||||
},
|
||||
{
|
||||
$rename: { 'attributes.project': 'attributes.component' }
|
||||
}
|
||||
)
|
||||
}
|
||||
const updateTxes = await client.find<TxUpdateDoc<IssueTemplate>>(DOMAIN_TX, {
|
||||
objectId: template._id,
|
||||
_class: core.class.TxUpdateDoc
|
||||
})
|
||||
for (const updateTx of updateTxes) {
|
||||
if ((updateTx.operations as any).project !== undefined) {
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_id: updateTx._id
|
||||
},
|
||||
{
|
||||
$rename: { 'operations.project': 'operations.component' }
|
||||
}
|
||||
)
|
||||
}
|
||||
if (updateTx.operations.children !== undefined) {
|
||||
const children: IssueTemplateChild[] = updateTx.operations.children.map((p) => {
|
||||
const res = {
|
||||
...p,
|
||||
component: p.component
|
||||
}
|
||||
delete (res as any).project
|
||||
return res
|
||||
})
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
_id: updateTx._id
|
||||
},
|
||||
{
|
||||
children
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultSpace = (
|
||||
await client.find<Project>(DOMAIN_SPACE, {
|
||||
_id: 'tracker:team:DefaultTeam' as Ref<Project>
|
||||
})
|
||||
)[0]
|
||||
if (defaultSpace !== undefined) {
|
||||
await client.delete(DOMAIN_SPACE, tracker.project.DefaultProject)
|
||||
await client.create(DOMAIN_SPACE, {
|
||||
...defaultSpace,
|
||||
_id: tracker.project.DefaultProject,
|
||||
_class: tracker.class.Project,
|
||||
description: defaultSpace.description === 'Default team' ? 'Default project' : defaultSpace.description
|
||||
})
|
||||
await client.delete(DOMAIN_SPACE, defaultSpace._id)
|
||||
}
|
||||
|
||||
await client.update(
|
||||
DOMAIN_SPACE,
|
||||
{
|
||||
_id: 'tracker:team:DefaultTeam' as Ref<Project>,
|
||||
_class: 'tracker:class:Team' as Ref<Class<Doc>>
|
||||
},
|
||||
{
|
||||
_id: tracker.project.DefaultProject,
|
||||
_class: tracker.class.Project,
|
||||
description: 'Default project'
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
attachedTo: 'tracker:team:DefaultTeam' as Ref<Doc>
|
||||
},
|
||||
{
|
||||
attachedTo: tracker.project.DefaultProject
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
space: 'tracker:team:DefaultTeam' as Ref<Project>
|
||||
},
|
||||
{
|
||||
space: tracker.project.DefaultProject
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TRACKER,
|
||||
{
|
||||
attachedToClass: 'tracker:class:Team' as Ref<Class<Doc>>
|
||||
},
|
||||
{
|
||||
attachedToClass: tracker.class.Project
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
objectId: 'tracker:team:DefaultTeam' as Ref<Project>
|
||||
},
|
||||
{
|
||||
objectId: tracker.project.DefaultProject
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
objectClass: 'tracker:class:Team' as Ref<Class<Doc>>
|
||||
},
|
||||
{
|
||||
objectClass: tracker.class.Project
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
'tx.objectClass': 'tracker:class:Team' as Ref<Class<Doc>>
|
||||
},
|
||||
{
|
||||
'tx.objectClass': tracker.class.Project
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
objectSpace: 'tracker:team:DefaultTeam' as Ref<Project>
|
||||
},
|
||||
{
|
||||
objectSpace: tracker.project.DefaultProject
|
||||
}
|
||||
)
|
||||
|
||||
await client.update(
|
||||
DOMAIN_TX,
|
||||
{
|
||||
'tx.objectSpace': 'tracker:team:DefaultTeam' as Ref<Project>
|
||||
},
|
||||
{
|
||||
'tx.objectSpace': tracker.project.DefaultProject
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export const trackerOperation: MigrateOperation = {
|
||||
@@ -423,15 +698,16 @@ export const trackerOperation: MigrateOperation = {
|
||||
reportedTime: 0
|
||||
}
|
||||
)
|
||||
await Promise.all([migrateIssueProjects(client), migrateParentIssues(client)])
|
||||
await Promise.all([migrateIssueComponents(client), migrateParentIssues(client)])
|
||||
await migrateIssueParentInfo(client)
|
||||
await fillRank(client)
|
||||
await renameProject(client)
|
||||
},
|
||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||
const tx = new TxOperations(client, core.account.System)
|
||||
await createDefaults(tx)
|
||||
await upgradeTeams(tx)
|
||||
await upgradeIssues(tx)
|
||||
await upgradeProjects(tx)
|
||||
await upgradeIssues(tx)
|
||||
await upgradeComponents(tx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ import { Application } from '@hcengineering/workbench'
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
string: {
|
||||
TrackerApplication: '' as IntlString,
|
||||
Teams: '' as IntlString,
|
||||
Projects: '' as IntlString,
|
||||
GotoIssues: '' as IntlString,
|
||||
GotoActive: '' as IntlString,
|
||||
GotoBacklog: '' as IntlString,
|
||||
GotoBoard: '' as IntlString,
|
||||
GotoProjects: '' as IntlString,
|
||||
GotoComponents: '' as IntlString,
|
||||
GotoTrackerApplication: '' as IntlString,
|
||||
SearchIssue: '' as IntlString,
|
||||
Parent: '' as IntlString
|
||||
@@ -61,14 +61,14 @@ export default mergeIds(trackerId, tracker, {
|
||||
actionImpl: {
|
||||
CopyToClipboard: '' as ViewAction,
|
||||
EditWorkflowStatuses: '' as ViewAction,
|
||||
EditTeam: '' as ViewAction,
|
||||
DeleteTeam: '' as ViewAction,
|
||||
EditProject: '' as ViewAction,
|
||||
DeleteProject: '' as ViewAction,
|
||||
DeleteSprint: '' as ViewAction
|
||||
},
|
||||
action: {
|
||||
NewRelatedIssue: '' as Ref<Action<Doc, Record<string, any>>>,
|
||||
DeleteSprint: '' as Ref<Action<Doc, Record<string, any>>>,
|
||||
DeleteTeam: '' as Ref<Action<Doc, Record<string, any>>>,
|
||||
DeleteProject: '' as Ref<Action<Doc, Record<string, any>>>,
|
||||
SetSprintLead: '' as Ref<Action<Doc, Record<string, any>>>
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user