@industry-theme/backlogmd-kanban-panel 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,17 +7,22 @@ export interface ColumnState {
7
7
  hasMore: boolean;
8
8
  isLoadingMore: boolean;
9
9
  }
10
+ /** Source column names (directory-based) */
11
+ export type SourceColumn = 'tasks' | 'completed';
12
+ /** Display labels for source columns */
13
+ export declare const SOURCE_DISPLAY_LABELS: Record<SourceColumn, string>;
10
14
  export interface UseKanbanDataResult {
11
15
  tasks: Task[];
12
- statuses: string[];
16
+ /** Source columns: "tasks" and "completed" */
17
+ sources: SourceColumn[];
13
18
  isLoading: boolean;
14
19
  error: string | null;
15
20
  isBacklogProject: boolean;
16
- tasksByStatus: Map<string, Task[]>;
21
+ tasksBySource: Map<string, Task[]>;
17
22
  /** Per-column pagination state */
18
23
  columnStates: Map<string, ColumnState>;
19
- /** Load more tasks for a specific status column */
20
- loadMore: (status: string) => Promise<void>;
24
+ /** Load more tasks for a specific source column */
25
+ loadMore: (source: SourceColumn) => Promise<void>;
21
26
  refreshData: () => Promise<void>;
22
27
  updateTaskStatus: (taskId: string, newStatus: string) => Promise<void>;
23
28
  }
@@ -28,8 +33,10 @@ interface UseKanbanDataOptions {
28
33
  pageSize?: number;
29
34
  }
30
35
  /**
31
- * Hook for managing kanban board data with pagination
32
- * Integrates with Backlog.md via @backlog-md/core
36
+ * Hook for managing kanban board data with lazy loading
37
+ *
38
+ * Uses 2-column view (Active/Completed) based on directory structure.
39
+ * Only loads task content for displayed items (no file reads on init).
33
40
  */
34
41
  export declare function useKanbanData(options?: UseKanbanDataOptions): UseKanbanDataResult;
35
42
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useKanbanData.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/hooks/useKanbanData.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,IAAI,EAAwB,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,kCAAkC;IAClC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,mDAAmD;IACnD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAED,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,mBAAmB,CAmUrB"}
1
+ {"version":3,"file":"useKanbanData.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/hooks/useKanbanData.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,IAAI,EAAwB,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,4CAA4C;AAC5C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,WAAW,CAAC;AAEjD,wCAAwC;AACxC,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAG9D,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,8CAA8C;IAC9C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,kCAAkC;IAClC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,mDAAmD;IACnD,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAED,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,mBAAmB,CA4TrB"}
@@ -526,10 +526,32 @@ function extractIdFromPath(filePath) {
526
526
  }
527
527
  return filename.replace(/\.md$/, "");
528
528
  }
529
+ function extractTitleFromPath(filePath) {
530
+ const filename = filePath.split("/").pop() || "";
531
+ const match = filename.match(/^(?:task-)?\d+(?:\.\d+)?\s*-\s*(.+)\.md$/);
532
+ if (match) {
533
+ return match[1].trim();
534
+ }
535
+ return filename.replace(/\.md$/, "");
536
+ }
537
+ function extractSourceFromPath(filePath) {
538
+ if (filePath.includes("/completed/") || filePath.includes("\\completed\\")) {
539
+ return "completed";
540
+ }
541
+ return "tasks";
542
+ }
543
+ function extractTaskIndexFromPath(filePath) {
544
+ return {
545
+ id: extractIdFromPath(filePath),
546
+ filePath,
547
+ title: extractTitleFromPath(filePath),
548
+ source: extractSourceFromPath(filePath)
549
+ };
550
+ }
529
551
  function escapeRegex(str) {
530
552
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
531
553
  }
532
- const DEFAULT_STATUSES$1 = ["To Do", "In Progress", "Done"];
554
+ const DEFAULT_STATUSES = ["To Do", "In Progress", "Done"];
533
555
  function parseBacklogConfig(content) {
534
556
  const config = {};
535
557
  const lines = content.split("\n");
@@ -609,10 +631,10 @@ function parseBacklogConfig(content) {
609
631
  }
610
632
  return {
611
633
  projectName: config.projectName || "Backlog",
612
- statuses: config.statuses || [...DEFAULT_STATUSES$1],
634
+ statuses: config.statuses || [...DEFAULT_STATUSES],
613
635
  labels: config.labels || [],
614
636
  milestones: config.milestones || [],
615
- defaultStatus: config.defaultStatus || DEFAULT_STATUSES$1[0],
637
+ defaultStatus: config.defaultStatus || DEFAULT_STATUSES[0],
616
638
  dateFormat: config.dateFormat || "YYYY-MM-DD",
617
639
  defaultAssignee: config.defaultAssignee,
618
640
  defaultReporter: config.defaultReporter,
@@ -747,6 +769,9 @@ class Core {
747
769
  __publicField(this, "config", null);
748
770
  __publicField(this, "tasks", /* @__PURE__ */ new Map());
749
771
  __publicField(this, "initialized", false);
772
+ /** Lightweight task index for lazy loading (no file reads) */
773
+ __publicField(this, "taskIndex", /* @__PURE__ */ new Map());
774
+ __publicField(this, "lazyInitialized", false);
750
775
  this.projectRoot = options.projectRoot;
751
776
  this.fs = options.adapters.fs;
752
777
  }
@@ -828,6 +853,173 @@ class Core {
828
853
  }
829
854
  this.initialized = true;
830
855
  }
856
+ /**
857
+ * Initialize with lazy loading (no file content reads)
858
+ *
859
+ * Only loads config and builds task index from file paths.
860
+ * Task content is loaded on-demand via loadTask().
861
+ * Use this for web/panel contexts where file reads are expensive.
862
+ *
863
+ * @param filePaths - Array of all file paths in the project
864
+ */
865
+ async initializeLazy(filePaths) {
866
+ if (this.lazyInitialized)
867
+ return;
868
+ const configPath = this.fs.join(this.projectRoot, "backlog", "config.yml");
869
+ const configExists = await this.fs.exists(configPath);
870
+ if (!configExists) {
871
+ throw new Error(`Not a Backlog.md project: config.yml not found at ${configPath}`);
872
+ }
873
+ const configContent = await this.fs.readFile(configPath);
874
+ this.config = parseBacklogConfig(configContent);
875
+ this.taskIndex.clear();
876
+ for (const filePath of filePaths) {
877
+ if (!filePath.endsWith(".md"))
878
+ continue;
879
+ const isTaskFile = filePath.includes("backlog/tasks/") || filePath.includes("backlog\\tasks\\");
880
+ const isCompletedFile = filePath.includes("backlog/completed/") || filePath.includes("backlog\\completed\\");
881
+ if (!isTaskFile && !isCompletedFile)
882
+ continue;
883
+ if (filePath.endsWith("config.yml"))
884
+ continue;
885
+ const indexEntry = extractTaskIndexFromPath(filePath);
886
+ this.taskIndex.set(indexEntry.id, indexEntry);
887
+ }
888
+ this.lazyInitialized = true;
889
+ }
890
+ /**
891
+ * Check if lazy initialization is complete
892
+ */
893
+ isLazyInitialized() {
894
+ return this.lazyInitialized;
895
+ }
896
+ /**
897
+ * Get the task index (lightweight entries)
898
+ */
899
+ getTaskIndex() {
900
+ if (!this.lazyInitialized) {
901
+ throw new Error("Core not lazy initialized. Call initializeLazy() first.");
902
+ }
903
+ return this.taskIndex;
904
+ }
905
+ /**
906
+ * Load a single task by ID (on-demand loading)
907
+ *
908
+ * @param id - Task ID
909
+ * @returns Task or undefined if not found
910
+ */
911
+ async loadTask(id) {
912
+ if (this.tasks.has(id)) {
913
+ return this.tasks.get(id);
914
+ }
915
+ const indexEntry = this.taskIndex.get(id);
916
+ if (!indexEntry) {
917
+ return void 0;
918
+ }
919
+ try {
920
+ const content = await this.fs.readFile(indexEntry.filePath);
921
+ const task = parseTaskMarkdown(content, indexEntry.filePath);
922
+ task.source = indexEntry.source === "completed" ? "completed" : "local";
923
+ this.tasks.set(task.id, task);
924
+ return task;
925
+ } catch (error) {
926
+ console.warn(`Failed to load task ${id} from ${indexEntry.filePath}:`, error);
927
+ return void 0;
928
+ }
929
+ }
930
+ /**
931
+ * Load multiple tasks by ID (on-demand loading)
932
+ *
933
+ * @param ids - Array of task IDs to load
934
+ * @returns Array of loaded tasks (undefined entries filtered out)
935
+ */
936
+ async loadTasks(ids) {
937
+ const tasks = await Promise.all(ids.map((id) => this.loadTask(id)));
938
+ return tasks.filter((t) => t !== void 0);
939
+ }
940
+ /**
941
+ * Get tasks by source (tasks/completed) with pagination
942
+ *
943
+ * This is a lazy-loading alternative to getTasksByStatusPaginated().
944
+ * Groups by directory (tasks/ or completed/) instead of status.
945
+ * Only loads task content for items in the requested page.
946
+ *
947
+ * @param pagination - Pagination options (applied per source)
948
+ * @returns Paginated tasks grouped by source
949
+ */
950
+ async getTasksBySourcePaginated(pagination) {
951
+ if (!this.lazyInitialized) {
952
+ throw new Error("Core not lazy initialized. Call initializeLazy() first.");
953
+ }
954
+ const limit = (pagination == null ? void 0 : pagination.limit) ?? 10;
955
+ const offset = (pagination == null ? void 0 : pagination.offset) ?? 0;
956
+ const sortBy = (pagination == null ? void 0 : pagination.sortBy) ?? "title";
957
+ const sortDirection = (pagination == null ? void 0 : pagination.sortDirection) ?? "asc";
958
+ const sources = ["tasks", "completed"];
959
+ const bySource = /* @__PURE__ */ new Map();
960
+ for (const source of sources) {
961
+ let entries = Array.from(this.taskIndex.values()).filter((e) => e.source === source);
962
+ entries = entries.sort((a, b) => {
963
+ const cmp = a.title.localeCompare(b.title);
964
+ return sortDirection === "asc" ? cmp : -cmp;
965
+ });
966
+ const total = entries.length;
967
+ const pageEntries = entries.slice(offset, offset + limit);
968
+ const items = await this.loadTasks(pageEntries.map((e) => e.id));
969
+ if (sortBy !== "title" && items.length > 0) {
970
+ const sorted = sortTasksBy(items, sortBy, sortDirection);
971
+ bySource.set(source, {
972
+ items: sorted,
973
+ total,
974
+ hasMore: offset + limit < total,
975
+ offset,
976
+ limit
977
+ });
978
+ } else {
979
+ bySource.set(source, {
980
+ items,
981
+ total,
982
+ hasMore: offset + limit < total,
983
+ offset,
984
+ limit
985
+ });
986
+ }
987
+ }
988
+ return {
989
+ bySource,
990
+ sources
991
+ };
992
+ }
993
+ /**
994
+ * Load more tasks for a specific source (lazy loading)
995
+ *
996
+ * @param source - Source to load more from ("tasks" or "completed")
997
+ * @param currentOffset - Current offset (items already loaded)
998
+ * @param pagination - Pagination options
999
+ * @returns Paginated result for the source
1000
+ */
1001
+ async loadMoreForSource(source, currentOffset, pagination) {
1002
+ if (!this.lazyInitialized) {
1003
+ throw new Error("Core not lazy initialized. Call initializeLazy() first.");
1004
+ }
1005
+ const limit = (pagination == null ? void 0 : pagination.limit) ?? 10;
1006
+ const sortDirection = (pagination == null ? void 0 : pagination.sortDirection) ?? "asc";
1007
+ let entries = Array.from(this.taskIndex.values()).filter((e) => e.source === source);
1008
+ entries = entries.sort((a, b) => {
1009
+ const cmp = a.title.localeCompare(b.title);
1010
+ return sortDirection === "asc" ? cmp : -cmp;
1011
+ });
1012
+ const total = entries.length;
1013
+ const pageEntries = entries.slice(currentOffset, currentOffset + limit);
1014
+ const items = await this.loadTasks(pageEntries.map((e) => e.id));
1015
+ return {
1016
+ items,
1017
+ total,
1018
+ hasMore: currentOffset + limit < total,
1019
+ offset: currentOffset,
1020
+ limit
1021
+ };
1022
+ }
831
1023
  /**
832
1024
  * Get the loaded configuration
833
1025
  *
@@ -1155,16 +1347,20 @@ class PanelFileSystemAdapter {
1155
1347
  return path.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\/+/g, "/");
1156
1348
  }
1157
1349
  }
1158
- const DEFAULT_STATUSES = ["To Do", "In Progress", "Done"];
1350
+ const SOURCE_DISPLAY_LABELS = {
1351
+ tasks: "Active",
1352
+ completed: "Completed"
1353
+ };
1354
+ const DEFAULT_SOURCES = ["tasks", "completed"];
1159
1355
  const DEFAULT_PAGE_SIZE = 10;
1160
1356
  function useKanbanData(options) {
1161
1357
  const { context, actions, pageSize = DEFAULT_PAGE_SIZE } = options || {};
1162
1358
  const [tasks, setTasks] = useState([]);
1163
- const [statuses, setStatuses] = useState(DEFAULT_STATUSES);
1359
+ const [sources] = useState(DEFAULT_SOURCES);
1164
1360
  const [isLoading, setIsLoading] = useState(true);
1165
1361
  const [error, setError] = useState(null);
1166
1362
  const [isBacklogProject, setIsBacklogProject] = useState(false);
1167
- const [tasksByStatus, setTasksByStatus] = useState(
1363
+ const [tasksBySource, setTasksBySource] = useState(
1168
1364
  /* @__PURE__ */ new Map()
1169
1365
  );
1170
1366
  const [columnStates, setColumnStates] = useState(
@@ -1213,8 +1409,7 @@ function useKanbanData(options) {
1213
1409
  console.log("[useKanbanData] No context provided");
1214
1410
  setIsBacklogProject(false);
1215
1411
  setTasks([]);
1216
- setStatuses(DEFAULT_STATUSES);
1217
- setTasksByStatus(/* @__PURE__ */ new Map());
1412
+ setTasksBySource(/* @__PURE__ */ new Map());
1218
1413
  setColumnStates(/* @__PURE__ */ new Map());
1219
1414
  setIsLoading(false);
1220
1415
  coreRef.current = null;
@@ -1228,8 +1423,7 @@ function useKanbanData(options) {
1228
1423
  console.log("[useKanbanData] FileTree not available");
1229
1424
  setIsBacklogProject(false);
1230
1425
  setTasks([]);
1231
- setStatuses(DEFAULT_STATUSES);
1232
- setTasksByStatus(/* @__PURE__ */ new Map());
1426
+ setTasksBySource(/* @__PURE__ */ new Map());
1233
1427
  setColumnStates(/* @__PURE__ */ new Map());
1234
1428
  coreRef.current = null;
1235
1429
  return;
@@ -1249,31 +1443,29 @@ function useKanbanData(options) {
1249
1443
  console.log("[useKanbanData] Not a Backlog.md project");
1250
1444
  setIsBacklogProject(false);
1251
1445
  setTasks([]);
1252
- setStatuses(DEFAULT_STATUSES);
1253
- setTasksByStatus(/* @__PURE__ */ new Map());
1446
+ setTasksBySource(/* @__PURE__ */ new Map());
1254
1447
  setColumnStates(/* @__PURE__ */ new Map());
1255
1448
  coreRef.current = null;
1256
1449
  return;
1257
1450
  }
1258
- console.log("[useKanbanData] Loading Backlog.md data with pagination...");
1451
+ console.log("[useKanbanData] Loading Backlog.md data with lazy loading...");
1259
1452
  setIsBacklogProject(true);
1260
- await core.initialize();
1453
+ await core.initializeLazy(filePaths);
1261
1454
  coreRef.current = core;
1262
- const config = core.getConfig();
1263
- const paginatedResult = core.getTasksByStatusPaginated({
1455
+ const paginatedResult = await core.getTasksBySourcePaginated({
1264
1456
  limit: pageSize,
1265
1457
  offset: 0,
1266
1458
  sortBy: "title",
1267
1459
  sortDirection: "asc"
1268
1460
  });
1269
- const newTasksByStatus = /* @__PURE__ */ new Map();
1461
+ const newTasksBySource = /* @__PURE__ */ new Map();
1270
1462
  const newColumnStates = /* @__PURE__ */ new Map();
1271
1463
  let allTasks = [];
1272
- for (const status of paginatedResult.statuses) {
1273
- const columnResult = paginatedResult.byStatus.get(status);
1464
+ for (const source of paginatedResult.sources) {
1465
+ const columnResult = paginatedResult.bySource.get(source);
1274
1466
  if (columnResult) {
1275
- newTasksByStatus.set(status, columnResult.items);
1276
- newColumnStates.set(status, {
1467
+ newTasksBySource.set(source, columnResult.items);
1468
+ newColumnStates.set(source, {
1277
1469
  tasks: columnResult.items,
1278
1470
  total: columnResult.total,
1279
1471
  hasMore: columnResult.hasMore,
@@ -1281,8 +1473,8 @@ function useKanbanData(options) {
1281
1473
  });
1282
1474
  allTasks = allTasks.concat(columnResult.items);
1283
1475
  } else {
1284
- newTasksByStatus.set(status, []);
1285
- newColumnStates.set(status, {
1476
+ newTasksBySource.set(source, []);
1477
+ newColumnStates.set(source, {
1286
1478
  tasks: [],
1287
1479
  total: 0,
1288
1480
  hasMore: false,
@@ -1290,24 +1482,22 @@ function useKanbanData(options) {
1290
1482
  });
1291
1483
  }
1292
1484
  }
1293
- const totalTasks = Array.from(paginatedResult.byStatus.values()).reduce(
1485
+ const totalTasks = Array.from(paginatedResult.bySource.values()).reduce(
1294
1486
  (sum, col) => sum + col.total,
1295
1487
  0
1296
1488
  );
1297
1489
  console.log(
1298
- `[useKanbanData] Loaded ${allTasks.length}/${totalTasks} tasks with ${config.statuses.length} statuses (page size: ${pageSize})`
1490
+ `[useKanbanData] Loaded ${allTasks.length}/${totalTasks} tasks (page size: ${pageSize})`
1299
1491
  );
1300
- setStatuses(config.statuses);
1301
1492
  setTasks(allTasks);
1302
- setTasksByStatus(newTasksByStatus);
1493
+ setTasksBySource(newTasksBySource);
1303
1494
  setColumnStates(newColumnStates);
1304
1495
  } catch (err) {
1305
1496
  console.error("[useKanbanData] Failed to load Backlog.md data:", err);
1306
1497
  setError(err instanceof Error ? err.message : "Failed to load backlog data");
1307
1498
  setIsBacklogProject(false);
1308
1499
  setTasks([]);
1309
- setStatuses(DEFAULT_STATUSES);
1310
- setTasksByStatus(/* @__PURE__ */ new Map());
1500
+ setTasksBySource(/* @__PURE__ */ new Map());
1311
1501
  setColumnStates(/* @__PURE__ */ new Map());
1312
1502
  coreRef.current = null;
1313
1503
  } finally {
@@ -1318,28 +1508,28 @@ function useKanbanData(options) {
1318
1508
  loadBacklogData();
1319
1509
  }, [loadBacklogData]);
1320
1510
  const loadMore = useCallback(
1321
- async (status) => {
1511
+ async (source) => {
1322
1512
  const core = coreRef.current;
1323
1513
  if (!core) {
1324
1514
  console.warn("[useKanbanData] Core not available for loadMore");
1325
1515
  return;
1326
1516
  }
1327
- const currentState = columnStates.get(status);
1517
+ const currentState = columnStates.get(source);
1328
1518
  if (!currentState || !currentState.hasMore || currentState.isLoadingMore) {
1329
1519
  return;
1330
1520
  }
1331
1521
  setColumnStates((prev) => {
1332
1522
  const newStates = new Map(prev);
1333
- const state = newStates.get(status);
1523
+ const state = newStates.get(source);
1334
1524
  if (state) {
1335
- newStates.set(status, { ...state, isLoadingMore: true });
1525
+ newStates.set(source, { ...state, isLoadingMore: true });
1336
1526
  }
1337
1527
  return newStates;
1338
1528
  });
1339
1529
  try {
1340
1530
  const currentOffset = currentState.tasks.length;
1341
- const result = core.loadMoreForStatus(
1342
- status,
1531
+ const result = await core.loadMoreForSource(
1532
+ source,
1343
1533
  currentOffset,
1344
1534
  {
1345
1535
  limit: pageSize,
@@ -1348,14 +1538,14 @@ function useKanbanData(options) {
1348
1538
  }
1349
1539
  );
1350
1540
  console.log(
1351
- `[useKanbanData] Loaded ${result.items.length} more tasks for "${status}" (${currentOffset + result.items.length}/${result.total})`
1541
+ `[useKanbanData] Loaded ${result.items.length} more tasks for "${source}" (${currentOffset + result.items.length}/${result.total})`
1352
1542
  );
1353
1543
  setColumnStates((prev) => {
1354
1544
  const newStates = new Map(prev);
1355
- const state = newStates.get(status);
1545
+ const state = newStates.get(source);
1356
1546
  if (state) {
1357
1547
  const newTasks = [...state.tasks, ...result.items];
1358
- newStates.set(status, {
1548
+ newStates.set(source, {
1359
1549
  tasks: newTasks,
1360
1550
  total: result.total,
1361
1551
  hasMore: result.hasMore,
@@ -1364,21 +1554,21 @@ function useKanbanData(options) {
1364
1554
  }
1365
1555
  return newStates;
1366
1556
  });
1367
- setTasksByStatus((prev) => {
1557
+ setTasksBySource((prev) => {
1368
1558
  const newMap = new Map(prev);
1369
- const currentTasks = newMap.get(status) || [];
1370
- newMap.set(status, [...currentTasks, ...result.items]);
1559
+ const currentTasks = newMap.get(source) || [];
1560
+ newMap.set(source, [...currentTasks, ...result.items]);
1371
1561
  return newMap;
1372
1562
  });
1373
1563
  setTasks((prev) => [...prev, ...result.items]);
1374
1564
  } catch (err) {
1375
- console.error(`[useKanbanData] Failed to load more for "${status}":`, err);
1565
+ console.error(`[useKanbanData] Failed to load more for "${source}":`, err);
1376
1566
  setError(err instanceof Error ? err.message : "Failed to load more tasks");
1377
1567
  setColumnStates((prev) => {
1378
1568
  const newStates = new Map(prev);
1379
- const state = newStates.get(status);
1569
+ const state = newStates.get(source);
1380
1570
  if (state) {
1381
- newStates.set(status, { ...state, isLoadingMore: false });
1571
+ newStates.set(source, { ...state, isLoadingMore: false });
1382
1572
  }
1383
1573
  return newStates;
1384
1574
  });
@@ -1401,11 +1591,11 @@ function useKanbanData(options) {
1401
1591
  );
1402
1592
  return {
1403
1593
  tasks,
1404
- statuses,
1594
+ sources,
1405
1595
  isLoading,
1406
1596
  error,
1407
1597
  isBacklogProject,
1408
- tasksByStatus,
1598
+ tasksBySource,
1409
1599
  columnStates,
1410
1600
  loadMore,
1411
1601
  refreshData,
@@ -1944,10 +2134,10 @@ const KanbanPanelContent = ({
1944
2134
  var _a, _b;
1945
2135
  const { theme: theme2 } = useTheme();
1946
2136
  const [_selectedTask, setSelectedTask] = useState(null);
1947
- const { statuses, tasksByStatus, columnStates, loadMore, error, isBacklogProject, refreshData } = useKanbanData({
2137
+ const { sources, tasksBySource, columnStates, loadMore, error, isBacklogProject, refreshData } = useKanbanData({
1948
2138
  context,
1949
2139
  actions,
1950
- pageSize: 10
2140
+ pageSize: 3
1951
2141
  });
1952
2142
  const handleTaskClick = (task) => {
1953
2143
  setSelectedTask(task);
@@ -2091,21 +2281,21 @@ const KanbanPanelContent = ({
2091
2281
  WebkitOverflowScrolling: "touch"
2092
2282
  // Smooth scrolling on iOS
2093
2283
  },
2094
- children: statuses.map((status) => {
2095
- const columnTasks = tasksByStatus.get(status) || [];
2096
- const columnState = columnStates.get(status);
2284
+ children: sources.map((source) => {
2285
+ const columnTasks = tasksBySource.get(source) || [];
2286
+ const columnState = columnStates.get(source);
2097
2287
  return /* @__PURE__ */ jsx(
2098
2288
  KanbanColumn,
2099
2289
  {
2100
- status,
2290
+ status: SOURCE_DISPLAY_LABELS[source],
2101
2291
  tasks: columnTasks,
2102
2292
  total: columnState == null ? void 0 : columnState.total,
2103
2293
  hasMore: columnState == null ? void 0 : columnState.hasMore,
2104
2294
  isLoadingMore: columnState == null ? void 0 : columnState.isLoadingMore,
2105
- onLoadMore: () => loadMore(status),
2295
+ onLoadMore: () => loadMore(source),
2106
2296
  onTaskClick: handleTaskClick
2107
2297
  },
2108
- status
2298
+ source
2109
2299
  );
2110
2300
  })
2111
2301
  }