diff --git a/foundations/utils/packages/platform-rig/bin/do-svelte-check.js b/foundations/utils/packages/platform-rig/bin/do-svelte-check.js index 55975aef47d..8c3f8b06d71 100755 --- a/foundations/utils/packages/platform-rig/bin/do-svelte-check.js +++ b/foundations/utils/packages/platform-rig/bin/do-svelte-check.js @@ -3,7 +3,9 @@ const { readFileSync, existsSync, mkdirSync, createWriteStream } = require('fs') const { spawn } = require('child_process') function parseSvelteCheckLog(logContent) { - const lines = logContent.split('\n') + // Human output includes ANSI colors, even when redirected to a log file. + // Strip them before looking for "Error:" so failed checks report the errors. + const lines = logContent.replace(/\x1b\[[0-9;]*m/g, '').split('\n') const errors = [] let currentError = null diff --git a/packages/gantt/src/__tests__/time-scale.test.ts b/packages/gantt/src/__tests__/time-scale.test.ts index bc3393f5e34..7b26550f0cb 100644 --- a/packages/gantt/src/__tests__/time-scale.test.ts +++ b/packages/gantt/src/__tests__/time-scale.test.ts @@ -141,3 +141,29 @@ describe('time-scale — secondary label (year/month supra row)', () => { void DAY }) }) + +describe('time-scale locale', () => { + const origin = Date.UTC(2026, 0, 1) + + it.each(['en', 'ru', 'de', 'ja'])('formats day and month labels using %s', (locale) => { + const expected = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' }).format(origin) + expect(createTimeScale('day', origin, undefined, { locale }).ticks([origin, origin])[0].secondaryLabel).toBe( + expected + ) + expect(createTimeScale('month', origin, undefined, { locale }).ticks([origin, origin])[0].label).toBe(expected) + }) + + it('accepts translated week and quarter labels without changing geometry', () => { + const labels = { + locale: 'ru', + weekLabel: (week: number) => `Нед. ${week}`, + quarterLabel: (quarter: number) => `Кв. ${quarter}` + } + const week = createTimeScale('week', origin, 14, labels) + const first = week.ticks([origin, origin + 7 * DAY_MS])[0] + expect(first.label).toBe('Нед. 2') + expect(first.date).toBe(Date.UTC(2026, 0, 5)) + expect(week.toX(first.date)).toBe(56) + expect(createTimeScale('quarter', origin, undefined, labels).ticks([origin, origin])[0].label).toBe('Кв. 1') + }) +}) diff --git a/packages/gantt/src/__tests__/toolbar-overflow.test.ts b/packages/gantt/src/__tests__/toolbar-overflow.test.ts index 59939b57e1e..b1176ae0a06 100644 --- a/packages/gantt/src/__tests__/toolbar-overflow.test.ts +++ b/packages/gantt/src/__tests__/toolbar-overflow.test.ts @@ -16,6 +16,7 @@ const ALL: ToolbarTier[] = [...TOOLBAR_TIERS] // One easy-to-reason-about width per tier. const W: Record = { group: 100, + color: 80, nav: 200, date: 150, zoom: 120, @@ -39,24 +40,31 @@ describe('computeToolbarOverflow', () => { }) it('keeps everything inline when it fits exactly', () => { - // 100+200+150+120+60+90 = 720, plus five gaps = 740 - const r = computeToolbarOverflow(ALL, W, 740, GAP, MORE) + // 100+80+200+150+120+60+90 = 800, plus six gaps = 824 + const r = computeToolbarOverflow(ALL, W, 824, GAP, MORE) expect(r.hidden).toEqual([]) expect(r.visible).toEqual(ALL) }) it('collapses the least important tier first', () => { - const r = computeToolbarOverflow(ALL, W, 739, GAP, MORE) + const r = computeToolbarOverflow(ALL, W, 823, GAP, MORE) expect(r.hidden).toEqual(['savedview']) - expect(r.visible).toEqual(['group', 'nav', 'date', 'zoom', 'undo']) + expect(r.visible).toEqual(['group', 'color', 'nav', 'date', 'zoom', 'undo']) }) it('collapses further tiers in TOOLBAR_COLLAPSE_ORDER as space shrinks', () => { - expect(computeToolbarOverflow(ALL, W, 600, GAP, MORE).hidden).toEqual(['date', 'savedview']) - expect(computeToolbarOverflow(ALL, W, 450, GAP, MORE).hidden).toEqual(['group', 'date', 'savedview']) - expect(computeToolbarOverflow(ALL, W, 400, GAP, MORE).hidden).toEqual(['group', 'date', 'undo', 'savedview']) + expect(computeToolbarOverflow(ALL, W, 600, GAP, MORE).hidden).toEqual(['color', 'date', 'savedview']) + expect(computeToolbarOverflow(ALL, W, 450, GAP, MORE).hidden).toEqual(['group', 'color', 'date', 'savedview']) + expect(computeToolbarOverflow(ALL, W, 400, GAP, MORE).hidden).toEqual([ + 'group', + 'color', + 'date', + 'undo', + 'savedview' + ]) expect(computeToolbarOverflow(ALL, W, 300, GAP, MORE).hidden).toEqual([ 'group', + 'color', 'date', 'zoom', 'undo', @@ -71,7 +79,7 @@ describe('computeToolbarOverflow', () => { }) it('never drops a tier — visible + hidden is always the input set', () => { - for (const available of [-1, 0, 30, 120, 300, 500, 740, 2000]) { + for (const available of [-1, 0, 30, 120, 300, 500, 824, 2000]) { const r = computeToolbarOverflow(ALL, W, available, GAP, MORE) expect([...r.visible, ...r.hidden].sort()).toEqual([...ALL].sort()) } @@ -83,6 +91,13 @@ describe('computeToolbarOverflow', () => { expect(r.hidden).toEqual(ALL.filter((t) => r.hidden.includes(t))) }) + it('keeps grouping inline when only one of the two view controls fits', () => { + const present: ToolbarTier[] = ['group', 'color', 'nav', 'zoom', 'undo'] + const r = computeToolbarOverflow(present, W, 510, GAP, 0) + expect(r.visible).toEqual(['group', 'nav', 'zoom', 'undo']) + expect(r.hidden).toEqual(['color']) + }) + it('ignores tiers that are not present', () => { const present: ToolbarTier[] = ['nav', 'zoom'] // nav(200) + zoom(120) + gap = 324 > 240; nav alone plus the "…" trigger diff --git a/packages/gantt/src/time-scale.ts b/packages/gantt/src/time-scale.ts index 94017e690eb..82ef40bd6ed 100644 --- a/packages/gantt/src/time-scale.ts +++ b/packages/gantt/src/time-scale.ts @@ -45,7 +45,22 @@ export interface TimeScale { ticks: (range: [number, number]) => Tick[] } -export function createTimeScale (zoom: ZoomLevel, origin: number, pxPerDayOverride?: number): TimeScale { +/** Presentation settings supplied by the host application's active language. */ +export interface TimeScaleLocale { + locale?: string + weekLabel?: (week: number) => string + quarterLabel?: (quarter: number) => string +} + +export function createTimeScale ( + zoom: ZoomLevel, + origin: number, + pxPerDayOverride?: number, + labels: TimeScaleLocale = {} +): TimeScale { + const locale = labels.locale ?? 'en' + const weekLabel = labels.weekLabel ?? ((week: number) => `W${week}`) + const quarterLabel = labels.quarterLabel ?? ((quarter: number) => `Q${quarter}`) const pxPerDay = pxPerDayOverride ?? PX_PER_DAY[zoom] const originSnapped = snapToUtcMidnight(origin) @@ -71,7 +86,7 @@ export function createTimeScale (zoom: ZoomLevel, origin: number, pxPerDayOverri const m = d.getUTCMonth() let secondary: string | undefined if (first || m !== lastMonth) { - secondary = d.toLocaleString(undefined, { month: 'short', timeZone: 'UTC' }) + secondary = d.toLocaleString(locale, { month: 'short', timeZone: 'UTC' }) lastMonth = m first = false } @@ -106,7 +121,7 @@ export function createTimeScale (zoom: ZoomLevel, origin: number, pxPerDayOverri } result.push({ date: cursor, - label: `W${isoWeekNumber(c)}`, + label: weekLabel(isoWeekNumber(c)), level: isFirstWeekOfMonth ? 'major' : 'minor', secondaryLabel: secondary }) @@ -135,7 +150,7 @@ export function createTimeScale (zoom: ZoomLevel, origin: number, pxPerDayOverri } result.push({ date: cursor, - label: c.toLocaleString(undefined, { month: 'short', timeZone: 'UTC' }), + label: c.toLocaleString(locale, { month: 'short', timeZone: 'UTC' }), level: c.getUTCMonth() === 0 ? 'major' : 'minor', secondaryLabel: secondary }) @@ -170,7 +185,7 @@ export function createTimeScale (zoom: ZoomLevel, origin: number, pxPerDayOverri } result.push({ date: cursor, - label: `Q${qNum}`, + label: quarterLabel(qNum), level: qNum === 1 ? 'major' : 'minor', secondaryLabel: secondary }) diff --git a/packages/gantt/src/toolbar-overflow.ts b/packages/gantt/src/toolbar-overflow.ts index 75011c7c6dc..7f7404bfdf4 100644 --- a/packages/gantt/src/toolbar-overflow.ts +++ b/packages/gantt/src/toolbar-overflow.ts @@ -28,7 +28,7 @@ * that collapses as a whole; splitting e.g. the date-navigation into single * buttons would leave a half-usable control group behind. */ -export const TOOLBAR_TIERS = ['group', 'nav', 'date', 'zoom', 'undo', 'savedview'] as const +export const TOOLBAR_TIERS = ['group', 'color', 'nav', 'date', 'zoom', 'undo', 'savedview'] as const export type ToolbarTier = (typeof TOOLBAR_TIERS)[number] /** @@ -37,12 +37,21 @@ export type ToolbarTier = (typeof TOOLBAR_TIERS)[number] * - `savedview` is a passive "modified" indicator plus its update button; the * same action is reachable from the More-actions menu. * - `date` (jump-to-date) duplicates what panning and the nav buttons do. - * - `group` (group-by / colour-by) is view configuration, not navigation. + * - `color` is cosmetic; keep `group` visible longer because it changes the + * layout of the issue list and chart. * - `undo` matters while editing, but the keyboard shortcuts stay live. * - `zoom` and `nav` are the two controls a Gantt is unusable without, so * they are the last to go. */ -export const TOOLBAR_COLLAPSE_ORDER: readonly ToolbarTier[] = ['savedview', 'date', 'group', 'undo', 'zoom', 'nav'] +export const TOOLBAR_COLLAPSE_ORDER: readonly ToolbarTier[] = [ + 'savedview', + 'date', + 'color', + 'group', + 'undo', + 'zoom', + 'nav' +] /** * Width assumed for a tier that has never been measured. Deliberately diff --git a/plugins/tracker-assets/assets/icons.svg b/plugins/tracker-assets/assets/icons.svg index eda12e190e5..9c44edfd781 100644 --- a/plugins/tracker-assets/assets/icons.svg +++ b/plugins/tracker-assets/assets/icons.svg @@ -124,10 +124,8 @@ - - - - + + diff --git a/plugins/tracker-assets/lang/cs.json b/plugins/tracker-assets/lang/cs.json index 90dd1af4446..a86d17ab3ca 100644 --- a/plugins/tracker-assets/lang/cs.json +++ b/plugins/tracker-assets/lang/cs.json @@ -315,7 +315,19 @@ "SearchEmptyTitle": "Pro „{query}\" nebyly nalezeny žádné úkoly", "SearchEmptyActiveFilters": "Aktivní filtry: {filters}", "SearchEmptyClearFilters": "Hledat bez filtrů", - "SearchEmptyAllProjects": "Hledat ve všech projektech" + "SearchEmptyAllProjects": "Hledat ve všech projektech", + "GanttWeekLabel": "T{week}", + "GanttQuarterLabel": "Q{quarter}", + "GanttWithoutDates": "{count} bez dat", + "GanttDates": "Data", + "GanttZoomLabel": "Přiblížení", + "GanttSetDates": "Nastavit data", + "GanttNoScheduledTasks": "Žádné naplánované úkoly", + "GanttTodayAlreadyVisible": "Dnešek je již zobrazen", + "GanttVisibleRange": "Rozsah", + "GanttNotScheduled": "Nenaplánováno", + "GanttMissingStartDates": "{count} úkolů nemá datum zahájení.", + "GanttSetDatesHint": "Nastavte u úkolu datum zahájení a termín dokončení, aby se zobrazil v časové ose." }, "status": {} } diff --git a/plugins/tracker-assets/lang/de.json b/plugins/tracker-assets/lang/de.json index 1b0678b96b9..4ef15e6c56f 100644 --- a/plugins/tracker-assets/lang/de.json +++ b/plugins/tracker-assets/lang/de.json @@ -358,6 +358,8 @@ "GanttJumpToDate": "Zu Datum springen", "GanttZoomDay": "Tag", "GanttZoomWeek": "Woche", + "GanttWeekLabel": "KW{week}", + "GanttQuarterLabel": "Q{quarter}", "GanttZoomMonth": "Monat", "GanttZoomQuarter": "Quartal", "GanttZoomCustom": "Benutzerdefiniert", @@ -563,7 +565,16 @@ "SearchEmptyTitle": "Keine Treffer für \"{query}\"", "SearchEmptyActiveFilters": "Aktive Filter: {filters}", "SearchEmptyClearFilters": "Suche ohne Filter", - "SearchEmptyAllProjects": "In allen Projekten suchen" + "SearchEmptyAllProjects": "In allen Projekten suchen", + "GanttWithoutDates": "{count} ohne Daten", + "GanttDates": "Termine", + "GanttSetDates": "Daten festlegen", + "GanttNoScheduledTasks": "Keine geplanten Aufgaben", + "GanttTodayAlreadyVisible": "Heute ist bereits sichtbar", + "GanttVisibleRange": "Zeitraum", + "GanttNotScheduled": "Nicht geplant", + "GanttMissingStartDates": "Für {count} Aufgaben ist kein Startdatum festgelegt.", + "GanttSetDatesHint": "Legen Sie für ein Issue Start- und Fälligkeitsdatum fest, damit es auf der Zeitachse erscheint." }, "status": {} } diff --git a/plugins/tracker-assets/lang/en.json b/plugins/tracker-assets/lang/en.json index b54f1152f0f..01a260ee457 100644 --- a/plugins/tracker-assets/lang/en.json +++ b/plugins/tracker-assets/lang/en.json @@ -344,6 +344,8 @@ "GanttJumpToDate": "Jump to date", "GanttZoomDay": "Day", "GanttZoomWeek": "Week", + "GanttWeekLabel": "W{week}", + "GanttQuarterLabel": "Q{quarter}", "GanttZoomMonth": "Month", "GanttZoomQuarter": "Quarter", "GanttZoomCustom": "Custom", @@ -563,7 +565,16 @@ "SearchEmptyTitle": "No issues found for \"{query}\"", "SearchEmptyActiveFilters": "Active filters: {filters}", "SearchEmptyClearFilters": "Search without filters", - "SearchEmptyAllProjects": "Search in all projects" + "SearchEmptyAllProjects": "Search in all projects", + "GanttWithoutDates": "{count} without dates", + "GanttDates": "Dates", + "GanttSetDates": "Set dates", + "GanttNoScheduledTasks": "No scheduled tasks", + "GanttTodayAlreadyVisible": "Today is already in view", + "GanttVisibleRange": "Range", + "GanttNotScheduled": "Not scheduled", + "GanttMissingStartDates": "{count} issues have no start date.", + "GanttSetDatesHint": "Set start and due dates in an issue to show its timeline." }, "status": {} } diff --git a/plugins/tracker-assets/lang/es.json b/plugins/tracker-assets/lang/es.json index 77cc31b392f..e64739a8677 100644 --- a/plugins/tracker-assets/lang/es.json +++ b/plugins/tracker-assets/lang/es.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "No se encontraron tareas para \"{query}\"", "SearchEmptyActiveFilters": "Filtros activos: {filters}", "SearchEmptyClearFilters": "Buscar sin filtros", - "SearchEmptyAllProjects": "Buscar en todos los proyectos" + "SearchEmptyAllProjects": "Buscar en todos los proyectos", + "GanttWeekLabel": "S{week}", + "GanttQuarterLabel": "T{quarter}", + "GanttWithoutDates": "{count} sin fechas", + "GanttDates": "Fechas", + "GanttZoomLabel": "Zoom", + "GanttSetDates": "Establecer fechas", + "GanttNoScheduledTasks": "No hay tareas programadas", + "GanttTodayAlreadyVisible": "Hoy ya está visible", + "GanttVisibleRange": "Intervalo", + "GanttNotScheduled": "Sin programar", + "GanttMissingStartDates": "{count} tareas no tienen fecha de inicio.", + "GanttSetDatesHint": "Establece las fechas de inicio y vencimiento de una tarea para mostrarla en la línea de tiempo." }, "status": {} } diff --git a/plugins/tracker-assets/lang/fr.json b/plugins/tracker-assets/lang/fr.json index 993900aceef..f50efabb503 100644 --- a/plugins/tracker-assets/lang/fr.json +++ b/plugins/tracker-assets/lang/fr.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "Aucun problème trouvé pour \"{query}\"", "SearchEmptyActiveFilters": "Filtres actifs : {filters}", "SearchEmptyClearFilters": "Rechercher sans filtres", - "SearchEmptyAllProjects": "Rechercher dans tous les projets" + "SearchEmptyAllProjects": "Rechercher dans tous les projets", + "GanttWeekLabel": "S{week}", + "GanttQuarterLabel": "T{quarter}", + "GanttWithoutDates": "{count} sans dates", + "GanttDates": "Dates", + "GanttZoomLabel": "Zoom", + "GanttSetDates": "Définir les dates", + "GanttNoScheduledTasks": "Aucune tâche planifiée", + "GanttTodayAlreadyVisible": "Aujourd'hui est déjà visible", + "GanttVisibleRange": "Période", + "GanttNotScheduled": "Non planifié", + "GanttMissingStartDates": "{count} tâches n'ont pas de date de début.", + "GanttSetDatesHint": "Définissez les dates de début et d'échéance d'une tâche pour l'afficher sur la chronologie." }, "status": {} } diff --git a/plugins/tracker-assets/lang/it.json b/plugins/tracker-assets/lang/it.json index 7491e28c44d..6987099ebb9 100644 --- a/plugins/tracker-assets/lang/it.json +++ b/plugins/tracker-assets/lang/it.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "Nessuna issue trovata per \"{query}\"", "SearchEmptyActiveFilters": "Filtri attivi: {filters}", "SearchEmptyClearFilters": "Cerca senza filtri", - "SearchEmptyAllProjects": "Cerca in tutti i progetti" + "SearchEmptyAllProjects": "Cerca in tutti i progetti", + "GanttWeekLabel": "S{week}", + "GanttQuarterLabel": "T{quarter}", + "GanttWithoutDates": "{count} senza date", + "GanttDates": "Date", + "GanttZoomLabel": "Zoom", + "GanttSetDates": "Imposta le date", + "GanttNoScheduledTasks": "Nessuna attività pianificata", + "GanttTodayAlreadyVisible": "Oggi è già visibile", + "GanttVisibleRange": "Intervallo", + "GanttNotScheduled": "Non pianificato", + "GanttMissingStartDates": "{count} attività non hanno una data di inizio.", + "GanttSetDatesHint": "Imposta le date di inizio e scadenza di un'attività per mostrarla nella cronologia." }, "status": {} } diff --git a/plugins/tracker-assets/lang/ja.json b/plugins/tracker-assets/lang/ja.json index d7a5d9b4970..72af11ae93f 100644 --- a/plugins/tracker-assets/lang/ja.json +++ b/plugins/tracker-assets/lang/ja.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "\"{query}\" に一致するイシューが見つかりません", "SearchEmptyActiveFilters": "アクティブなフィルター:{filters}", "SearchEmptyClearFilters": "フィルターなしで検索", - "SearchEmptyAllProjects": "すべてのプロジェクトを検索" + "SearchEmptyAllProjects": "すべてのプロジェクトを検索", + "GanttWeekLabel": "第{week}週", + "GanttQuarterLabel": "第{quarter}四半期", + "GanttWithoutDates": "日付なし: {count}", + "GanttDates": "日付", + "GanttZoomLabel": "ズーム", + "GanttSetDates": "日付を設定", + "GanttNoScheduledTasks": "予定されたタスクはありません", + "GanttTodayAlreadyVisible": "今日の日付はすでに表示されています", + "GanttVisibleRange": "表示範囲", + "GanttNotScheduled": "未予定", + "GanttMissingStartDates": "{count} 件の課題に開始日が設定されていません。", + "GanttSetDatesHint": "課題に開始日と期限を設定すると、タイムラインに表示されます。" }, "status": {} } diff --git a/plugins/tracker-assets/lang/ko.json b/plugins/tracker-assets/lang/ko.json index 1f494b440c4..628aad44b3b 100644 --- a/plugins/tracker-assets/lang/ko.json +++ b/plugins/tracker-assets/lang/ko.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "\"{query}\"에 대한 이슈를 찾을 수 없습니다", "SearchEmptyActiveFilters": "활성 필터: {filters}", "SearchEmptyClearFilters": "필터 없이 검색", - "SearchEmptyAllProjects": "모든 프로젝트에서 검색" + "SearchEmptyAllProjects": "모든 프로젝트에서 검색", + "GanttWeekLabel": "{week}주", + "GanttQuarterLabel": "{quarter}분기", + "GanttWithoutDates": "날짜 없음: {count}", + "GanttDates": "날짜", + "GanttZoomLabel": "확대/축소", + "GanttSetDates": "날짜 설정", + "GanttNoScheduledTasks": "예정된 작업이 없습니다", + "GanttTodayAlreadyVisible": "오늘이 이미 표시되어 있습니다", + "GanttVisibleRange": "표시 범위", + "GanttNotScheduled": "일정 없음", + "GanttMissingStartDates": "{count}개 이슈에 시작일이 없습니다.", + "GanttSetDatesHint": "이슈의 시작일과 마감일을 설정하면 타임라인에 표시됩니다." }, "status": {} } diff --git a/plugins/tracker-assets/lang/pl.json b/plugins/tracker-assets/lang/pl.json index 9cf1984152d..9f2fe1c26da 100644 --- a/plugins/tracker-assets/lang/pl.json +++ b/plugins/tracker-assets/lang/pl.json @@ -291,6 +291,18 @@ "ForbidCreateProjectPermission": "Zakaż tworzenia projektów", "ForbidCreateProjectPermissionDescription": "Zakaż użytkownikom tworzenia nowych projektów.", "AllowCreatingIssues": "Zezwól na tworzenie zadań", + "GanttWeekLabel": "T{week}", + "GanttQuarterLabel": "K{quarter}", + "GanttWithoutDates": "{count} bez dat", + "GanttDates": "Daty", + "GanttZoomLabel": "Powiększenie", + "GanttSetDates": "Ustaw daty", + "GanttNoScheduledTasks": "Brak zaplanowanych zadań", + "GanttTodayAlreadyVisible": "Dzisiejsza data jest już widoczna", + "GanttVisibleRange": "Zakres", + "GanttNotScheduled": "Nie zaplanowano", + "GanttMissingStartDates": "{count} zadań nie ma daty rozpoczęcia.", + "GanttSetDatesHint": "Ustaw datę rozpoczęcia i termin zakończenia zadania, aby wyświetlić je na osi czasu.", "GanttHelpCalendarDaysDrag": "Przytrzymaj podczas przeciągania, aby ignorować dni robocze (dni kalendarzowe)", "GanttDragCalendarDays": "Dni kalendarzowe" }, diff --git a/plugins/tracker-assets/lang/pt-br.json b/plugins/tracker-assets/lang/pt-br.json index e335539d269..af8ed33bea5 100644 --- a/plugins/tracker-assets/lang/pt-br.json +++ b/plugins/tracker-assets/lang/pt-br.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "Nenhum problema encontrado para \"{query}\"", "SearchEmptyActiveFilters": "Filtros ativos: {filters}", "SearchEmptyClearFilters": "Procurar sem filtros", - "SearchEmptyAllProjects": "Procurar em todos os projetos" + "SearchEmptyAllProjects": "Procurar em todos os projetos", + "GanttWeekLabel": "S{week}", + "GanttQuarterLabel": "T{quarter}", + "GanttWithoutDates": "{count} sem datas", + "GanttDates": "Datas", + "GanttZoomLabel": "Zoom", + "GanttSetDates": "Definir datas", + "GanttNoScheduledTasks": "Nenhuma tarefa agendada", + "GanttTodayAlreadyVisible": "Hoje já está visível", + "GanttVisibleRange": "Período", + "GanttNotScheduled": "Não agendado", + "GanttMissingStartDates": "{count} tarefas não têm data de início.", + "GanttSetDatesHint": "Defina as datas de início e conclusão de uma tarefa para exibi-la na linha do tempo." }, "status": {} } diff --git a/plugins/tracker-assets/lang/pt.json b/plugins/tracker-assets/lang/pt.json index de2826546d4..7742053a95e 100644 --- a/plugins/tracker-assets/lang/pt.json +++ b/plugins/tracker-assets/lang/pt.json @@ -308,7 +308,19 @@ "SearchEmptyTitle": "Nenhum problema encontrado para \"{query}\"", "SearchEmptyActiveFilters": "Filtros ativos: {filters}", "SearchEmptyClearFilters": "Procurar sem filtros", - "SearchEmptyAllProjects": "Procurar em todos os projetos" + "SearchEmptyAllProjects": "Procurar em todos os projetos", + "GanttWeekLabel": "S{week}", + "GanttQuarterLabel": "T{quarter}", + "GanttWithoutDates": "{count} sem datas", + "GanttDates": "Datas", + "GanttZoomLabel": "Zoom", + "GanttSetDates": "Definir datas", + "GanttNoScheduledTasks": "Não há tarefas agendadas", + "GanttTodayAlreadyVisible": "Hoje já está visível", + "GanttVisibleRange": "Período", + "GanttNotScheduled": "Não agendado", + "GanttMissingStartDates": "{count} tarefas não têm data de início.", + "GanttSetDatesHint": "Defina as datas de início e conclusão de uma tarefa para a apresentar na cronologia." }, "status": {} } diff --git a/plugins/tracker-assets/lang/ru.json b/plugins/tracker-assets/lang/ru.json index ac28e2d4186..b67cf1828c5 100644 --- a/plugins/tracker-assets/lang/ru.json +++ b/plugins/tracker-assets/lang/ru.json @@ -344,6 +344,8 @@ "GanttJumpToDate": "Перейти к дате", "GanttZoomDay": "День", "GanttZoomWeek": "Неделя", + "GanttWeekLabel": "Нед. {week}", + "GanttQuarterLabel": "Кв. {quarter}", "GanttZoomMonth": "Месяц", "GanttZoomQuarter": "Квартал", "GanttZoomCustom": "Другой", @@ -563,7 +565,16 @@ "SearchEmptyTitle": "Не найдено задач по запросу «{query}»", "SearchEmptyActiveFilters": "Активные фильтры: {filters}", "SearchEmptyClearFilters": "Искать без фильтров", - "SearchEmptyAllProjects": "Искать во всех проектах" + "SearchEmptyAllProjects": "Искать во всех проектах", + "GanttWithoutDates": "Без дат: {count}", + "GanttDates": "Даты", + "GanttSetDates": "Задать даты", + "GanttNoScheduledTasks": "Нет запланированных задач", + "GanttTodayAlreadyVisible": "Сегодня уже на экране", + "GanttVisibleRange": "Период", + "GanttNotScheduled": "Не запланировано", + "GanttMissingStartDates": "У {count} задач не задана дата начала.", + "GanttSetDatesHint": "Задайте дату начала и срок в карточке задачи, чтобы увидеть полосу на шкале." }, "status": {} } diff --git a/plugins/tracker-assets/lang/tr.json b/plugins/tracker-assets/lang/tr.json index 3b5786f8cf0..f465a56e61a 100644 --- a/plugins/tracker-assets/lang/tr.json +++ b/plugins/tracker-assets/lang/tr.json @@ -327,6 +327,8 @@ "GanttJumpToDate": "Jump to date", "GanttZoomDay": "Gün", "GanttZoomWeek": "Hafta", + "GanttWeekLabel": "H{week}", + "GanttQuarterLabel": "Ç{quarter}", "GanttZoomMonth": "Ay", "GanttZoomQuarter": "Çeyrek", "GanttZoomCustom": "Özel", @@ -546,7 +548,16 @@ "SearchEmptyTitle": "\"{query}\" için sorun bulunamadı", "SearchEmptyActiveFilters": "Aktif filtreler: {filters}", "SearchEmptyClearFilters": "Filtresiz ara", - "SearchEmptyAllProjects": "Tüm projelerde ara" + "SearchEmptyAllProjects": "Tüm projelerde ara", + "GanttWithoutDates": "Tarihsiz: {count}", + "GanttDates": "Tarihler", + "GanttSetDates": "Tarihleri ayarla", + "GanttNoScheduledTasks": "Planlanmış görev yok", + "GanttTodayAlreadyVisible": "Bugün zaten görünür durumda", + "GanttVisibleRange": "Aralık", + "GanttNotScheduled": "Planlanmadı", + "GanttMissingStartDates": "{count} görevin başlangıç tarihi yok.", + "GanttSetDatesHint": "Zaman çizelgesinde görmek için bir göreve başlangıç ve bitiş tarihleri ekleyin." }, "status": {} } diff --git a/plugins/tracker-assets/lang/zh.json b/plugins/tracker-assets/lang/zh.json index c57a8c98513..68634b0207a 100644 --- a/plugins/tracker-assets/lang/zh.json +++ b/plugins/tracker-assets/lang/zh.json @@ -325,7 +325,19 @@ "SearchEmptyTitle": "未找到与 \"{query}\" 匹配的问题", "SearchEmptyActiveFilters": "活动筛选器:{filters}", "SearchEmptyClearFilters": "不使用筛选器搜索", - "SearchEmptyAllProjects": "在所有项目中搜索" + "SearchEmptyAllProjects": "在所有项目中搜索", + "GanttWeekLabel": "第{week}周", + "GanttQuarterLabel": "第{quarter}季度", + "GanttWithoutDates": "无日期:{count}", + "GanttDates": "日期", + "GanttZoomLabel": "缩放", + "GanttSetDates": "设置日期", + "GanttNoScheduledTasks": "没有已安排的任务", + "GanttTodayAlreadyVisible": "今天已在当前视图中", + "GanttVisibleRange": "范围", + "GanttNotScheduled": "未安排", + "GanttMissingStartDates": "{count} 个任务没有开始日期。", + "GanttSetDatesHint": "为任务设置开始日期和截止日期,即可在时间轴上显示。" }, "status": {} } diff --git a/plugins/tracker-resources/src/components/LinkSubIssueActionPopup.svelte b/plugins/tracker-resources/src/components/LinkSubIssueActionPopup.svelte index 1496874b292..68dc21b6244 100644 --- a/plugins/tracker-resources/src/components/LinkSubIssueActionPopup.svelte +++ b/plugins/tracker-resources/src/components/LinkSubIssueActionPopup.svelte @@ -67,7 +67,7 @@ // Descendants: BFS over parents[0].parentId pointers. const childrenByParent = new Map, Issue[]>() for (const i of all) { - const parentId = i.parents?.[0]?.parentId as Ref | undefined + const parentId = i.parents?.[0]?.parentId if (parentId === undefined) continue const bucket = childrenByParent.get(parentId) if (bucket === undefined) childrenByParent.set(parentId, [i]) diff --git a/plugins/tracker-resources/src/components/gantt/ConfirmCascadePopup.svelte b/plugins/tracker-resources/src/components/gantt/ConfirmCascadePopup.svelte index 46c2b4fa534..2a0e19b36a1 100644 --- a/plugins/tracker-resources/src/components/gantt/ConfirmCascadePopup.svelte +++ b/plugins/tracker-resources/src/components/gantt/ConfirmCascadePopup.svelte @@ -4,7 +4,7 @@ --> @@ -39,7 +39,11 @@
{:else} @@ -446,6 +444,10 @@ {row.groupLabel ?? ''} {row.groupCount ?? 0} + {#if row.groupKey !== undefined && groupRanges.has(row.groupKey)} + {@const range = groupRanges.get(row.groupKey)} + {formatDates(range?.start, range?.due, $themeStore.language) ?? ''} + {/if} {:else} {@const indent = row.depth * 20} @@ -581,6 +583,14 @@ {/if} {/if} + + {#if row.issue !== null} + {@const dates = formatDates(row.issue.startDate, row.issue.dueDate, $themeStore.language)} + {#if dates === null} {#if dir !== null && jumpX !== null} + + + + {:else if tier === 'date'} - - - {:else if tier === 'date'} - - {:else if tier === 'zoom'} -
+
+ {:else if tier === 'zoom'} +
+ {#each zoomPresets as preset (preset.id)} + + {/each} + {#if snap.zoomDropdownSelection === 'custom'} + + {/if} +
{:else if tier === 'undo'}