diff --git a/frontend/src/components/gantt/GanttChart.vue b/frontend/src/components/gantt/GanttChart.vue index 19a4e1124..0fbcabf76 100644 --- a/frontend/src/components/gantt/GanttChart.vue +++ b/frontend/src/components/gantt/GanttChart.vue @@ -102,6 +102,7 @@ import type {ITask, ITaskPartialWithId} from '@/modelTypes/ITask' import type {DateISO} from '@/types/DateISO' import type {GanttFilters} from '@/views/project/helpers/useGanttFilters' import type {GanttBarModel, GanttBarDateType} from '@/composables/useGanttBar' +import {useProjectStore} from '@/stores/projects' import GanttChartBody from '@/components/gantt/GanttChartBody.vue' import GanttRow from '@/components/gantt/GanttRow.vue' @@ -117,6 +118,7 @@ import {roundToNaturalDayBoundary} from '@/helpers/time/roundToNaturalDayBoundar const props = defineProps<{ isLoading: boolean, filters: GanttFilters, + includeSubprojects: boolean, tasks: Map, defaultTaskStartDate: DateISO defaultTaskEndDate: DateISO @@ -131,6 +133,7 @@ const dayWidthPixels = ref(0) let resizeObserver: ResizeObserver const {tasks, filters} = toRefs(props) +const projectStore = useProjectStore() const dayjsLanguageLoading = useDayjsLanguageSync(dayjs) const ganttContainer = ref(null) @@ -245,6 +248,24 @@ function getRoundedDate(value: string | Date | undefined, fallback: Date | strin return roundToNaturalDayBoundary(value ? new Date(value) : new Date(fallback), isStart) } +function getTaskLabel(task: ITask): string { + if (!props.includeSubprojects) { + return task.title + } + + const isProjectContext = filters.value.projectId > 0 + if (isProjectContext && task.projectId === filters.value.projectId) { + return task.title + } + + const projectTitle = projectStore.projects[task.projectId]?.title + if (!projectTitle) { + return task.title + } + + return `${task.title} ยท ${projectTitle}` +} + function transformTaskToGanttBar(node: GanttTaskTreeNode): GanttBarModel { const t = node.task const DEFAULT_SPAN_DAYS = 7 @@ -286,7 +307,7 @@ function transformTaskToGanttBar(node: GanttTaskTreeNode): GanttBarModel { start: startDate, end: endDate, meta: { - label: t.title, + label: getTaskLabel(t), task: t, color: taskColor, hasActualDates: Boolean(t.startDate && (t.endDate || t.dueDate)), diff --git a/frontend/src/components/project/partials/FilterPopup.vue b/frontend/src/components/project/partials/FilterPopup.vue index 1ece58801..6a0742a0a 100644 --- a/frontend/src/components/project/partials/FilterPopup.vue +++ b/frontend/src/components/project/partials/FilterPopup.vue @@ -20,15 +20,18 @@ class="filter-popup" :change-immediately="false" :filter-from-view="filterFromView" + :show-include-subprojects-toggle="isProjectView" + :include-subprojects="includeSubprojects" show-close @close="modalOpen = false" + @update:includeSubprojects="updateIncludeSubprojects" @showResults="showResults" />