Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b0195b0
Gantt headers with week and days
srozen Dec 15, 2025
4876e35
Add Month Header and Grouping
srozen Dec 15, 2025
b86595c
Sticky scrolling and placeholder values
srozen Dec 15, 2025
2a9d9de
Remove placeholder values
srozen Dec 15, 2025
5c3ca90
Dedicated component for Gantt chart header
srozen Dec 15, 2025
2398d9c
Add rows with virtual rendering and horizontal scrolling
srozen Dec 15, 2025
189926a
Make use of resizeObserver to dynamically adapt the virtual renderer …
srozen Dec 15, 2025
1fc6902
Handle overflow and border-radius
srozen Dec 15, 2025
5fbbfff
Merge branch 'main' of github.com:n-side-dev/wefa into SOFA-310-we-fa…
srozen Dec 16, 2025
4e0408f
Row highlight when hovering
srozen Dec 16, 2025
5880905
Lint and format
srozen Dec 16, 2025
8967543
Include GanttChartComponent export in lib.ts
srozen Dec 16, 2025
665a6e1
Fix Knip
srozen Dec 16, 2025
ac7ed94
shade on weekends
FabianSouris Dec 19, 2025
a74521c
implement base featureset for Gantt Chart
FabianSouris Dec 22, 2025
3ed7ae8
add translation system and documentation
FabianSouris Dec 22, 2025
0aa0851
adapt translation to standard
FabianSouris Dec 22, 2025
0633af6
add a story with custom tooltip and click event
FabianSouris Dec 23, 2025
e4adc24
add inline comments
FabianSouris Dec 23, 2025
856a7fc
add links feature to Gantt chart (currently dirty)
FabianSouris Dec 24, 2025
f9841bd
refactor the structure of the Gantt chart and fix header stickiness a…
FabianSouris Jan 9, 2026
c422b5c
Merge branch 'main' of github.com:n-side-dev/wefa into SOFA-310-gantt…
srozen Jan 12, 2026
74cc289
PR comments
FabianSouris Jan 20, 2026
4b7a6f3
Merge branch 'main' into SOFA-310-gantt-chart-clean-structure
srozen Jan 20, 2026
0aa932d
PR last comment and AGENTS.md adaptation to match props definition co…
FabianSouris Jan 21, 2026
87f28fe
Merge branch 'main' into SOFA-310-gantt-chart-clean-structure
FabianSouris Jan 22, 2026
48d9043
update package-lock
FabianSouris Jan 22, 2026
6569ead
fix format
FabianSouris Jan 22, 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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- **Component discovery**: inspect `src/components`, exported barrels (`src/components/**/index.ts`), and `@nside/wefa` type definitions before crafting new UI. Use `npm info @nside/wefa` or the local `dist/lib.d.ts` for quick lookup.
- **PrimeVue composition**: when WeFa lacks a widget, compose PrimeVue primitives with Tailwind classes. Imports follow `import Component from 'primevue/component'` and styling sticks to utility classes or theme tokens (`bg-primary-500`, `text-surface-900`, etc.).
- **State & data utilities**: rely on provided composables (`src/composables`), Pinia stores (`src/stores`), and network helpers (`src/network`). Prefer enhancing these layers rather than re-implementing ad-hoc logic inside components.
- **Props definition**: use `const { prop1 = prop1Default, ... } = defineProps<YourPropsType>()` with explicit interfaces/types. Avoid the usage of `withDefault()`.
- **Stories & docs**: every component lives with `.stories.ts`, `.mdx`, and spec files under its folder. Keep stories authoritative and update MDX docs when props/state change.
- **Quality gates**: run `npm run lint-check`, `npm run format-check`, `npm run test:unit`, `npm run test:e2e` (when flows/routing change), `npm run build`, and regenerate Storybook (`npm run storybook` or `npm run build-storybook`) before handing work off.

Expand Down
3 changes: 2 additions & 1 deletion vue/eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export default defineConfigWithVueTs(
"order": [ "template", "script", "style" ] // Enforce this precise order in component definition!
}],
"vitest/prefer-called-exactly-once-with": "off", // Exactly once is not always possible
'sonarjs/todo-tag': 'warn' // TODOs can refer to issues that are not yet fixed
"sonarjs/todo-tag": "warn", // TODOs can refer to issues that are not yet fixed
"security/detect-object-injection": "off" // False positives are common with this rule in TS projects
}
},
{
Expand Down
6 changes: 5 additions & 1 deletion vue/knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@
"ignoreDependencies": ["@tailwindcss/cli", "@vee-validate/zod"],
"tags": [
"-lintignore"
]
],
"storybook": {
"config": [".storybook/main.ts"],
"entry": [".storybook/preview.ts", "src/**/*.stories.@(js|jsx|ts|tsx)"]
}
}
63 changes: 63 additions & 0 deletions vue/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@
"@tailwindcss/vite": "^4.1.18",
"@tanstack/vue-query": "^5.92.8",
"@vee-validate/zod": "^4.15.1",
"@vueuse/core": "^14.1.0",
"axios": "^1.13.2",
"luxon": "^3.7.2",
"marked": "^17.0.1",
"pinia": "^3.0.4",
"plotly.js-dist-min": "^3.3.1",
Expand All @@ -96,6 +98,7 @@
"@tsconfig/node22": "^22.0.5",
"@types/eslint-plugin-security": "^3.0.0",
"@types/jsdom": "^27.0.0",
"@types/luxon": "^3.7.1",
"@types/node": "^25.0.9",
"@types/plotly.js-dist-min": "^2.3.4",
"@vitejs/plugin-vue": "^6.0.3",
Expand Down
143 changes: 143 additions & 0 deletions vue/src/components/GanttChartComponent/GanttChartComponent.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Meta, Canvas, ArgTypes } from '@storybook/addon-docs/blocks'
import * as GanttChartStories from './GanttChartComponent.stories'

<Meta of={GanttChartStories} />

# Gantt Chart

A flexible, virtualized Gantt chart that supports daily and weekly views, layered activity types, and translation-ready labels.

## Overview

The GanttChart component renders a calendar grid with month and week headers, and a virtualized list of rows. Activities can be rendered as stripes, primary bars, or compact stacked minis. Weekly view collapses the grid to week columns and expands month headers across overlapping weeks.

### Key Features

- **Daily & Weekly Views**: Toggle with `viewMode`.
- **Layered Activities**: Stripe, bar, and mini styles with overlap rules.
- **Stacked Minis**: Overlapping minis grow row height automatically.
- **Virtualized Rows**: Smooth scrolling for large datasets.
- **Translation Ready**: All user-facing labels are passed through `t()`.
- **Configurable Sidebar**: Adjust the label column width via `leftHeaderWidthPx`.

## Basic Usage

<Canvas of={GanttChartStories.Default} />

```vue
<template>
<GanttChartComponent
:start-date="startDate"
:end-date="endDate"
:rows="rows"
:links="links"
header-label="gantt_chart.header"
/>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import GanttChartComponent from '@/components/GanttChartComponent/GanttChartComponent.vue'

const startDate = ref(new Date(2026, 0, 1))
const endDate = ref(new Date(2026, 0, 2))
const rows = ref([
{
id: 1,
header: 'gantt_chart.row',
activities: [
{
id: 'planned',
label: 'gantt_chart.activity',
startDate: new Date(2026, 0, 1),
endDate: new Date(2026, 0, 4),
visualType: 'stripe',
color: 'rgba(59, 130, 246, 0.2)',
},
{
id: 'optimized',
label: 'gantt_chart.activity',
startDate: new Date(2026, 0, 2),
endDate: new Date(2026, 0, 8),
visualType: 'bar',
colorClass: 'bg-emerald-400/80',
},
],
},
])
const links = ref([{ fromId: 'planned', toId: 'optimized' }])
</script>
```

## Weekly View

```vue
<GanttChartComponent
:start-date="startDate"
:end-date="endDate"
:rows="rows"
view-mode="week"
:show-weekend-shading="false"
/>
```

- Weekly view renders a single week cell per column.
- Activities fill any week they overlap (inclusive by week).
- Month headers can span overlapping weeks.

## Activity Types

Activities support a `visualType`:

- `stripe`: diagonal background context
- `bar`: primary rounded bar
- `mini`: compact bar, stacked into lanes when overlapping

## Tooltips and Clicks

```vue
<GanttChartComponent
:start-date="startDate"
:end-date="endDate"
:rows="rows"
:links="links"
:activity-tooltip="(activity, row) => `${row?.id}: ${activity.label}`"
:activity-click="(activity, row) => console.log(activity, row)"
/>
```

## API Reference

<ArgTypes of={GanttChartStories} />

```ts
export type GanttChartActivityData = {
id?: string | number
label?: string
startDate: Date
endDate: Date
visualType?: 'stripe' | 'bar' | 'mini'
color?: string
colorClass?: string
}

export type GanttChartRowData = {
id?: string | number
label?: string
header?: string
activities: GanttChartActivityData[]
}

export type GanttChartLinkData = {
id?: string | number
fromId: string | number
toId: string | number
type?: 'finish-start' | 'start-start'
color?: string
}
```

## Translation Notes

- `headerLabel`, `row.header`, `row.label`, and `activity.label` are treated as translation keys.
- Week labels use the key `gantt_chart.week` by default.
Loading
Loading