@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;
|
|
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
|
|
33
|
-
|
|
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,
|
|
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"}
|
package/dist/panels.bundle.js
CHANGED
|
@@ -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
|
|
947
|
+
* @param options - Per-source pagination options
|
|
948
948
|
* @returns Paginated tasks grouped by source
|
|
949
949
|
*/
|
|
950
|
-
async getTasksBySourcePaginated(
|
|
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
|
|
955
|
-
const
|
|
956
|
-
const
|
|
957
|
-
const
|
|
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
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
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
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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
|
|
997
|
+
* @param options - Pagination options
|
|
999
998
|
* @returns Paginated result for the source
|
|
1000
999
|
*/
|
|
1001
|
-
async loadMoreForSource(source, currentOffset,
|
|
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 = (
|
|
1006
|
-
const sortDirection = (
|
|
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
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
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
|
|
1363
|
+
const DEFAULT_TASKS_LIMIT = 20;
|
|
1364
|
+
const DEFAULT_COMPLETED_LIMIT = 5;
|
|
1356
1365
|
function useKanbanData(options) {
|
|
1357
|
-
const {
|
|
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
|
-
|
|
1470
|
+
tasksLimit,
|
|
1471
|
+
completedLimit,
|
|
1457
1472
|
offset: 0,
|
|
1458
|
-
|
|
1459
|
-
|
|
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 (
|
|
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,
|
|
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
|
|
1536
|
-
|
|
1537
|
-
|
|
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,
|
|
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
|
-
|
|
2156
|
+
tasksLimit: 20,
|
|
2157
|
+
completedLimit: 5
|
|
2141
2158
|
});
|
|
2142
2159
|
const handleTaskClick = (task) => {
|
|
2143
2160
|
setSelectedTask(task);
|