@industry-theme/backlogmd-kanban-panel 1.0.8 → 1.0.10
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.
- package/dist/panels/KanbanPanel.d.ts.map +1 -1
- package/dist/panels/kanban/components/KanbanColumn.d.ts +2 -0
- package/dist/panels/kanban/components/KanbanColumn.d.ts.map +1 -1
- package/dist/panels/kanban/hooks/useKanbanData.d.ts +25 -1
- package/dist/panels/kanban/hooks/useKanbanData.d.ts.map +1 -1
- package/dist/panels.bundle.js +231 -59
- package/dist/panels.bundle.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KanbanPanel.d.ts","sourceRoot":"","sources":["../../src/panels/KanbanPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"KanbanPanel.d.ts","sourceRoot":"","sources":["../../src/panels/KanbanPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAG9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAyWpD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAMrD,CAAC"}
|
|
@@ -12,6 +12,8 @@ interface KanbanColumnProps {
|
|
|
12
12
|
/** Callback to load more tasks */
|
|
13
13
|
onLoadMore?: () => void;
|
|
14
14
|
onTaskClick?: (task: Task) => void;
|
|
15
|
+
/** Whether column should take full width (for narrow/mobile views) */
|
|
16
|
+
fullWidth?: boolean;
|
|
15
17
|
}
|
|
16
18
|
export declare const KanbanColumn: React.FC<KanbanColumnProps>;
|
|
17
19
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KanbanColumn.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/components/KanbanColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"KanbanColumn.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/components/KanbanColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsRpD,CAAC"}
|
|
@@ -9,8 +9,24 @@ export interface ColumnState {
|
|
|
9
9
|
}
|
|
10
10
|
/** Source column names (directory-based) */
|
|
11
11
|
export type SourceColumn = 'tasks' | 'completed';
|
|
12
|
-
/**
|
|
12
|
+
/** Status column names (for 3-column view) */
|
|
13
|
+
export type StatusColumn = 'todo' | 'in-progress' | 'completed';
|
|
14
|
+
/** Display labels for status columns */
|
|
15
|
+
export declare const STATUS_DISPLAY_LABELS: Record<StatusColumn, string>;
|
|
16
|
+
/** Display labels for source columns (legacy) */
|
|
13
17
|
export declare const SOURCE_DISPLAY_LABELS: Record<SourceColumn, string>;
|
|
18
|
+
/** Status-based column state (computed from source data) */
|
|
19
|
+
export interface StatusColumnState {
|
|
20
|
+
tasks: Task[];
|
|
21
|
+
count: number;
|
|
22
|
+
}
|
|
23
|
+
/** Active tasks pagination state */
|
|
24
|
+
export interface ActiveTasksState {
|
|
25
|
+
total: number;
|
|
26
|
+
loaded: number;
|
|
27
|
+
hasMore: boolean;
|
|
28
|
+
isLoadingMore: boolean;
|
|
29
|
+
}
|
|
14
30
|
export interface UseKanbanDataResult {
|
|
15
31
|
tasks: Task[];
|
|
16
32
|
/** Source columns: "tasks" and "completed" */
|
|
@@ -25,6 +41,14 @@ export interface UseKanbanDataResult {
|
|
|
25
41
|
loadMore: (source: SourceColumn) => Promise<void>;
|
|
26
42
|
refreshData: () => Promise<void>;
|
|
27
43
|
updateTaskStatus: (taskId: string, newStatus: string) => Promise<void>;
|
|
44
|
+
/** Status columns for 3-column view */
|
|
45
|
+
statusColumns: StatusColumn[];
|
|
46
|
+
/** Tasks grouped by status (To Do, In Progress, Completed) */
|
|
47
|
+
tasksByStatus: Map<StatusColumn, StatusColumnState>;
|
|
48
|
+
/** Active tasks (To Do + In Progress) pagination state */
|
|
49
|
+
activeTasksState: ActiveTasksState;
|
|
50
|
+
/** Load more active tasks */
|
|
51
|
+
loadMoreActive: () => Promise<void>;
|
|
28
52
|
}
|
|
29
53
|
interface UseKanbanDataOptions {
|
|
30
54
|
context?: PanelContextValue;
|
|
@@ -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;
|
|
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,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC;AAEhE,wCAAwC;AACxC,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAI9D,CAAC;AASF,iDAAiD;AACjD,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAG9D,CAAC;AAEF,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,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;IACvE,uCAAuC;IACvC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,8DAA8D;IAC9D,aAAa,EAAE,GAAG,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACpD,0DAA0D;IAC1D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,6BAA6B;IAC7B,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;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,CAmYrB"}
|
package/dist/panels.bundle.js
CHANGED
|
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
5
5
|
import * as React2 from "react";
|
|
6
|
-
import React2__default, { forwardRef, createElement, createContext, useState, useEffect, useContext, useRef, useCallback, useImperativeHandle, useMemo
|
|
6
|
+
import React2__default, { forwardRef, createElement, createContext, useState, useEffect, useContext, useRef, useCallback, useLayoutEffect, useImperativeHandle, useMemo } from "react";
|
|
7
7
|
import { createPortal } from "react-dom";
|
|
8
8
|
/**
|
|
9
9
|
* @license lucide-react v0.552.0 - ISC
|
|
@@ -1507,9 +1507,10 @@ class PanelFileSystemAdapter {
|
|
|
1507
1507
|
return path2.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\/+/g, "/");
|
|
1508
1508
|
}
|
|
1509
1509
|
}
|
|
1510
|
-
const
|
|
1511
|
-
|
|
1512
|
-
|
|
1510
|
+
const STATUS_DISPLAY_LABELS = {
|
|
1511
|
+
"todo": "To Do",
|
|
1512
|
+
"in-progress": "In Progress",
|
|
1513
|
+
"completed": "Completed"
|
|
1513
1514
|
};
|
|
1514
1515
|
const DEFAULT_SOURCES = ["tasks", "completed"];
|
|
1515
1516
|
const DEFAULT_TASKS_LIMIT = 20;
|
|
@@ -1768,6 +1769,30 @@ function useKanbanData(options) {
|
|
|
1768
1769
|
},
|
|
1769
1770
|
[]
|
|
1770
1771
|
);
|
|
1772
|
+
const statusColumns = ["todo", "in-progress", "completed"];
|
|
1773
|
+
const tasksByStatus = (() => {
|
|
1774
|
+
const result = /* @__PURE__ */ new Map();
|
|
1775
|
+
const activeTasks = tasksBySource.get("tasks") || [];
|
|
1776
|
+
const completedTasks = tasksBySource.get("completed") || [];
|
|
1777
|
+
const todoTasks = activeTasks.filter((t) => t.status === "To Do");
|
|
1778
|
+
const inProgressTasks = activeTasks.filter((t) => t.status === "In Progress");
|
|
1779
|
+
result.set("todo", { tasks: todoTasks, count: todoTasks.length });
|
|
1780
|
+
result.set("in-progress", { tasks: inProgressTasks, count: inProgressTasks.length });
|
|
1781
|
+
result.set("completed", { tasks: completedTasks, count: completedTasks.length });
|
|
1782
|
+
return result;
|
|
1783
|
+
})();
|
|
1784
|
+
const activeTasksState = (() => {
|
|
1785
|
+
const activeColumnState = columnStates.get("tasks");
|
|
1786
|
+
return {
|
|
1787
|
+
total: (activeColumnState == null ? void 0 : activeColumnState.total) || 0,
|
|
1788
|
+
loaded: (activeColumnState == null ? void 0 : activeColumnState.tasks.length) || 0,
|
|
1789
|
+
hasMore: (activeColumnState == null ? void 0 : activeColumnState.hasMore) || false,
|
|
1790
|
+
isLoadingMore: (activeColumnState == null ? void 0 : activeColumnState.isLoadingMore) || false
|
|
1791
|
+
};
|
|
1792
|
+
})();
|
|
1793
|
+
const loadMoreActive = useCallback(async () => {
|
|
1794
|
+
await loadMore("tasks");
|
|
1795
|
+
}, [loadMore]);
|
|
1771
1796
|
return {
|
|
1772
1797
|
tasks,
|
|
1773
1798
|
sources,
|
|
@@ -1778,7 +1803,12 @@ function useKanbanData(options) {
|
|
|
1778
1803
|
columnStates,
|
|
1779
1804
|
loadMore,
|
|
1780
1805
|
refreshData,
|
|
1781
|
-
updateTaskStatus
|
|
1806
|
+
updateTaskStatus,
|
|
1807
|
+
// New 3-column view exports
|
|
1808
|
+
statusColumns,
|
|
1809
|
+
tasksByStatus,
|
|
1810
|
+
activeTasksState,
|
|
1811
|
+
loadMoreActive
|
|
1782
1812
|
};
|
|
1783
1813
|
}
|
|
1784
1814
|
const KanbanColumn = ({
|
|
@@ -1788,7 +1818,8 @@ const KanbanColumn = ({
|
|
|
1788
1818
|
hasMore = false,
|
|
1789
1819
|
isLoadingMore = false,
|
|
1790
1820
|
onLoadMore,
|
|
1791
|
-
onTaskClick
|
|
1821
|
+
onTaskClick,
|
|
1822
|
+
fullWidth = false
|
|
1792
1823
|
}) => {
|
|
1793
1824
|
const { theme: theme2 } = useTheme();
|
|
1794
1825
|
const getPriorityColor = (priority) => {
|
|
@@ -1810,8 +1841,8 @@ const KanbanColumn = ({
|
|
|
1810
1841
|
style: {
|
|
1811
1842
|
flex: "1 1 0",
|
|
1812
1843
|
// Grow to fill available width equally
|
|
1813
|
-
minWidth: "280px",
|
|
1814
|
-
maxWidth: "500px",
|
|
1844
|
+
minWidth: fullWidth ? void 0 : "280px",
|
|
1845
|
+
maxWidth: fullWidth ? void 0 : "500px",
|
|
1815
1846
|
// Cap max width for readability
|
|
1816
1847
|
height: "100%",
|
|
1817
1848
|
// Fill parent height
|
|
@@ -1875,7 +1906,11 @@ const KanbanColumn = ({
|
|
|
1875
1906
|
flexDirection: "column",
|
|
1876
1907
|
gap: "8px",
|
|
1877
1908
|
overflowY: "auto",
|
|
1878
|
-
|
|
1909
|
+
overflowX: "hidden",
|
|
1910
|
+
WebkitOverflowScrolling: "touch",
|
|
1911
|
+
// Add padding for scroll content, use margin trick to prevent clipping
|
|
1912
|
+
paddingRight: "4px",
|
|
1913
|
+
marginRight: "-4px"
|
|
1879
1914
|
},
|
|
1880
1915
|
children: [
|
|
1881
1916
|
tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
@@ -2054,7 +2089,8 @@ const KanbanColumn = ({
|
|
|
2054
2089
|
"Loading..."
|
|
2055
2090
|
] }) : `Load more (${remaining} remaining)`
|
|
2056
2091
|
}
|
|
2057
|
-
)
|
|
2092
|
+
),
|
|
2093
|
+
/* @__PURE__ */ jsx("div", { style: { flexShrink: 0, height: "4px" } })
|
|
2058
2094
|
]
|
|
2059
2095
|
}
|
|
2060
2096
|
),
|
|
@@ -2324,7 +2360,31 @@ const KanbanPanelContent = ({
|
|
|
2324
2360
|
var _a, _b;
|
|
2325
2361
|
const { theme: theme2 } = useTheme();
|
|
2326
2362
|
const [_selectedTask, setSelectedTask] = useState(null);
|
|
2327
|
-
const
|
|
2363
|
+
const [selectedTab, setSelectedTab] = useState("todo");
|
|
2364
|
+
const [isNarrowView, setIsNarrowView] = useState(false);
|
|
2365
|
+
const containerRef = useRef(null);
|
|
2366
|
+
useLayoutEffect(() => {
|
|
2367
|
+
const container = containerRef.current;
|
|
2368
|
+
if (!container) return;
|
|
2369
|
+
const observer = new ResizeObserver((entries) => {
|
|
2370
|
+
for (const entry of entries) {
|
|
2371
|
+
setIsNarrowView(entry.contentRect.width < 768);
|
|
2372
|
+
}
|
|
2373
|
+
});
|
|
2374
|
+
observer.observe(container);
|
|
2375
|
+
return () => observer.disconnect();
|
|
2376
|
+
}, []);
|
|
2377
|
+
const {
|
|
2378
|
+
statusColumns,
|
|
2379
|
+
tasksByStatus,
|
|
2380
|
+
columnStates,
|
|
2381
|
+
loadMore,
|
|
2382
|
+
activeTasksState,
|
|
2383
|
+
loadMoreActive,
|
|
2384
|
+
error,
|
|
2385
|
+
isBacklogProject,
|
|
2386
|
+
refreshData
|
|
2387
|
+
} = useKanbanData({
|
|
2328
2388
|
context,
|
|
2329
2389
|
actions,
|
|
2330
2390
|
tasksLimit: 20,
|
|
@@ -2404,6 +2464,7 @@ const KanbanPanelContent = ({
|
|
|
2404
2464
|
return /* @__PURE__ */ jsxs(
|
|
2405
2465
|
"div",
|
|
2406
2466
|
{
|
|
2467
|
+
ref: containerRef,
|
|
2407
2468
|
style: {
|
|
2408
2469
|
padding: "clamp(12px, 3vw, 20px)",
|
|
2409
2470
|
// Responsive padding for mobile
|
|
@@ -2428,22 +2489,72 @@ const KanbanPanelContent = ({
|
|
|
2428
2489
|
// Don't shrink header
|
|
2429
2490
|
display: "flex",
|
|
2430
2491
|
alignItems: "center",
|
|
2492
|
+
justifyContent: "space-between",
|
|
2431
2493
|
gap: "12px",
|
|
2432
2494
|
flexWrap: "wrap"
|
|
2433
2495
|
},
|
|
2434
2496
|
children: [
|
|
2435
|
-
/* @__PURE__ */
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2497
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
|
|
2498
|
+
/* @__PURE__ */ jsx(Kanban, { size: 24, color: theme2.colors.primary }),
|
|
2499
|
+
/* @__PURE__ */ jsx(
|
|
2500
|
+
"h2",
|
|
2501
|
+
{
|
|
2502
|
+
style: {
|
|
2503
|
+
margin: 0,
|
|
2504
|
+
fontSize: theme2.fontSizes[4],
|
|
2505
|
+
color: theme2.colors.text
|
|
2506
|
+
},
|
|
2507
|
+
children: "Kanban Board"
|
|
2508
|
+
}
|
|
2509
|
+
)
|
|
2510
|
+
] }),
|
|
2511
|
+
isBacklogProject && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "16px", flexWrap: "wrap" }, children: [
|
|
2512
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: statusColumns.map((status) => {
|
|
2513
|
+
const statusState = tasksByStatus.get(status);
|
|
2514
|
+
const count = (statusState == null ? void 0 : statusState.count) || 0;
|
|
2515
|
+
const completedState = columnStates.get("completed");
|
|
2516
|
+
const displayCount = status === "completed" && completedState ? `${count}/${completedState.total}` : count;
|
|
2517
|
+
return /* @__PURE__ */ jsxs(
|
|
2518
|
+
"span",
|
|
2519
|
+
{
|
|
2520
|
+
style: {
|
|
2521
|
+
fontSize: theme2.fontSizes[1],
|
|
2522
|
+
color: theme2.colors.textSecondary,
|
|
2523
|
+
background: theme2.colors.backgroundSecondary,
|
|
2524
|
+
padding: "4px 10px",
|
|
2525
|
+
borderRadius: theme2.radii[1],
|
|
2526
|
+
fontWeight: theme2.fontWeights.medium
|
|
2527
|
+
},
|
|
2528
|
+
children: [
|
|
2529
|
+
STATUS_DISPLAY_LABELS[status],
|
|
2530
|
+
": ",
|
|
2531
|
+
displayCount
|
|
2532
|
+
]
|
|
2533
|
+
},
|
|
2534
|
+
status
|
|
2535
|
+
);
|
|
2536
|
+
}) }),
|
|
2537
|
+
activeTasksState.hasMore && /* @__PURE__ */ jsx(
|
|
2538
|
+
"button",
|
|
2539
|
+
{
|
|
2540
|
+
onClick: loadMoreActive,
|
|
2541
|
+
disabled: activeTasksState.isLoadingMore,
|
|
2542
|
+
style: {
|
|
2543
|
+
background: theme2.colors.primary,
|
|
2544
|
+
color: theme2.colors.background,
|
|
2545
|
+
border: "none",
|
|
2546
|
+
borderRadius: theme2.radii[2],
|
|
2547
|
+
padding: "6px 12px",
|
|
2548
|
+
fontSize: theme2.fontSizes[1],
|
|
2549
|
+
fontWeight: theme2.fontWeights.medium,
|
|
2550
|
+
cursor: activeTasksState.isLoadingMore ? "wait" : "pointer",
|
|
2551
|
+
opacity: activeTasksState.isLoadingMore ? 0.7 : 1,
|
|
2552
|
+
transition: "opacity 0.2s ease"
|
|
2553
|
+
},
|
|
2554
|
+
children: activeTasksState.isLoadingMore ? "Loading..." : `Load more active (${activeTasksState.total - activeTasksState.loaded} remaining)`
|
|
2555
|
+
}
|
|
2556
|
+
)
|
|
2557
|
+
] })
|
|
2447
2558
|
]
|
|
2448
2559
|
}
|
|
2449
2560
|
),
|
|
@@ -2475,42 +2586,103 @@ const KanbanPanelContent = ({
|
|
|
2475
2586
|
canInitialize,
|
|
2476
2587
|
onInitialize: handleInitialize
|
|
2477
2588
|
}
|
|
2478
|
-
) : /* @__PURE__ */
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2589
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2590
|
+
isNarrowView && /* @__PURE__ */ jsx(
|
|
2591
|
+
"div",
|
|
2592
|
+
{
|
|
2593
|
+
style: {
|
|
2594
|
+
flexShrink: 0,
|
|
2595
|
+
display: "flex",
|
|
2596
|
+
gap: "4px",
|
|
2597
|
+
background: theme2.colors.backgroundSecondary,
|
|
2598
|
+
borderRadius: theme2.radii[2],
|
|
2599
|
+
padding: "4px"
|
|
2600
|
+
},
|
|
2601
|
+
children: statusColumns.map((status) => {
|
|
2602
|
+
const isSelected = status === selectedTab;
|
|
2603
|
+
const statusState = tasksByStatus.get(status);
|
|
2604
|
+
const count = (statusState == null ? void 0 : statusState.count) || 0;
|
|
2605
|
+
return /* @__PURE__ */ jsxs(
|
|
2606
|
+
"button",
|
|
2607
|
+
{
|
|
2608
|
+
onClick: () => setSelectedTab(status),
|
|
2609
|
+
style: {
|
|
2610
|
+
flex: 1,
|
|
2611
|
+
padding: "10px 12px",
|
|
2612
|
+
border: "none",
|
|
2613
|
+
borderRadius: theme2.radii[1],
|
|
2614
|
+
background: isSelected ? theme2.colors.primary : "transparent",
|
|
2615
|
+
color: isSelected ? theme2.colors.background : theme2.colors.textSecondary,
|
|
2616
|
+
fontSize: theme2.fontSizes[1],
|
|
2617
|
+
fontWeight: theme2.fontWeights.medium,
|
|
2618
|
+
cursor: "pointer",
|
|
2619
|
+
transition: "all 0.2s ease",
|
|
2620
|
+
display: "flex",
|
|
2621
|
+
alignItems: "center",
|
|
2622
|
+
justifyContent: "center",
|
|
2623
|
+
gap: "6px"
|
|
2624
|
+
},
|
|
2625
|
+
children: [
|
|
2626
|
+
STATUS_DISPLAY_LABELS[status],
|
|
2627
|
+
/* @__PURE__ */ jsx(
|
|
2628
|
+
"span",
|
|
2629
|
+
{
|
|
2630
|
+
style: {
|
|
2631
|
+
background: isSelected ? "rgba(255,255,255,0.2)" : theme2.colors.background,
|
|
2632
|
+
padding: "2px 6px",
|
|
2633
|
+
borderRadius: theme2.radii[1],
|
|
2634
|
+
fontSize: theme2.fontSizes[0]
|
|
2635
|
+
},
|
|
2636
|
+
children: count
|
|
2637
|
+
}
|
|
2638
|
+
)
|
|
2639
|
+
]
|
|
2640
|
+
},
|
|
2641
|
+
status
|
|
2642
|
+
);
|
|
2643
|
+
})
|
|
2644
|
+
}
|
|
2645
|
+
),
|
|
2646
|
+
/* @__PURE__ */ jsx(
|
|
2647
|
+
"div",
|
|
2648
|
+
{
|
|
2649
|
+
style: {
|
|
2650
|
+
flex: 1,
|
|
2651
|
+
display: "flex",
|
|
2652
|
+
gap: "16px",
|
|
2653
|
+
justifyContent: "center",
|
|
2654
|
+
// Center columns when they hit max-width
|
|
2655
|
+
overflowX: isNarrowView ? "hidden" : "auto",
|
|
2656
|
+
overflowY: "hidden",
|
|
2657
|
+
paddingBottom: "8px",
|
|
2658
|
+
minHeight: 0,
|
|
2659
|
+
// Allow flex child to shrink below content size
|
|
2660
|
+
WebkitOverflowScrolling: "touch"
|
|
2661
|
+
// Smooth scrolling on iOS
|
|
2662
|
+
},
|
|
2663
|
+
children: statusColumns.filter((status) => !isNarrowView || status === selectedTab).map((status) => {
|
|
2664
|
+
const statusState = tasksByStatus.get(status);
|
|
2665
|
+
const columnTasks = (statusState == null ? void 0 : statusState.tasks) || [];
|
|
2666
|
+
const isCompleted = status === "completed";
|
|
2667
|
+
const completedState = columnStates.get("completed");
|
|
2668
|
+
return /* @__PURE__ */ jsx(
|
|
2669
|
+
KanbanColumn,
|
|
2670
|
+
{
|
|
2671
|
+
status: STATUS_DISPLAY_LABELS[status],
|
|
2672
|
+
tasks: columnTasks,
|
|
2673
|
+
total: isCompleted ? completedState == null ? void 0 : completedState.total : void 0,
|
|
2674
|
+
hasMore: isCompleted ? completedState == null ? void 0 : completedState.hasMore : false,
|
|
2675
|
+
isLoadingMore: isCompleted ? completedState == null ? void 0 : completedState.isLoadingMore : false,
|
|
2676
|
+
onLoadMore: isCompleted ? () => loadMore("completed") : void 0,
|
|
2677
|
+
onTaskClick: handleTaskClick,
|
|
2678
|
+
fullWidth: isNarrowView
|
|
2679
|
+
},
|
|
2680
|
+
status
|
|
2681
|
+
);
|
|
2682
|
+
})
|
|
2683
|
+
}
|
|
2684
|
+
)
|
|
2685
|
+
] })
|
|
2514
2686
|
]
|
|
2515
2687
|
}
|
|
2516
2688
|
);
|