Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
0e6d0df
feat(tracker): add Gantt scheduling schema (startDate + IssueRelation)
MichaelUray May 15, 2026
5c9faf7
test(model-tracker): add migrateAddStartDate jest tests
MichaelUray May 15, 2026
8641423
feat(model-tracker): add migrateAddStartDate + wire into trackerOpera…
MichaelUray May 15, 2026
8d932e8
feat(tracker): expose Issue.startDate / Milestone.startDate in UI; ti…
MichaelUray May 15, 2026
c94a5cc
fix(tracker): set explicit @Prop ranks for Milestone date fields
MichaelUray May 15, 2026
f84e497
fix(tracker-resources): EditMilestone renders Status/Start/Target in …
MichaelUray May 15, 2026
7d745f9
fix(fulltext): bump model version to 0.7.423 to match deployed worksp…
MichaelUray May 17, 2026
8c9fc01
Merge branch 'develop' into feat/gantt-upstream-pr1-schema
ArtyomSavchenko Jun 16, 2026
12eda95
chore: apply rush format after develop merge
MichaelUray Jun 18, 2026
86b1c19
test(tracker): fix milestone page-object selectors after startDate fi…
MichaelUray Jun 19, 2026
acfca69
test(tracker): shift buttonEstimation index after startDate row addition
MichaelUray Jun 19, 2026
ea35288
Merge remote-tracking branch 'upstream/develop' into feat/gantt-upstr…
MichaelUray Jun 22, 2026
70c6be2
chore: apply rush format (prettier compliance for CI)
MichaelUray Jun 22, 2026
ccd17c5
fix(tests/tracker): use contains() for cell-label class to survive Sv…
MichaelUray Jun 22, 2026
0c6c5a4
Merge remote-tracking branch 'upstream/develop' into feat/gantt-upstr…
MichaelUray Jul 2, 2026
fe454e9
Merge remote-tracking branch 'upstream/develop' into feat/gantt-upstr…
MichaelUray Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/scripts/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"0.7.422"
"0.7.423"
49 changes: 49 additions & 0 deletions models/tracker/src/__tests__/migration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Copyright © 2026 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.
//

import { DOMAIN_TASK } from '@hcengineering/model-task'
import tracker from '@hcengineering/tracker'

import { DOMAIN_TRACKER } from '../types'
import { migrateAddStartDate } from '../migration'

describe('migrateAddStartDate', () => {
it('sets startDate=null on every Issue lacking the field (DOMAIN_TASK)', async () => {
const update = jest.fn().mockResolvedValue(undefined)
const client: any = { update }

await migrateAddStartDate(client)

expect(update).toHaveBeenCalledWith(
DOMAIN_TASK,
{ _class: tracker.class.Issue, startDate: { $exists: false } },
{ startDate: null }
)
})

it('sets startDate=null on every Milestone lacking the field (DOMAIN_TRACKER)', async () => {
const update = jest.fn().mockResolvedValue(undefined)
const client: any = { update }

await migrateAddStartDate(client)

expect(update).toHaveBeenCalledWith(
DOMAIN_TRACKER,
{ _class: tracker.class.Milestone, startDate: { $exists: false } },
{ startDate: null }
)
})

it('issues exactly two update calls (one per class)', async () => {
const update = jest.fn().mockResolvedValue(undefined)
const client: any = { update }

await migrateAddStartDate(client)

expect(update).toHaveBeenCalledTimes(2)
})
})
2 changes: 2 additions & 0 deletions models/tracker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
TClassicProjectTypeData,
TComponent,
TIssue,
TIssueRelation,
TIssueStatus,
TIssueTemplate,
TIssueTypeData,
Expand Down Expand Up @@ -441,6 +442,7 @@ export function createModel (builder: Builder): void {
TProject,
TComponent,
TIssue,
TIssueRelation,
TIssueTemplate,
TIssueStatus,
TTypeIssuePriority,
Expand Down
16 changes: 16 additions & 0 deletions models/tracker/src/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import tracker, {
} from '@hcengineering/tracker'

import { classicIssueTaskStatuses } from '.'
import { DOMAIN_TRACKER } from './types'

async function createDefaultProject (tx: TxOperations): Promise<void> {
const current = await tx.findOne(tracker.class.Project, {
Expand Down Expand Up @@ -170,6 +171,16 @@ async function migrateIdentifiers (client: MigrationClient): Promise<void> {
}
}

export async function migrateAddStartDate (client: MigrationClient): Promise<void> {
// Issues live in DOMAIN_TASK; Milestones live in DOMAIN_TRACKER.
await client.update(DOMAIN_TASK, { _class: tracker.class.Issue, startDate: { $exists: false } }, { startDate: null })
await client.update(
DOMAIN_TRACKER,
{ _class: tracker.class.Milestone, startDate: { $exists: false } },
{ startDate: null }
)
}

async function migrateDefaultStatuses (client: MigrationClient, logger: ModelLogger): Promise<void> {
const defaultTypeId = tracker.ids.ClassingProjectType
const typeDescriptor = tracker.descriptors.ProjectType
Expand Down Expand Up @@ -398,6 +409,11 @@ export const trackerOperation: MigrateOperation = {
state: 'migrateDefaultTypeMixins',
mode: 'upgrade',
func: migrateDefaultTypeMixins
},
{
state: 'gantt-add-startdate',
mode: 'upgrade',
func: migrateAddStartDate
}
])
},
Expand Down
31 changes: 31 additions & 0 deletions models/tracker/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ import time, { type ToDo } from '@hcengineering/time'
import {
type ProjectTargetPreference,
type Component,
type DependencyKind,
type Issue,
type IssueChildInfo,
type IssueParentInfo,
type IssuePriority,
type IssueRelation,
type IssueStatus,
type IssueTemplate,
type IssueTemplateChild,
Expand Down Expand Up @@ -233,6 +235,10 @@ export class TIssue extends TTask implements Issue {
@ReadOnly()
declare space: Ref<Project>

@Prop(TypeDate(DateRangeMode.DATETIME), tracker.string.IssueStartDate)
@Index(IndexKind.Indexed)
declare startDate: Timestamp | null

@Prop(TypeDate(DateRangeMode.DATETIME), tracker.string.DueDate)
declare dueDate: Timestamp | null

Expand Down Expand Up @@ -340,6 +346,28 @@ export class TTimeSpendReport extends TAttachedDoc implements TimeSpendReport {
@Prop(TypeString(), tracker.string.TimeSpendReportDescription)
description!: string
}

/**
* @public
*/
@Model(tracker.class.IssueRelation, core.class.AttachedDoc, DOMAIN_TRACKER)
@UX(tracker.string.GanttDependency, tracker.icon.Issue)
export class TIssueRelation extends TAttachedDoc implements IssueRelation {
@Prop(TypeRef(tracker.class.Issue), tracker.string.Issue)
declare attachedTo: Ref<Issue>

declare collection: 'relations'

@Prop(TypeRef(tracker.class.Issue), tracker.string.Issue)
@Index(IndexKind.Indexed)
target!: Ref<Issue>

@Prop(TypeString(), tracker.string.GanttDependency)
kind!: DependencyKind

@Prop(TypeNumber(), tracker.string.GanttLag)
lag!: number
}
/**
* @public
*/
Expand Down Expand Up @@ -389,6 +417,9 @@ export class TMilestone extends TDoc implements Milestone {
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number

@Prop(TypeDate(), tracker.string.StartDate)
startDate!: Timestamp | null

@Prop(TypeDate(), tracker.string.TargetDate)
targetDate!: Timestamp

Expand Down
8 changes: 7 additions & 1 deletion models/tracker/src/viewlets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ export function defineViewlets (builder: Builder): void {
viewOptions: milestoneOptions,
configOptions: {
strict: true,
hiddenKeys: ['targetDate', 'label', 'description']
hiddenKeys: ['startDate', 'targetDate', 'label', 'description']
},
config: [
{
Expand All @@ -672,6 +672,12 @@ export function defineViewlets (builder: Builder): void {
},
{ key: '', presenter: tracker.component.MilestonePresenter, props: { shouldUseMargin: true } },
{ key: '', displayProps: { grow: true } },
{
key: '',
label: tracker.string.StartDate,
presenter: tracker.component.MilestoneDatePresenter,
props: { field: 'startDate' }
},
{
key: '',
label: tracker.string.TargetDate,
Expand Down
1 change: 1 addition & 0 deletions packages/importer/src/importer/importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ export class WorkspaceImporter {
rank,
comments: issue.comments?.length ?? 0,
subIssues: issue.subdocs.length,
startDate: null,
dueDate: null,
parents: parentsInfo,
remainingTime,
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@
"NoAssignee": "Bez přiřazení",
"LastUpdated": "Poslední aktualizace",
"DueDate": "Datum splnění",
"IssueStartDate": "Datum zahájení",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manuální",
"All": "Vše",
"PastWeek": "Minulý týden",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"NoAssignee": "Nicht zugewiesen",
"LastUpdated": "Zuletzt aktualisiert",
"DueDate": "Fälligkeitsdatum",
"IssueStartDate": "Startdatum",
"GanttDependency": "Abhängigkeit",
"GanttLag": "Verzögerung",
"Manual": "Manuell",
"All": "Alle",
"PastWeek": "Letzte Woche",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"NoAssignee": "No assignee",
"LastUpdated": "Last updated",
"DueDate": "Due date",
"IssueStartDate": "Start date",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manual",
"All": "All",
"PastWeek": "Past week",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Sin asignar",
"LastUpdated": "Última actualización",
"DueDate": "Fecha de vencimiento",
"IssueStartDate": "Fecha de inicio",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manual",
"All": "Todos",
"PastWeek": "Semana pasada",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Non assigné",
"LastUpdated": "Dernière mise à jour",
"DueDate": "Date d'échéance",
"IssueStartDate": "Date de début",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manuel",
"All": "Tous",
"PastWeek": "La semaine passée",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Nessun assegnatario",
"LastUpdated": "Ultimo aggiornamento",
"DueDate": "Data di scadenza",
"IssueStartDate": "Data di inizio",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manuale",
"All": "Tutti",
"PastWeek": "Settimana scorsa",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "担当者なし",
"LastUpdated": "最終更新日",
"DueDate": "期日",
"IssueStartDate": "開始日",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "手動",
"All": "すべて",
"PastWeek": "先週",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "담당자 없음",
"LastUpdated": "최근 업데이트",
"DueDate": "마감일",
"IssueStartDate": "시작일",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "수동",
"All": "전체",
"PastWeek": "지난주",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/pt-br.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Sem atribuição",
"LastUpdated": "Última atualização",
"DueDate": "Data de vencimento",
"IssueStartDate": "Data de início",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manual",
"All": "Todos",
"PastWeek": "Semana passada",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Sem atribuição",
"LastUpdated": "Última atualização",
"DueDate": "Data de vencimento",
"IssueStartDate": "Data de início",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manual",
"All": "Todos",
"PastWeek": "Semana passada",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"NoAssignee": "Нет исполнителя",
"LastUpdated": "Последнее обновление",
"DueDate": "Срок",
"IssueStartDate": "Дата начала",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Пользовательский",
"All": "Все",
"PastWeek": "Предыдущая неделя",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
"NoAssignee": "Atanan yok",
"LastUpdated": "Son güncelleme",
"DueDate": "Bitiş tarihi",
"IssueStartDate": "Başlangıç tarihi",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "Manuel",
"All": "Tümü",
"PastWeek": "Geçen hafta",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"NoAssignee": "无受理人",
"LastUpdated": "最后更新",
"DueDate": "截止日期",
"IssueStartDate": "开始日期",
"GanttDependency": "Dependency",
"GanttLag": "Lag",
"Manual": "手动",
"All": "全部",
"PastWeek": "过去一周",
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-resources/src/components/CreateIssue.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
priority: priority ?? IssuePriority.NoPriority,
space: _space as Ref<Project>,
component: component ?? $activeComponent ?? null,
startDate: null,
dueDate: null,
attachments: 0,
estimation: 0,
Expand Down Expand Up @@ -292,7 +293,7 @@
if (object.template?.template === template._id) {
return
}
const { _class, _id, space, children, comments, attachments, labels, description, ...templBase } = template

Check warning on line 296 in plugins/tracker-resources/src/components/CreateIssue.svelte

View workflow job for this annotation

GitHub Actions / formatting

'attachments' is assigned a value but never used. Allowed unused vars must match /^\$\$(Props|Events|Slots)$/u

Check warning on line 296 in plugins/tracker-resources/src/components/CreateIssue.svelte

View workflow job for this annotation

GitHub Actions / formatting

'comments' is assigned a value but never used. Allowed unused vars must match /^\$\$(Props|Events|Slots)$/u

Check warning on line 296 in plugins/tracker-resources/src/components/CreateIssue.svelte

View workflow job for this annotation

GitHub Actions / formatting

'space' is assigned a value but never used. Allowed unused vars must match /^\$\$(Props|Events|Slots)$/u

Check warning on line 296 in plugins/tracker-resources/src/components/CreateIssue.svelte

View workflow job for this annotation

GitHub Actions / formatting

'_id' is assigned a value but never used. Allowed unused vars must match /^\$\$(Props|Events|Slots)$/u

Check warning on line 296 in plugins/tracker-resources/src/components/CreateIssue.svelte

View workflow job for this annotation

GitHub Actions / formatting

'_class' is assigned a value but never used. Allowed unused vars must match /^\$\$(Props|Events|Slots)$/u

const allLabels = new Set<Ref<TagElement>>()
for (const label of labels ?? []) {
Expand All @@ -312,6 +313,7 @@
_id: generateId(),
space: _space as Ref<Project>,
subIssues: [],
startDate: null,
dueDate: null,
labels:
p.labels !== undefined
Expand Down Expand Up @@ -488,6 +490,7 @@
rank: '',
comments: 0,
subIssues: 0,
startDate: object.startDate,
dueDate: object.dueDate,
parents:
parentIssue != null
Expand Down
1 change: 1 addition & 0 deletions plugins/tracker-resources/src/components/SubIssues.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
rank: '',
comments: 0,
subIssues: 0,
startDate: subIssue.startDate ?? null,
dueDate: null,
parents,
reportedTime: 0,
Expand Down
Loading
Loading