Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
14 changes: 14 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true

- name: Checkout tasknotes-nlp-core
run: git clone --depth 1 https://github.com/callumalpass/tasknotes-nlp-core.git ../tasknotes-nlp-core

- name: Install tasknotes-nlp-core dependencies
run: npm ci --prefix ../tasknotes-nlp-core --prefer-offline --no-audit
timeout-minutes: 5

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
Expand Down Expand Up @@ -123,6 +130,13 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true

- name: Checkout tasknotes-nlp-core
run: git clone --depth 1 https://github.com/callumalpass/tasknotes-nlp-core.git ../tasknotes-nlp-core

- name: Install tasknotes-nlp-core dependencies
run: npm ci --prefix ../tasknotes-nlp-core --prefer-offline --no-audit
timeout-minutes: 5

- name: Setup Node.js
uses: actions/setup-node@v4
Expand Down
30 changes: 30 additions & 0 deletions PR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# fix/swimlane-order

## Deterministic swimlane ordering

Swimlane ordering is now deterministic and independent from card sorting. Status/priority swimlanes follow their configured order, other fields sort alphabetically with "None" last. When filters/search are active, empty swimlanes are hidden. Switching between swimlane and non-swimlane boards resets the layout correctly.

Examples (illustrative):

- Status swimlanes follow the custom status order; empty lanes are hidden when filters/search are active
- Context swimlanes are sorted A–Z with "None" at the end

## Changelog

- Sort swimlanes by property semantics instead of task order
- Include empty status/priority swimlanes based on configured options
- Keep "None" swimlane last for free-text fields
- Hide empty swimlanes when filters/search are active
- Reset swimlane layout class when toggling swimlanes or switching boards

## Tests

- `npm run i18n:sync`
- `npm run lint` (warnings only)
- `node generate-release-notes-import.mjs`
- `npm run typecheck`
- `npm run test:ci -- --verbose` (fails: `tests/unit/issues/due-date-timezone-inconsistency.test.ts` — confirmed failing in `upstream/main`)
- `npm run test:integration`
- `npm run test:performance` (no tests found)
- `npm run build` (warning: missing OAuth client IDs)
- `npm run test:build`
9 changes: 9 additions & 0 deletions docs/views/kanban-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Access these options through the Bases view settings panel:
- **Hide Empty Columns**: When enabled, columns containing no tasks are hidden from the view
- **Show items in multiple columns**: When enabled (default), tasks with multiple values in list properties (contexts, tags, projects) appear in each individual column. For example, a task with `contexts: [work, call]` appears in both the "work" and "call" columns. When disabled, tasks appear in a single combined column (e.g., "work, call")
- **Column Order**: Managed automatically when dragging column headers. Stores custom column ordering
- **Swim Lane Order**: Managed automatically when dragging swimlane labels. Stores custom row ordering, layered on top of the default semantic order (status order, priority weight, alphabetical, "None" last)
A common setup is to keep one board grouped by status and another grouped by project or context, each in a separate `.base` file.

## Interface Layout
Expand All @@ -49,6 +50,10 @@ Each swimlane row includes:
- Multiple cells, each representing a column within that swimlane
- Scrollable cells containing task cards

Drag a swimlane label cell to reorder rows. The new order persists per `.base` file in the `swimLaneOrder` config and survives reloads. Default ordering follows property semantics — configured status order for status, weight for priority, alphabetical otherwise, with `None` always last. A custom user order layers on top: when a previously unseen value first appears, it slots in using the default rule. Row reorder is desktop-only — no touch/mobile support yet.

When a search or filter is active, only matching rows are visible. Reordering while filtered is safe — hidden rows are anchored at their previous positions instead of being lost.

## Task Cards

Each task card displays information based on the visible properties configured in the Bases view. Standard task information includes title, priority, due date, and scheduled date.
Expand Down Expand Up @@ -116,10 +121,13 @@ views:
type: tasknotesKanban
groupBy:
property: task.status
direction: ASC
config:
swimLane: task.priority
columnWidth: 300
hideEmptyColumns: true
# Auto-managed when dragging swimlane labels:
swimLaneOrder: '{"task.priority":["high","normal","low","None"]}'
---
```

Expand All @@ -128,6 +136,7 @@ This configuration creates a Kanban board with:
- Swimlanes based on task priority
- 300px column width
- Empty columns hidden
- Custom swimlane row order pinned via `swimLaneOrder`

## Filtering and Sorting

Expand Down
5 changes: 3 additions & 2 deletions jest.integration.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ module.exports = {
// Only mock Obsidian and UI libraries - use real date/parsing libraries
'^obsidian$': '<rootDir>/tests/__mocks__/obsidian.ts',
'^@fullcalendar/(.*)$': '<rootDir>/tests/__mocks__/fullcalendar.ts',
'^yaml$': '<rootDir>/tests/__mocks__/yaml.ts'
'^yaml$': '<rootDir>/tests/__mocks__/yaml.ts',
'^tasknotes-nlp-core$': '<rootDir>/tests/integration/mocks/tasknotes-nlp-core.ts'
// chrono-node, rrule, ical.js, date-fns will use real implementations
},
// Integration tests may need more time for complex workflows
Expand All @@ -28,4 +29,4 @@ module.exports = {
'!src/main.ts',
'!tests/**/*'
]
};
};
Loading