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

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.
@@ -1 +1 @@
1
- {"version":3,"file":"KanbanPanel.d.ts","sourceRoot":"","sources":["../../src/panels/KanbanPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AA4LpD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAMrD,CAAC"}
1
+ {"version":3,"file":"KanbanPanel.d.ts","sourceRoot":"","sources":["../../src/panels/KanbanPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AA6LpD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAMrD,CAAC"}
@@ -29,14 +29,17 @@ export interface UseKanbanDataResult {
29
29
  interface UseKanbanDataOptions {
30
30
  context?: PanelContextValue;
31
31
  actions?: PanelActions;
32
- /** Number of tasks to load per column (default: 10) */
33
- pageSize?: number;
32
+ /** Number of active tasks to load (default: 20) */
33
+ tasksLimit?: number;
34
+ /** Number of completed tasks to load (default: 5) */
35
+ completedLimit?: number;
34
36
  }
35
37
  /**
36
38
  * Hook for managing kanban board data with lazy loading
37
39
  *
38
40
  * Uses 2-column view (Active/Completed) based on directory structure.
39
41
  * Only loads task content for displayed items (no file reads on init).
42
+ * Completed tasks are sorted by ID descending (most recent first).
40
43
  */
41
44
  export declare function useKanbanData(options?: UseKanbanDataOptions): UseKanbanDataResult;
42
45
  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,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"}
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,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,mBAAmB,CAoUrB"}
@@ -944,46 +944,45 @@ class Core {
944
944
  * Groups by directory (tasks/ or completed/) instead of status.
945
945
  * Only loads task content for items in the requested page.
946
946
  *
947
- * @param pagination - Pagination options (applied per source)
947
+ * @param options - Per-source pagination options
948
948
  * @returns Paginated tasks grouped by source
949
949
  */
950
- async getTasksBySourcePaginated(pagination) {
950
+ async getTasksBySourcePaginated(options) {
951
951
  if (!this.lazyInitialized) {
952
952
  throw new Error("Core not lazy initialized. Call initializeLazy() first.");
953
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";
954
+ const tasksLimit = (options == null ? void 0 : options.tasksLimit) ?? 10;
955
+ const completedLimit = (options == null ? void 0 : options.completedLimit) ?? 10;
956
+ const offset = (options == null ? void 0 : options.offset) ?? 0;
957
+ const tasksSortDirection = (options == null ? void 0 : options.tasksSortDirection) ?? "asc";
958
+ const completedSortByIdDesc = (options == null ? void 0 : options.completedSortByIdDesc) ?? true;
958
959
  const sources = ["tasks", "completed"];
959
960
  const bySource = /* @__PURE__ */ new Map();
960
961
  for (const source of sources) {
961
962
  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
963
+ const limit = source === "tasks" ? tasksLimit : completedLimit;
964
+ if (source === "completed" && completedSortByIdDesc) {
965
+ entries = entries.sort((a, b) => {
966
+ const aNum = parseInt(a.id.replace(/\D/g, ""), 10) || 0;
967
+ const bNum = parseInt(b.id.replace(/\D/g, ""), 10) || 0;
968
+ return bNum - aNum;
977
969
  });
978
970
  } else {
979
- bySource.set(source, {
980
- items,
981
- total,
982
- hasMore: offset + limit < total,
983
- offset,
984
- limit
971
+ entries = entries.sort((a, b) => {
972
+ const cmp = a.title.localeCompare(b.title);
973
+ return tasksSortDirection === "asc" ? cmp : -cmp;
985
974
  });
986
975
  }
976
+ const total = entries.length;
977
+ const pageEntries = entries.slice(offset, offset + limit);
978
+ const items = await this.loadTasks(pageEntries.map((e) => e.id));
979
+ bySource.set(source, {
980
+ items,
981
+ total,
982
+ hasMore: offset + limit < total,
983
+ offset,
984
+ limit
985
+ });
987
986
  }
988
987
  return {
989
988
  bySource,
@@ -995,20 +994,29 @@ class Core {
995
994
  *
996
995
  * @param source - Source to load more from ("tasks" or "completed")
997
996
  * @param currentOffset - Current offset (items already loaded)
998
- * @param pagination - Pagination options
997
+ * @param options - Pagination options
999
998
  * @returns Paginated result for the source
1000
999
  */
1001
- async loadMoreForSource(source, currentOffset, pagination) {
1000
+ async loadMoreForSource(source, currentOffset, options) {
1002
1001
  if (!this.lazyInitialized) {
1003
1002
  throw new Error("Core not lazy initialized. Call initializeLazy() first.");
1004
1003
  }
1005
- const limit = (pagination == null ? void 0 : pagination.limit) ?? 10;
1006
- const sortDirection = (pagination == null ? void 0 : pagination.sortDirection) ?? "asc";
1004
+ const limit = (options == null ? void 0 : options.limit) ?? 10;
1005
+ const sortDirection = (options == null ? void 0 : options.sortDirection) ?? "asc";
1006
+ const completedSortByIdDesc = (options == null ? void 0 : options.completedSortByIdDesc) ?? true;
1007
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
- });
1008
+ if (source === "completed" && completedSortByIdDesc) {
1009
+ entries = entries.sort((a, b) => {
1010
+ const aNum = parseInt(a.id.replace(/\D/g, ""), 10) || 0;
1011
+ const bNum = parseInt(b.id.replace(/\D/g, ""), 10) || 0;
1012
+ return bNum - aNum;
1013
+ });
1014
+ } else {
1015
+ entries = entries.sort((a, b) => {
1016
+ const cmp = a.title.localeCompare(b.title);
1017
+ return sortDirection === "asc" ? cmp : -cmp;
1018
+ });
1019
+ }
1012
1020
  const total = entries.length;
1013
1021
  const pageEntries = entries.slice(currentOffset, currentOffset + limit);
1014
1022
  const items = await this.loadTasks(pageEntries.map((e) => e.id));
@@ -1352,9 +1360,15 @@ const SOURCE_DISPLAY_LABELS = {
1352
1360
  completed: "Completed"
1353
1361
  };
1354
1362
  const DEFAULT_SOURCES = ["tasks", "completed"];
1355
- const DEFAULT_PAGE_SIZE = 10;
1363
+ const DEFAULT_TASKS_LIMIT = 20;
1364
+ const DEFAULT_COMPLETED_LIMIT = 5;
1356
1365
  function useKanbanData(options) {
1357
- const { context, actions, pageSize = DEFAULT_PAGE_SIZE } = options || {};
1366
+ const {
1367
+ context,
1368
+ actions,
1369
+ tasksLimit = DEFAULT_TASKS_LIMIT,
1370
+ completedLimit = DEFAULT_COMPLETED_LIMIT
1371
+ } = options || {};
1358
1372
  const [tasks, setTasks] = useState([]);
1359
1373
  const [sources] = useState(DEFAULT_SOURCES);
1360
1374
  const [isLoading, setIsLoading] = useState(true);
@@ -1453,10 +1467,11 @@ function useKanbanData(options) {
1453
1467
  await core.initializeLazy(filePaths);
1454
1468
  coreRef.current = core;
1455
1469
  const paginatedResult = await core.getTasksBySourcePaginated({
1456
- limit: pageSize,
1470
+ tasksLimit,
1471
+ completedLimit,
1457
1472
  offset: 0,
1458
- sortBy: "title",
1459
- sortDirection: "asc"
1473
+ tasksSortDirection: "asc",
1474
+ completedSortByIdDesc: true
1460
1475
  });
1461
1476
  const newTasksBySource = /* @__PURE__ */ new Map();
1462
1477
  const newColumnStates = /* @__PURE__ */ new Map();
@@ -1487,7 +1502,7 @@ function useKanbanData(options) {
1487
1502
  0
1488
1503
  );
1489
1504
  console.log(
1490
- `[useKanbanData] Loaded ${allTasks.length}/${totalTasks} tasks (page size: ${pageSize})`
1505
+ `[useKanbanData] Loaded ${allTasks.length}/${totalTasks} tasks (active: ${tasksLimit}, completed: ${completedLimit})`
1491
1506
  );
1492
1507
  setTasks(allTasks);
1493
1508
  setTasksBySource(newTasksBySource);
@@ -1503,7 +1518,7 @@ function useKanbanData(options) {
1503
1518
  } finally {
1504
1519
  setIsLoading(false);
1505
1520
  }
1506
- }, [context, actions, fetchFileContent, pageSize]);
1521
+ }, [context, actions, fetchFileContent, tasksLimit, completedLimit]);
1507
1522
  useEffect(() => {
1508
1523
  loadBacklogData();
1509
1524
  }, [loadBacklogData]);
@@ -1528,13 +1543,14 @@ function useKanbanData(options) {
1528
1543
  });
1529
1544
  try {
1530
1545
  const currentOffset = currentState.tasks.length;
1546
+ const limit = source === "tasks" ? tasksLimit : completedLimit;
1531
1547
  const result = await core.loadMoreForSource(
1532
1548
  source,
1533
1549
  currentOffset,
1534
1550
  {
1535
- limit: pageSize,
1536
- sortBy: "title",
1537
- sortDirection: "asc"
1551
+ limit,
1552
+ sortDirection: "asc",
1553
+ completedSortByIdDesc: source === "completed"
1538
1554
  }
1539
1555
  );
1540
1556
  console.log(
@@ -1574,7 +1590,7 @@ function useKanbanData(options) {
1574
1590
  });
1575
1591
  }
1576
1592
  },
1577
- [columnStates, pageSize]
1593
+ [columnStates, tasksLimit, completedLimit]
1578
1594
  );
1579
1595
  const refreshData = useCallback(async () => {
1580
1596
  await loadBacklogData();
@@ -2137,7 +2153,8 @@ const KanbanPanelContent = ({
2137
2153
  const { sources, tasksBySource, columnStates, loadMore, error, isBacklogProject, refreshData } = useKanbanData({
2138
2154
  context,
2139
2155
  actions,
2140
- pageSize: 3
2156
+ tasksLimit: 20,
2157
+ completedLimit: 5
2141
2158
  });
2142
2159
  const handleTaskClick = (task) => {
2143
2160
  setSelectedTask(task);