Skip to content

Commit 5b3a376

Browse files
committed
Fix kanban manual reorder scope
1 parent 2ee37ce commit 5b3a376

1 file changed

Lines changed: 72 additions & 2 deletions

File tree

src/bases/KanbanView.ts

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class KanbanView extends BasesViewBase {
4545
private draggedSourceSwimlanes: Map<string, string> = new Map(); // Track source swimlane per task for batch operations
4646
private taskInfoCache = new Map<string, TaskInfo>();
4747
private sortScopeTaskPaths = new Map<string, string[]>();
48+
private sortScopeCandidateTaskPaths = new Map<string, string[]>();
4849
private containerListenersRegistered = false;
4950
private columnScrollers = new Map<string, VirtualScroller<TaskInfo>>(); // columnKey -> scroller
5051
private expandedRelationshipFilterMode: TaskCardOptions["expandedRelationshipFilterMode"] =
@@ -350,6 +351,7 @@ export class KanbanView extends BasesViewBase {
350351
this.destroyColumnScrollers();
351352
this.boardEl.empty();
352353
this.sortScopeTaskPaths.clear();
354+
this.sortScopeCandidateTaskPaths.clear();
353355

354356
if (filteredTasks.length === 0) {
355357
// Show "no results" if search returned empty but we had tasks
@@ -375,17 +377,20 @@ export class KanbanView extends BasesViewBase {
375377

376378
// Group tasks
377379
const groups = this.groupTasks(filteredTasks, groupByPropertyId, pathToProps);
380+
const allGroups = this.groupTasks(taskNotes, groupByPropertyId, pathToProps);
378381

379382
// Render swimlanes if configured
380383
if (this.swimLanePropertyId) {
381384
await this.renderWithSwimLanes(
382385
groups,
383386
filteredTasks,
387+
allGroups,
388+
taskNotes,
384389
pathToProps,
385390
groupByPropertyId
386391
);
387392
} else {
388-
await this.renderFlat(groups);
393+
await this.renderFlat(groups, allGroups);
389394
}
390395
} catch (error: any) {
391396
console.error("[TaskNotes][KanbanView] Error rendering:", error);
@@ -433,6 +438,17 @@ export class KanbanView extends BasesViewBase {
433438
return this.sortScopeTaskPaths.get(this.getSortScopeKey(groupKey, swimLaneKey));
434439
}
435440

441+
private getCandidateSortScopePaths(groupKey: string, swimLaneKey: string | null = null): string[] | undefined {
442+
return this.sortScopeCandidateTaskPaths.get(this.getSortScopeKey(groupKey, swimLaneKey));
443+
}
444+
445+
private setSortScopeCandidatePaths(entries: Iterable<[string, string[]]>): void {
446+
this.sortScopeCandidateTaskPaths.clear();
447+
for (const [scopeKey, paths] of entries) {
448+
this.sortScopeCandidateTaskPaths.set(scopeKey, [...paths]);
449+
}
450+
}
451+
436452
private async confirmLargeReorder(
437453
editCount: number,
438454
groupKey: string,
@@ -686,9 +702,18 @@ export class KanbanView extends BasesViewBase {
686702
}
687703
}
688704

689-
private async renderFlat(groups: Map<string, TaskInfo[]>): Promise<void> {
705+
private async renderFlat(
706+
groups: Map<string, TaskInfo[]>,
707+
allGroups: Map<string, TaskInfo[]>
708+
): Promise<void> {
690709
if (!this.boardEl) return;
691710
this.sortScopeTaskPaths.clear();
711+
this.setSortScopeCandidatePaths(
712+
Array.from(allGroups.entries()).map(([groupKey, tasks]) => [
713+
this.getSortScopeKey(groupKey),
714+
tasks.map((task) => task.path),
715+
])
716+
);
692717

693718
// Set CSS variable for column width (allows responsive override)
694719
this.boardEl.style.setProperty("--kanban-column-width", `${this.columnWidth}px`);
@@ -729,6 +754,8 @@ export class KanbanView extends BasesViewBase {
729754
private async renderWithSwimLanes(
730755
groups: Map<string, TaskInfo[]>,
731756
allTasks: TaskInfo[],
757+
allGroups: Map<string, TaskInfo[]>,
758+
allTasksForCandidateScopes: TaskInfo[],
732759
pathToProps: Map<string, Record<string, any>>,
733760
groupByPropertyId: string
734761
): Promise<void> {
@@ -784,6 +811,47 @@ export class KanbanView extends BasesViewBase {
784811
}
785812
}
786813

814+
const candidateSwimLanes = new Map<string, Map<string, TaskInfo[]>>();
815+
const candidateSwimLaneValues = new Set<string>();
816+
817+
for (const task of allTasksForCandidateScopes) {
818+
const props = pathToProps.get(task.path) || {};
819+
const swimLaneValue = this.getPropertyValue(props, this.swimLanePropertyId);
820+
const swimLaneKey = this.valueToString(swimLaneValue);
821+
candidateSwimLaneValues.add(swimLaneKey);
822+
}
823+
824+
for (const swimLaneKey of candidateSwimLaneValues) {
825+
const swimLaneMap = new Map<string, TaskInfo[]>();
826+
candidateSwimLanes.set(swimLaneKey, swimLaneMap);
827+
828+
for (const [columnKey] of allGroups) {
829+
swimLaneMap.set(columnKey, []);
830+
}
831+
}
832+
833+
for (const [columnKey, columnTasks] of allGroups) {
834+
for (const task of columnTasks) {
835+
const props = pathToProps.get(task.path) || {};
836+
const swimLaneValue = this.getPropertyValue(props, this.swimLanePropertyId);
837+
const swimLaneKey = this.valueToString(swimLaneValue);
838+
const swimLane = candidateSwimLanes.get(swimLaneKey);
839+
if (!swimLane) continue;
840+
if (swimLane.has(columnKey)) {
841+
swimLane.get(columnKey)!.push(task);
842+
}
843+
}
844+
}
845+
846+
this.setSortScopeCandidatePaths(
847+
Array.from(candidateSwimLanes.entries()).flatMap(([swimLaneKey, columns]) =>
848+
Array.from(columns.entries()).map(([columnKey, tasks]) => [
849+
this.getSortScopeKey(columnKey, swimLaneKey),
850+
tasks.map((task) => task.path),
851+
] as [string, string[]])
852+
)
853+
);
854+
787855
// Apply column ordering
788856
const columnKeys = Array.from(groups.keys());
789857
const orderedKeys = this.applyColumnOrder(groupByPropertyId, columnKeys);
@@ -2409,6 +2477,7 @@ export class KanbanView extends BasesViewBase {
24092477
? [{ property: cleanSwimLaneForSort, value: newSwimLaneValue }]
24102478
: undefined;
24112479
const visibleTaskPaths = this.getVisibleSortScopePaths(newGroupValue, newSwimLaneValue);
2480+
const candidateTaskPaths = this.getCandidateSortScopePaths(newGroupValue, newSwimLaneValue);
24122481

24132482
this.debugLog("SORT-ORDER-CHECK", {
24142483
hasDropTarget: !!dropTarget,
@@ -2474,6 +2543,7 @@ export class KanbanView extends BasesViewBase {
24742543
scopeFilters: sortScopeFilters,
24752544
taskInfoCache: this.taskInfoCache,
24762545
visibleTaskPaths,
2546+
candidateTaskPaths,
24772547
}
24782548
);
24792549
if (sortOrderPlan.sortOrder === null) {

0 commit comments

Comments
 (0)