@industry-theme/backlogmd-kanban-panel 1.0.25 → 1.0.27
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/KanbanPanel.stories.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/components/TaskCard.d.ts +1 -0
- package/dist/panels/kanban/components/TaskCard.d.ts.map +1 -1
- package/dist/panels/kanban/components/TaskModal.d.ts +6 -1
- package/dist/panels/kanban/components/TaskModal.d.ts.map +1 -1
- package/dist/panels/milestone/hooks/useMilestoneData.d.ts.map +1 -1
- package/dist/panels.bundle.js +460 -406
- package/dist/panels.bundle.js.map +1 -1
- package/package.json +1 -1
package/dist/panels.bundle.js
CHANGED
|
@@ -3740,78 +3740,70 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
3740
3740
|
* This source code is licensed under the ISC license.
|
|
3741
3741
|
* See the LICENSE file in the root directory of this source tree.
|
|
3742
3742
|
*/
|
|
3743
|
-
const __iconNode$
|
|
3743
|
+
const __iconNode$m = [
|
|
3744
3744
|
["path", { d: "M8 2v4", key: "1cmpym" }],
|
|
3745
3745
|
["path", { d: "M16 2v4", key: "4m81vk" }],
|
|
3746
3746
|
["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
|
|
3747
3747
|
["path", { d: "M3 10h18", key: "8toen8" }]
|
|
3748
3748
|
];
|
|
3749
|
-
const Calendar = createLucideIcon("calendar", __iconNode$
|
|
3749
|
+
const Calendar = createLucideIcon("calendar", __iconNode$m);
|
|
3750
3750
|
/**
|
|
3751
3751
|
* @license lucide-react v0.552.0 - ISC
|
|
3752
3752
|
*
|
|
3753
3753
|
* This source code is licensed under the ISC license.
|
|
3754
3754
|
* See the LICENSE file in the root directory of this source tree.
|
|
3755
3755
|
*/
|
|
3756
|
-
const __iconNode$
|
|
3757
|
-
const Check = createLucideIcon("check", __iconNode$
|
|
3756
|
+
const __iconNode$l = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
|
|
3757
|
+
const Check = createLucideIcon("check", __iconNode$l);
|
|
3758
3758
|
/**
|
|
3759
3759
|
* @license lucide-react v0.552.0 - ISC
|
|
3760
3760
|
*
|
|
3761
3761
|
* This source code is licensed under the ISC license.
|
|
3762
3762
|
* See the LICENSE file in the root directory of this source tree.
|
|
3763
3763
|
*/
|
|
3764
|
-
const __iconNode$
|
|
3765
|
-
const ChevronDown = createLucideIcon("chevron-down", __iconNode$
|
|
3764
|
+
const __iconNode$k = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
3765
|
+
const ChevronDown = createLucideIcon("chevron-down", __iconNode$k);
|
|
3766
3766
|
/**
|
|
3767
3767
|
* @license lucide-react v0.552.0 - ISC
|
|
3768
3768
|
*
|
|
3769
3769
|
* This source code is licensed under the ISC license.
|
|
3770
3770
|
* See the LICENSE file in the root directory of this source tree.
|
|
3771
3771
|
*/
|
|
3772
|
-
const __iconNode$
|
|
3773
|
-
const ChevronRight = createLucideIcon("chevron-right", __iconNode$l);
|
|
3774
|
-
/**
|
|
3775
|
-
* @license lucide-react v0.552.0 - ISC
|
|
3776
|
-
*
|
|
3777
|
-
* This source code is licensed under the ISC license.
|
|
3778
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
3779
|
-
*/
|
|
3780
|
-
const __iconNode$k = [
|
|
3772
|
+
const __iconNode$j = [
|
|
3781
3773
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
3782
3774
|
["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
|
|
3783
3775
|
["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
|
|
3784
3776
|
];
|
|
3785
|
-
const CircleAlert = createLucideIcon("circle-alert", __iconNode$
|
|
3777
|
+
const CircleAlert = createLucideIcon("circle-alert", __iconNode$j);
|
|
3786
3778
|
/**
|
|
3787
3779
|
* @license lucide-react v0.552.0 - ISC
|
|
3788
3780
|
*
|
|
3789
3781
|
* This source code is licensed under the ISC license.
|
|
3790
3782
|
* See the LICENSE file in the root directory of this source tree.
|
|
3791
3783
|
*/
|
|
3792
|
-
const __iconNode$
|
|
3784
|
+
const __iconNode$i = [
|
|
3793
3785
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
3794
3786
|
["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
|
|
3795
3787
|
];
|
|
3796
|
-
const CircleCheck = createLucideIcon("circle-check", __iconNode$
|
|
3788
|
+
const CircleCheck = createLucideIcon("circle-check", __iconNode$i);
|
|
3797
3789
|
/**
|
|
3798
3790
|
* @license lucide-react v0.552.0 - ISC
|
|
3799
3791
|
*
|
|
3800
3792
|
* This source code is licensed under the ISC license.
|
|
3801
3793
|
* See the LICENSE file in the root directory of this source tree.
|
|
3802
3794
|
*/
|
|
3803
|
-
const __iconNode$
|
|
3795
|
+
const __iconNode$h = [
|
|
3804
3796
|
["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
|
|
3805
3797
|
["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
|
|
3806
3798
|
];
|
|
3807
|
-
const Copy = createLucideIcon("copy", __iconNode$
|
|
3799
|
+
const Copy = createLucideIcon("copy", __iconNode$h);
|
|
3808
3800
|
/**
|
|
3809
3801
|
* @license lucide-react v0.552.0 - ISC
|
|
3810
3802
|
*
|
|
3811
3803
|
* This source code is licensed under the ISC license.
|
|
3812
3804
|
* See the LICENSE file in the root directory of this source tree.
|
|
3813
3805
|
*/
|
|
3814
|
-
const __iconNode$
|
|
3806
|
+
const __iconNode$g = [
|
|
3815
3807
|
["path", { d: "m15 15 6 6", key: "1s409w" }],
|
|
3816
3808
|
["path", { d: "m15 9 6-6", key: "ko1vev" }],
|
|
3817
3809
|
["path", { d: "M21 16v5h-5", key: "1ck2sf" }],
|
|
@@ -3821,26 +3813,26 @@ const __iconNode$h = [
|
|
|
3821
3813
|
["path", { d: "M3 8V3h5", key: "1ln10m" }],
|
|
3822
3814
|
["path", { d: "M9 9 3 3", key: "v551iv" }]
|
|
3823
3815
|
];
|
|
3824
|
-
const Expand = createLucideIcon("expand", __iconNode$
|
|
3816
|
+
const Expand = createLucideIcon("expand", __iconNode$g);
|
|
3825
3817
|
/**
|
|
3826
3818
|
* @license lucide-react v0.552.0 - ISC
|
|
3827
3819
|
*
|
|
3828
3820
|
* This source code is licensed under the ISC license.
|
|
3829
3821
|
* See the LICENSE file in the root directory of this source tree.
|
|
3830
3822
|
*/
|
|
3831
|
-
const __iconNode$
|
|
3823
|
+
const __iconNode$f = [
|
|
3832
3824
|
["path", { d: "M15 3h6v6", key: "1q9fwt" }],
|
|
3833
3825
|
["path", { d: "M10 14 21 3", key: "gplh6r" }],
|
|
3834
3826
|
["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
|
|
3835
3827
|
];
|
|
3836
|
-
const ExternalLink = createLucideIcon("external-link", __iconNode$
|
|
3828
|
+
const ExternalLink = createLucideIcon("external-link", __iconNode$f);
|
|
3837
3829
|
/**
|
|
3838
3830
|
* @license lucide-react v0.552.0 - ISC
|
|
3839
3831
|
*
|
|
3840
3832
|
* This source code is licensed under the ISC license.
|
|
3841
3833
|
* See the LICENSE file in the root directory of this source tree.
|
|
3842
3834
|
*/
|
|
3843
|
-
const __iconNode$
|
|
3835
|
+
const __iconNode$e = [
|
|
3844
3836
|
[
|
|
3845
3837
|
"path",
|
|
3846
3838
|
{
|
|
@@ -3853,14 +3845,14 @@ const __iconNode$f = [
|
|
|
3853
3845
|
["path", { d: "M16 13H8", key: "t4e002" }],
|
|
3854
3846
|
["path", { d: "M16 17H8", key: "z1uh3a" }]
|
|
3855
3847
|
];
|
|
3856
|
-
const FileText = createLucideIcon("file-text", __iconNode$
|
|
3848
|
+
const FileText = createLucideIcon("file-text", __iconNode$e);
|
|
3857
3849
|
/**
|
|
3858
3850
|
* @license lucide-react v0.552.0 - ISC
|
|
3859
3851
|
*
|
|
3860
3852
|
* This source code is licensed under the ISC license.
|
|
3861
3853
|
* See the LICENSE file in the root directory of this source tree.
|
|
3862
3854
|
*/
|
|
3863
|
-
const __iconNode$
|
|
3855
|
+
const __iconNode$d = [
|
|
3864
3856
|
[
|
|
3865
3857
|
"path",
|
|
3866
3858
|
{
|
|
@@ -3869,14 +3861,14 @@ const __iconNode$e = [
|
|
|
3869
3861
|
}
|
|
3870
3862
|
]
|
|
3871
3863
|
];
|
|
3872
|
-
const Flag = createLucideIcon("flag", __iconNode$
|
|
3864
|
+
const Flag = createLucideIcon("flag", __iconNode$d);
|
|
3873
3865
|
/**
|
|
3874
3866
|
* @license lucide-react v0.552.0 - ISC
|
|
3875
3867
|
*
|
|
3876
3868
|
* This source code is licensed under the ISC license.
|
|
3877
3869
|
* See the LICENSE file in the root directory of this source tree.
|
|
3878
3870
|
*/
|
|
3879
|
-
const __iconNode$
|
|
3871
|
+
const __iconNode$c = [
|
|
3880
3872
|
["path", { d: "M12 10v6", key: "1bos4e" }],
|
|
3881
3873
|
["path", { d: "M9 13h6", key: "1uhe8q" }],
|
|
3882
3874
|
[
|
|
@@ -3887,32 +3879,20 @@ const __iconNode$d = [
|
|
|
3887
3879
|
}
|
|
3888
3880
|
]
|
|
3889
3881
|
];
|
|
3890
|
-
const FolderPlus = createLucideIcon("folder-plus", __iconNode$
|
|
3882
|
+
const FolderPlus = createLucideIcon("folder-plus", __iconNode$c);
|
|
3891
3883
|
/**
|
|
3892
3884
|
* @license lucide-react v0.552.0 - ISC
|
|
3893
3885
|
*
|
|
3894
3886
|
* This source code is licensed under the ISC license.
|
|
3895
3887
|
* See the LICENSE file in the root directory of this source tree.
|
|
3896
3888
|
*/
|
|
3897
|
-
const __iconNode$
|
|
3889
|
+
const __iconNode$b = [
|
|
3898
3890
|
["line", { x1: "6", x2: "6", y1: "3", y2: "15", key: "17qcm7" }],
|
|
3899
3891
|
["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
|
|
3900
3892
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
3901
3893
|
["path", { d: "M18 9a9 9 0 0 1-9 9", key: "n2h4wq" }]
|
|
3902
3894
|
];
|
|
3903
|
-
const GitBranch = createLucideIcon("git-branch", __iconNode$
|
|
3904
|
-
/**
|
|
3905
|
-
* @license lucide-react v0.552.0 - ISC
|
|
3906
|
-
*
|
|
3907
|
-
* This source code is licensed under the ISC license.
|
|
3908
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
3909
|
-
*/
|
|
3910
|
-
const __iconNode$b = [
|
|
3911
|
-
["path", { d: "M5 3v14", key: "9nsxs2" }],
|
|
3912
|
-
["path", { d: "M12 3v8", key: "1h2ygw" }],
|
|
3913
|
-
["path", { d: "M19 3v18", key: "1sk56x" }]
|
|
3914
|
-
];
|
|
3915
|
-
const Kanban = createLucideIcon("kanban", __iconNode$b);
|
|
3895
|
+
const GitBranch = createLucideIcon("git-branch", __iconNode$b);
|
|
3916
3896
|
/**
|
|
3917
3897
|
* @license lucide-react v0.552.0 - ISC
|
|
3918
3898
|
*
|
|
@@ -6149,7 +6129,8 @@ function useKanbanData(options) {
|
|
|
6149
6129
|
const TaskCard = ({
|
|
6150
6130
|
task,
|
|
6151
6131
|
onClick,
|
|
6152
|
-
isDragOverlay = false
|
|
6132
|
+
isDragOverlay = false,
|
|
6133
|
+
isSelected = false
|
|
6153
6134
|
}) => {
|
|
6154
6135
|
const { theme: theme2 } = useTheme();
|
|
6155
6136
|
const {
|
|
@@ -6176,10 +6157,10 @@ const TaskCard = ({
|
|
|
6176
6157
|
};
|
|
6177
6158
|
const style2 = {
|
|
6178
6159
|
flexShrink: 0,
|
|
6179
|
-
background: theme2.colors.surface,
|
|
6160
|
+
background: isSelected ? `${theme2.colors.primary}10` : theme2.colors.surface,
|
|
6180
6161
|
borderRadius: theme2.radii[2],
|
|
6181
6162
|
padding: "12px",
|
|
6182
|
-
border: `1px solid ${theme2.colors.border}`,
|
|
6163
|
+
border: `1px solid ${isSelected ? theme2.colors.primary : theme2.colors.border}`,
|
|
6183
6164
|
borderLeft: `4px solid ${getPriorityColor(task.priority)}`,
|
|
6184
6165
|
cursor: isDragOverlay ? "grabbing" : "grab",
|
|
6185
6166
|
transition: isDragging ? "none" : "all 0.2s ease",
|
|
@@ -6189,6 +6170,10 @@ const TaskCard = ({
|
|
|
6189
6170
|
// When dragging, the original card stays in place but becomes a placeholder
|
|
6190
6171
|
// The DragOverlay handles the visual movement
|
|
6191
6172
|
opacity: isDragging ? 0.4 : 1,
|
|
6173
|
+
// Selected card styling
|
|
6174
|
+
...isSelected && !isDragOverlay && {
|
|
6175
|
+
boxShadow: `0 0 0 1px ${theme2.colors.primary}`
|
|
6176
|
+
},
|
|
6192
6177
|
// Overlay card styling
|
|
6193
6178
|
...isDragOverlay && {
|
|
6194
6179
|
boxShadow: `0 8px 16px rgba(0, 0, 0, 0.15)`,
|
|
@@ -6328,7 +6313,8 @@ const KanbanColumn = ({
|
|
|
6328
6313
|
isLoadingMore = false,
|
|
6329
6314
|
onLoadMore,
|
|
6330
6315
|
onTaskClick,
|
|
6331
|
-
fullWidth = false
|
|
6316
|
+
fullWidth = false,
|
|
6317
|
+
selectedTaskId
|
|
6332
6318
|
}) => {
|
|
6333
6319
|
const { theme: theme2 } = useTheme();
|
|
6334
6320
|
const { setNodeRef, isOver } = useDroppable({
|
|
@@ -6417,7 +6403,8 @@ const KanbanColumn = ({
|
|
|
6417
6403
|
TaskCard,
|
|
6418
6404
|
{
|
|
6419
6405
|
task,
|
|
6420
|
-
onClick: onTaskClick
|
|
6406
|
+
onClick: onTaskClick,
|
|
6407
|
+
isSelected: selectedTaskId === task.id
|
|
6421
6408
|
},
|
|
6422
6409
|
task.id
|
|
6423
6410
|
)),
|
|
@@ -6741,6 +6728,7 @@ const TaskModal = ({
|
|
|
6741
6728
|
onSave,
|
|
6742
6729
|
task,
|
|
6743
6730
|
defaultStatus = "To Do",
|
|
6731
|
+
defaultMilestone = "",
|
|
6744
6732
|
availableStatuses = ["To Do", "In Progress", "Done"],
|
|
6745
6733
|
availableMilestones = []
|
|
6746
6734
|
}) => {
|
|
@@ -6773,11 +6761,11 @@ const TaskModal = ({
|
|
|
6773
6761
|
setPriority("medium");
|
|
6774
6762
|
setLabels("");
|
|
6775
6763
|
setAssignee("");
|
|
6776
|
-
setMilestone(
|
|
6764
|
+
setMilestone(defaultMilestone);
|
|
6777
6765
|
}
|
|
6778
6766
|
setError(null);
|
|
6779
6767
|
}
|
|
6780
|
-
}, [isOpen, task, defaultStatus]);
|
|
6768
|
+
}, [isOpen, task, defaultStatus, defaultMilestone]);
|
|
6781
6769
|
const handleSubmit = async (e) => {
|
|
6782
6770
|
e.preventDefault();
|
|
6783
6771
|
if (!title.trim()) {
|
|
@@ -7154,7 +7142,7 @@ const TaskModal = ({
|
|
|
7154
7142
|
},
|
|
7155
7143
|
children: [
|
|
7156
7144
|
/* @__PURE__ */ jsx("option", { value: "", children: "None" }),
|
|
7157
|
-
availableMilestones.map((m) => /* @__PURE__ */ jsx("option", { value: m, children: m }, m))
|
|
7145
|
+
availableMilestones.map((m) => /* @__PURE__ */ jsx("option", { value: m.id, children: m.title }, m.id))
|
|
7158
7146
|
]
|
|
7159
7147
|
}
|
|
7160
7148
|
)
|
|
@@ -7315,6 +7303,11 @@ function useMilestoneData(options) {
|
|
|
7315
7303
|
try {
|
|
7316
7304
|
const files = fileTreeSlice.data.allFiles;
|
|
7317
7305
|
const filePaths = files.map((f) => f.path);
|
|
7306
|
+
const taskPaths = filePaths.filter((p2) => p2.includes("backlog/tasks/"));
|
|
7307
|
+
console.log(`[useMilestoneData] File paths: ${filePaths.length} total, ${taskPaths.length} task files`);
|
|
7308
|
+
if (taskPaths.length > 0) {
|
|
7309
|
+
console.log(`[useMilestoneData] Sample task paths:`, taskPaths.slice(0, 3));
|
|
7310
|
+
}
|
|
7318
7311
|
const fs = new PanelFileSystemAdapter({
|
|
7319
7312
|
fetchFile: fetchFileContent,
|
|
7320
7313
|
filePaths,
|
|
@@ -7337,6 +7330,11 @@ function useMilestoneData(options) {
|
|
|
7337
7330
|
setCanWrite(fs.canWrite);
|
|
7338
7331
|
await core2.initializeLazy(filePaths);
|
|
7339
7332
|
coreRef.current = core2;
|
|
7333
|
+
const taskIndex = core2.taskIndex;
|
|
7334
|
+
if (taskIndex) {
|
|
7335
|
+
const indexedIds = Array.from(taskIndex.keys());
|
|
7336
|
+
console.log(`[useMilestoneData] Core taskIndex has ${indexedIds.length} tasks:`, indexedIds.slice(0, 5));
|
|
7337
|
+
}
|
|
7340
7338
|
console.log("[useMilestoneData] Core instance:", core2);
|
|
7341
7339
|
console.log("[useMilestoneData] Core.listMilestones:", typeof core2.listMilestones);
|
|
7342
7340
|
console.log("[useMilestoneData] Core prototype:", Object.getPrototypeOf(core2));
|
|
@@ -7350,7 +7348,7 @@ function useMilestoneData(options) {
|
|
|
7350
7348
|
console.log(`[useMilestoneData] Loaded ${milestoneList.length} milestones`);
|
|
7351
7349
|
const allTaskIds = milestoneList.flatMap((m) => m.tasks);
|
|
7352
7350
|
const uniqueTaskIds = [...new Set(allTaskIds)];
|
|
7353
|
-
console.log(`[useMilestoneData]
|
|
7351
|
+
console.log(`[useMilestoneData] Milestone task IDs to load:`, uniqueTaskIds.slice(0, 5), `(${uniqueTaskIds.length} total)`);
|
|
7354
7352
|
let allTasks = [];
|
|
7355
7353
|
if (uniqueTaskIds.length > 0) {
|
|
7356
7354
|
try {
|
|
@@ -7468,326 +7466,6 @@ function useMilestoneData(options) {
|
|
|
7468
7466
|
core: coreRef.current
|
|
7469
7467
|
};
|
|
7470
7468
|
}
|
|
7471
|
-
const MilestoneCard = ({
|
|
7472
|
-
milestoneState,
|
|
7473
|
-
onToggle,
|
|
7474
|
-
onTaskClick
|
|
7475
|
-
}) => {
|
|
7476
|
-
const { theme: theme2 } = useTheme();
|
|
7477
|
-
const { milestone, tasks, isLoading, isExpanded } = milestoneState;
|
|
7478
|
-
const totalTasks = milestone.tasks.length;
|
|
7479
|
-
const doneTasks = tasks.filter(
|
|
7480
|
-
(t) => {
|
|
7481
|
-
var _a, _b;
|
|
7482
|
-
return ((_a = t.status) == null ? void 0 : _a.toLowerCase().includes("done")) || ((_b = t.status) == null ? void 0 : _b.toLowerCase().includes("complete"));
|
|
7483
|
-
}
|
|
7484
|
-
).length;
|
|
7485
|
-
const progress = totalTasks > 0 ? Math.round(doneTasks / totalTasks * 100) : 0;
|
|
7486
|
-
const showProgress = tasks.length > 0 || totalTasks === 0;
|
|
7487
|
-
const getPriorityColor = (priority) => {
|
|
7488
|
-
switch (priority) {
|
|
7489
|
-
case "high":
|
|
7490
|
-
return theme2.colors.error;
|
|
7491
|
-
case "medium":
|
|
7492
|
-
return theme2.colors.warning;
|
|
7493
|
-
case "low":
|
|
7494
|
-
return theme2.colors.info;
|
|
7495
|
-
default:
|
|
7496
|
-
return theme2.colors.border;
|
|
7497
|
-
}
|
|
7498
|
-
};
|
|
7499
|
-
return /* @__PURE__ */ jsxs(
|
|
7500
|
-
"div",
|
|
7501
|
-
{
|
|
7502
|
-
style: {
|
|
7503
|
-
flexShrink: 0,
|
|
7504
|
-
background: theme2.colors.surface,
|
|
7505
|
-
borderRadius: theme2.radii[2],
|
|
7506
|
-
border: `1px solid ${theme2.colors.border}`,
|
|
7507
|
-
overflow: "hidden"
|
|
7508
|
-
},
|
|
7509
|
-
children: [
|
|
7510
|
-
/* @__PURE__ */ jsxs(
|
|
7511
|
-
"div",
|
|
7512
|
-
{
|
|
7513
|
-
onClick: onToggle,
|
|
7514
|
-
style: {
|
|
7515
|
-
padding: "16px",
|
|
7516
|
-
cursor: "pointer",
|
|
7517
|
-
display: "flex",
|
|
7518
|
-
flexDirection: "column",
|
|
7519
|
-
gap: "12px",
|
|
7520
|
-
transition: "background 0.2s ease"
|
|
7521
|
-
},
|
|
7522
|
-
onMouseEnter: (e) => {
|
|
7523
|
-
e.currentTarget.style.background = theme2.colors.backgroundSecondary;
|
|
7524
|
-
},
|
|
7525
|
-
onMouseLeave: (e) => {
|
|
7526
|
-
e.currentTarget.style.background = "transparent";
|
|
7527
|
-
},
|
|
7528
|
-
children: [
|
|
7529
|
-
/* @__PURE__ */ jsxs(
|
|
7530
|
-
"div",
|
|
7531
|
-
{
|
|
7532
|
-
style: {
|
|
7533
|
-
display: "flex",
|
|
7534
|
-
alignItems: "center",
|
|
7535
|
-
justifyContent: "space-between",
|
|
7536
|
-
gap: "12px"
|
|
7537
|
-
},
|
|
7538
|
-
children: [
|
|
7539
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
7540
|
-
isLoading ? /* @__PURE__ */ jsx(
|
|
7541
|
-
LoaderCircle,
|
|
7542
|
-
{
|
|
7543
|
-
size: 16,
|
|
7544
|
-
color: theme2.colors.primary,
|
|
7545
|
-
style: { animation: "spin 1s linear infinite" }
|
|
7546
|
-
}
|
|
7547
|
-
) : isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { size: 16, color: theme2.colors.textSecondary }) : /* @__PURE__ */ jsx(ChevronRight, { size: 16, color: theme2.colors.textSecondary }),
|
|
7548
|
-
/* @__PURE__ */ jsx(
|
|
7549
|
-
"h3",
|
|
7550
|
-
{
|
|
7551
|
-
style: {
|
|
7552
|
-
margin: 0,
|
|
7553
|
-
fontSize: theme2.fontSizes[3],
|
|
7554
|
-
fontWeight: theme2.fontWeights.semibold,
|
|
7555
|
-
color: theme2.colors.text
|
|
7556
|
-
},
|
|
7557
|
-
children: milestone.title
|
|
7558
|
-
}
|
|
7559
|
-
)
|
|
7560
|
-
] }),
|
|
7561
|
-
/* @__PURE__ */ jsxs(
|
|
7562
|
-
"span",
|
|
7563
|
-
{
|
|
7564
|
-
style: {
|
|
7565
|
-
fontSize: theme2.fontSizes[1],
|
|
7566
|
-
color: theme2.colors.textSecondary,
|
|
7567
|
-
background: theme2.colors.backgroundSecondary,
|
|
7568
|
-
padding: "4px 10px",
|
|
7569
|
-
borderRadius: theme2.radii[1],
|
|
7570
|
-
fontWeight: theme2.fontWeights.medium
|
|
7571
|
-
},
|
|
7572
|
-
children: [
|
|
7573
|
-
totalTasks,
|
|
7574
|
-
" task",
|
|
7575
|
-
totalTasks !== 1 ? "s" : "",
|
|
7576
|
-
showProgress && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7577
|
-
" · ",
|
|
7578
|
-
/* @__PURE__ */ jsxs("span", { style: { color: progress === 100 ? theme2.colors.success : theme2.colors.text }, children: [
|
|
7579
|
-
progress,
|
|
7580
|
-
"%"
|
|
7581
|
-
] })
|
|
7582
|
-
] })
|
|
7583
|
-
]
|
|
7584
|
-
}
|
|
7585
|
-
)
|
|
7586
|
-
]
|
|
7587
|
-
}
|
|
7588
|
-
),
|
|
7589
|
-
!isExpanded && milestone.description && /* @__PURE__ */ jsx(
|
|
7590
|
-
"p",
|
|
7591
|
-
{
|
|
7592
|
-
style: {
|
|
7593
|
-
margin: 0,
|
|
7594
|
-
fontSize: theme2.fontSizes[1],
|
|
7595
|
-
color: theme2.colors.textSecondary,
|
|
7596
|
-
overflow: "hidden",
|
|
7597
|
-
textOverflow: "ellipsis",
|
|
7598
|
-
display: "-webkit-box",
|
|
7599
|
-
WebkitLineClamp: 2,
|
|
7600
|
-
WebkitBoxOrient: "vertical",
|
|
7601
|
-
lineHeight: "1.4"
|
|
7602
|
-
},
|
|
7603
|
-
children: milestone.description
|
|
7604
|
-
}
|
|
7605
|
-
)
|
|
7606
|
-
]
|
|
7607
|
-
}
|
|
7608
|
-
),
|
|
7609
|
-
isExpanded && /* @__PURE__ */ jsxs(
|
|
7610
|
-
"div",
|
|
7611
|
-
{
|
|
7612
|
-
style: {
|
|
7613
|
-
borderTop: `1px solid ${theme2.colors.border}`,
|
|
7614
|
-
padding: "16px",
|
|
7615
|
-
display: "flex",
|
|
7616
|
-
flexDirection: "column",
|
|
7617
|
-
gap: "12px"
|
|
7618
|
-
},
|
|
7619
|
-
children: [
|
|
7620
|
-
milestone.description && /* @__PURE__ */ jsx(
|
|
7621
|
-
"p",
|
|
7622
|
-
{
|
|
7623
|
-
style: {
|
|
7624
|
-
margin: 0,
|
|
7625
|
-
fontSize: theme2.fontSizes[1],
|
|
7626
|
-
color: theme2.colors.textSecondary,
|
|
7627
|
-
lineHeight: "1.5"
|
|
7628
|
-
},
|
|
7629
|
-
children: milestone.description
|
|
7630
|
-
}
|
|
7631
|
-
),
|
|
7632
|
-
tasks.length > 0 && /* @__PURE__ */ jsxs(
|
|
7633
|
-
"div",
|
|
7634
|
-
{
|
|
7635
|
-
style: {
|
|
7636
|
-
display: "flex",
|
|
7637
|
-
gap: "12px",
|
|
7638
|
-
flexWrap: "wrap",
|
|
7639
|
-
fontSize: theme2.fontSizes[1]
|
|
7640
|
-
},
|
|
7641
|
-
children: [
|
|
7642
|
-
/* @__PURE__ */ jsxs("span", { style: { color: theme2.colors.success }, children: [
|
|
7643
|
-
doneTasks,
|
|
7644
|
-
" done"
|
|
7645
|
-
] }),
|
|
7646
|
-
/* @__PURE__ */ jsxs("span", { style: { color: theme2.colors.textSecondary }, children: [
|
|
7647
|
-
totalTasks - doneTasks,
|
|
7648
|
-
" remaining"
|
|
7649
|
-
] })
|
|
7650
|
-
]
|
|
7651
|
-
}
|
|
7652
|
-
),
|
|
7653
|
-
isLoading ? /* @__PURE__ */ jsxs(
|
|
7654
|
-
"div",
|
|
7655
|
-
{
|
|
7656
|
-
style: {
|
|
7657
|
-
display: "flex",
|
|
7658
|
-
alignItems: "center",
|
|
7659
|
-
justifyContent: "center",
|
|
7660
|
-
padding: "24px",
|
|
7661
|
-
color: theme2.colors.textSecondary,
|
|
7662
|
-
gap: "8px"
|
|
7663
|
-
},
|
|
7664
|
-
children: [
|
|
7665
|
-
/* @__PURE__ */ jsx(
|
|
7666
|
-
LoaderCircle,
|
|
7667
|
-
{
|
|
7668
|
-
size: 16,
|
|
7669
|
-
style: { animation: "spin 1s linear infinite" }
|
|
7670
|
-
}
|
|
7671
|
-
),
|
|
7672
|
-
"Loading tasks..."
|
|
7673
|
-
]
|
|
7674
|
-
}
|
|
7675
|
-
) : tasks.length > 0 ? /* @__PURE__ */ jsx(
|
|
7676
|
-
"div",
|
|
7677
|
-
{
|
|
7678
|
-
style: {
|
|
7679
|
-
display: "flex",
|
|
7680
|
-
flexDirection: "column",
|
|
7681
|
-
gap: "8px",
|
|
7682
|
-
maxHeight: "300px",
|
|
7683
|
-
overflowY: "auto",
|
|
7684
|
-
paddingRight: "4px"
|
|
7685
|
-
},
|
|
7686
|
-
children: tasks.map((task) => {
|
|
7687
|
-
var _a;
|
|
7688
|
-
return /* @__PURE__ */ jsxs(
|
|
7689
|
-
"div",
|
|
7690
|
-
{
|
|
7691
|
-
onClick: (e) => {
|
|
7692
|
-
e.stopPropagation();
|
|
7693
|
-
onTaskClick == null ? void 0 : onTaskClick(task);
|
|
7694
|
-
},
|
|
7695
|
-
style: {
|
|
7696
|
-
background: theme2.colors.background,
|
|
7697
|
-
borderRadius: theme2.radii[1],
|
|
7698
|
-
padding: "10px 12px",
|
|
7699
|
-
border: `1px solid ${theme2.colors.border}`,
|
|
7700
|
-
borderLeft: `3px solid ${getPriorityColor(task.priority)}`,
|
|
7701
|
-
cursor: onTaskClick ? "pointer" : "default",
|
|
7702
|
-
transition: "all 0.2s ease",
|
|
7703
|
-
display: "flex",
|
|
7704
|
-
alignItems: "center",
|
|
7705
|
-
justifyContent: "space-between",
|
|
7706
|
-
gap: "12px"
|
|
7707
|
-
},
|
|
7708
|
-
onMouseEnter: (e) => {
|
|
7709
|
-
if (onTaskClick) {
|
|
7710
|
-
e.currentTarget.style.background = theme2.colors.backgroundSecondary;
|
|
7711
|
-
}
|
|
7712
|
-
},
|
|
7713
|
-
onMouseLeave: (e) => {
|
|
7714
|
-
e.currentTarget.style.background = theme2.colors.background;
|
|
7715
|
-
},
|
|
7716
|
-
children: [
|
|
7717
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", flex: 1, minWidth: 0 }, children: [
|
|
7718
|
-
/* @__PURE__ */ jsxs(
|
|
7719
|
-
"span",
|
|
7720
|
-
{
|
|
7721
|
-
style: {
|
|
7722
|
-
fontFamily: theme2.fonts.monospace,
|
|
7723
|
-
fontSize: theme2.fontSizes[0],
|
|
7724
|
-
color: theme2.colors.textMuted,
|
|
7725
|
-
flexShrink: 0
|
|
7726
|
-
},
|
|
7727
|
-
children: [
|
|
7728
|
-
"#",
|
|
7729
|
-
task.id
|
|
7730
|
-
]
|
|
7731
|
-
}
|
|
7732
|
-
),
|
|
7733
|
-
/* @__PURE__ */ jsx(
|
|
7734
|
-
"span",
|
|
7735
|
-
{
|
|
7736
|
-
style: {
|
|
7737
|
-
fontSize: theme2.fontSizes[1],
|
|
7738
|
-
color: theme2.colors.text,
|
|
7739
|
-
overflow: "hidden",
|
|
7740
|
-
textOverflow: "ellipsis",
|
|
7741
|
-
whiteSpace: "nowrap"
|
|
7742
|
-
},
|
|
7743
|
-
children: task.title
|
|
7744
|
-
}
|
|
7745
|
-
)
|
|
7746
|
-
] }),
|
|
7747
|
-
/* @__PURE__ */ jsx(
|
|
7748
|
-
"span",
|
|
7749
|
-
{
|
|
7750
|
-
style: {
|
|
7751
|
-
fontSize: theme2.fontSizes[0],
|
|
7752
|
-
color: ((_a = task.status) == null ? void 0 : _a.toLowerCase().includes("done")) ? theme2.colors.success : theme2.colors.textSecondary,
|
|
7753
|
-
background: theme2.colors.backgroundSecondary,
|
|
7754
|
-
padding: "2px 8px",
|
|
7755
|
-
borderRadius: theme2.radii[1],
|
|
7756
|
-
flexShrink: 0
|
|
7757
|
-
},
|
|
7758
|
-
children: task.status
|
|
7759
|
-
}
|
|
7760
|
-
)
|
|
7761
|
-
]
|
|
7762
|
-
},
|
|
7763
|
-
task.id
|
|
7764
|
-
);
|
|
7765
|
-
})
|
|
7766
|
-
}
|
|
7767
|
-
) : totalTasks === 0 ? /* @__PURE__ */ jsx(
|
|
7768
|
-
"div",
|
|
7769
|
-
{
|
|
7770
|
-
style: {
|
|
7771
|
-
padding: "16px",
|
|
7772
|
-
textAlign: "center",
|
|
7773
|
-
color: theme2.colors.textMuted,
|
|
7774
|
-
fontSize: theme2.fontSizes[1]
|
|
7775
|
-
},
|
|
7776
|
-
children: "No tasks in this milestone"
|
|
7777
|
-
}
|
|
7778
|
-
) : null
|
|
7779
|
-
]
|
|
7780
|
-
}
|
|
7781
|
-
),
|
|
7782
|
-
/* @__PURE__ */ jsx("style", { children: `
|
|
7783
|
-
@keyframes spin {
|
|
7784
|
-
to { transform: rotate(360deg); }
|
|
7785
|
-
}
|
|
7786
|
-
` })
|
|
7787
|
-
]
|
|
7788
|
-
}
|
|
7789
|
-
);
|
|
7790
|
-
};
|
|
7791
7469
|
const MilestoneModal = ({
|
|
7792
7470
|
isOpen,
|
|
7793
7471
|
onClose,
|
|
@@ -8096,7 +7774,7 @@ const KanbanPanel = ({
|
|
|
8096
7774
|
}) => {
|
|
8097
7775
|
var _a, _b;
|
|
8098
7776
|
const { theme: theme2 } = useTheme();
|
|
8099
|
-
const [
|
|
7777
|
+
const [selectedTaskId, setSelectedTaskId] = useState(null);
|
|
8100
7778
|
const [selectedTab, setSelectedTab] = useState("todo");
|
|
8101
7779
|
const [isNarrowView, setIsNarrowView] = useState(false);
|
|
8102
7780
|
const containerRef = useRef(null);
|
|
@@ -8107,6 +7785,8 @@ const KanbanPanel = ({
|
|
|
8107
7785
|
const [isMilestoneModalOpen, setIsMilestoneModalOpen] = useState(false);
|
|
8108
7786
|
const [editingMilestone, setEditingMilestone] = useState(void 0);
|
|
8109
7787
|
const [isRefreshingMilestones, setIsRefreshingMilestones] = useState(false);
|
|
7788
|
+
const [selectedMilestoneId, setSelectedMilestoneId] = useState(null);
|
|
7789
|
+
const [milestoneStatusFilter, setMilestoneStatusFilter] = useState(null);
|
|
8110
7790
|
const [searchQuery, setSearchQuery] = useState("");
|
|
8111
7791
|
const sensors = useSensors(
|
|
8112
7792
|
useSensor(PointerSensor, {
|
|
@@ -8132,6 +7812,16 @@ const KanbanPanel = ({
|
|
|
8132
7812
|
observer.observe(container);
|
|
8133
7813
|
return () => observer.disconnect();
|
|
8134
7814
|
}, []);
|
|
7815
|
+
useEffect(() => {
|
|
7816
|
+
if (!events2) return;
|
|
7817
|
+
const unsubscribe = events2.on("task:selected", (event) => {
|
|
7818
|
+
const payload = event.payload;
|
|
7819
|
+
if (payload == null ? void 0 : payload.taskId) {
|
|
7820
|
+
setSelectedTaskId(payload.taskId);
|
|
7821
|
+
}
|
|
7822
|
+
});
|
|
7823
|
+
return unsubscribe;
|
|
7824
|
+
}, [events2]);
|
|
8135
7825
|
const {
|
|
8136
7826
|
statusColumns,
|
|
8137
7827
|
tasksByStatus,
|
|
@@ -8153,7 +7843,6 @@ const KanbanPanel = ({
|
|
|
8153
7843
|
milestones,
|
|
8154
7844
|
isLoading: isMilestonesLoading,
|
|
8155
7845
|
error: milestonesError,
|
|
8156
|
-
toggleMilestone,
|
|
8157
7846
|
refreshData: refreshMilestones,
|
|
8158
7847
|
canWrite: canWriteMilestones,
|
|
8159
7848
|
core: milestoneCore
|
|
@@ -8207,7 +7896,7 @@ const KanbanPanel = ({
|
|
|
8207
7896
|
}
|
|
8208
7897
|
}, [getTaskById, moveTaskOptimistic]);
|
|
8209
7898
|
const handleTaskClick = (task) => {
|
|
8210
|
-
|
|
7899
|
+
setSelectedTaskId(task.id);
|
|
8211
7900
|
if (events2) {
|
|
8212
7901
|
events2.emit({
|
|
8213
7902
|
type: "task:selected",
|
|
@@ -8328,7 +8017,7 @@ const KanbanPanel = ({
|
|
|
8328
8017
|
}
|
|
8329
8018
|
};
|
|
8330
8019
|
const handleMilestoneTaskClick = (task) => {
|
|
8331
|
-
|
|
8020
|
+
setSelectedTaskId(task.id);
|
|
8332
8021
|
if (events2) {
|
|
8333
8022
|
events2.emit({
|
|
8334
8023
|
type: "task:selected",
|
|
@@ -8374,7 +8063,6 @@ const KanbanPanel = ({
|
|
|
8374
8063
|
},
|
|
8375
8064
|
children: [
|
|
8376
8065
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
|
|
8377
|
-
/* @__PURE__ */ jsx(Kanban, { size: 24, color: theme2.colors.primary }),
|
|
8378
8066
|
/* @__PURE__ */ jsx(
|
|
8379
8067
|
"h2",
|
|
8380
8068
|
{
|
|
@@ -8383,7 +8071,21 @@ const KanbanPanel = ({
|
|
|
8383
8071
|
fontSize: theme2.fontSizes[4],
|
|
8384
8072
|
color: theme2.colors.text
|
|
8385
8073
|
},
|
|
8386
|
-
children:
|
|
8074
|
+
children: /* @__PURE__ */ jsx(
|
|
8075
|
+
"a",
|
|
8076
|
+
{
|
|
8077
|
+
href: "https://github.com/MrLesk/Backlog.md",
|
|
8078
|
+
target: "_blank",
|
|
8079
|
+
rel: "noopener noreferrer",
|
|
8080
|
+
style: {
|
|
8081
|
+
color: "inherit",
|
|
8082
|
+
textDecoration: "none"
|
|
8083
|
+
},
|
|
8084
|
+
onMouseEnter: (e) => e.currentTarget.style.textDecoration = "underline",
|
|
8085
|
+
onMouseLeave: (e) => e.currentTarget.style.textDecoration = "none",
|
|
8086
|
+
children: "Backlog.md"
|
|
8087
|
+
}
|
|
8088
|
+
)
|
|
8387
8089
|
}
|
|
8388
8090
|
),
|
|
8389
8091
|
isBacklogProject && /* @__PURE__ */ jsxs(
|
|
@@ -8559,6 +8261,33 @@ const KanbanPanel = ({
|
|
|
8559
8261
|
}
|
|
8560
8262
|
)
|
|
8561
8263
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8264
|
+
canWrite && /* @__PURE__ */ jsxs(
|
|
8265
|
+
"button",
|
|
8266
|
+
{
|
|
8267
|
+
onClick: handleOpenNewTask,
|
|
8268
|
+
disabled: !selectedMilestoneId,
|
|
8269
|
+
title: selectedMilestoneId ? "Add task to milestone" : "Select a milestone first",
|
|
8270
|
+
style: {
|
|
8271
|
+
display: "flex",
|
|
8272
|
+
alignItems: "center",
|
|
8273
|
+
gap: "6px",
|
|
8274
|
+
background: selectedMilestoneId ? theme2.colors.primary : theme2.colors.backgroundSecondary,
|
|
8275
|
+
color: selectedMilestoneId ? theme2.colors.textOnPrimary : theme2.colors.textMuted,
|
|
8276
|
+
border: selectedMilestoneId ? "none" : `1px solid ${theme2.colors.border}`,
|
|
8277
|
+
borderRadius: theme2.radii[2],
|
|
8278
|
+
padding: "6px 12px",
|
|
8279
|
+
fontSize: theme2.fontSizes[1],
|
|
8280
|
+
fontWeight: theme2.fontWeights.medium,
|
|
8281
|
+
cursor: selectedMilestoneId ? "pointer" : "not-allowed",
|
|
8282
|
+
opacity: selectedMilestoneId ? 1 : 0.6,
|
|
8283
|
+
transition: "all 0.2s ease"
|
|
8284
|
+
},
|
|
8285
|
+
children: [
|
|
8286
|
+
/* @__PURE__ */ jsx(Plus, { size: 14 }),
|
|
8287
|
+
"Add Task"
|
|
8288
|
+
]
|
|
8289
|
+
}
|
|
8290
|
+
),
|
|
8562
8291
|
canWriteMilestones && /* @__PURE__ */ jsxs(
|
|
8563
8292
|
"button",
|
|
8564
8293
|
{
|
|
@@ -8752,7 +8481,8 @@ const KanbanPanel = ({
|
|
|
8752
8481
|
status: STATUS_DISPLAY_LABELS[status],
|
|
8753
8482
|
tasks: columnTasks,
|
|
8754
8483
|
onTaskClick: handleTaskClick,
|
|
8755
|
-
fullWidth: isNarrowView
|
|
8484
|
+
fullWidth: isNarrowView,
|
|
8485
|
+
selectedTaskId
|
|
8756
8486
|
},
|
|
8757
8487
|
status
|
|
8758
8488
|
);
|
|
@@ -8780,14 +8510,14 @@ const KanbanPanel = ({
|
|
|
8780
8510
|
]
|
|
8781
8511
|
}
|
|
8782
8512
|
) : (
|
|
8783
|
-
/* Milestones View */
|
|
8513
|
+
/* Milestones View - Two Column Layout */
|
|
8784
8514
|
/* @__PURE__ */ jsx(
|
|
8785
8515
|
"div",
|
|
8786
8516
|
{
|
|
8787
8517
|
style: {
|
|
8788
8518
|
flex: 1,
|
|
8789
8519
|
display: "flex",
|
|
8790
|
-
|
|
8520
|
+
gap: "16px",
|
|
8791
8521
|
overflow: "hidden"
|
|
8792
8522
|
},
|
|
8793
8523
|
children: isMilestonesLoading ? /* @__PURE__ */ jsx(
|
|
@@ -8822,30 +8552,352 @@ const KanbanPanel = ({
|
|
|
8822
8552
|
] })
|
|
8823
8553
|
]
|
|
8824
8554
|
}
|
|
8825
|
-
) : /* @__PURE__ */
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
paddingRight: "4px",
|
|
8836
|
-
marginRight: "-4px"
|
|
8837
|
-
},
|
|
8838
|
-
children: milestones.map((milestoneState) => /* @__PURE__ */ jsx(
|
|
8839
|
-
MilestoneCard,
|
|
8840
|
-
{
|
|
8841
|
-
milestoneState,
|
|
8842
|
-
onToggle: () => toggleMilestone(milestoneState.milestone.id),
|
|
8843
|
-
onTaskClick: handleMilestoneTaskClick
|
|
8555
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8556
|
+
/* @__PURE__ */ jsx(
|
|
8557
|
+
"div",
|
|
8558
|
+
{
|
|
8559
|
+
style: {
|
|
8560
|
+
flex: 1,
|
|
8561
|
+
minWidth: 0,
|
|
8562
|
+
display: "flex",
|
|
8563
|
+
flexDirection: "column",
|
|
8564
|
+
overflow: "hidden"
|
|
8844
8565
|
},
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8566
|
+
children: /* @__PURE__ */ jsx(
|
|
8567
|
+
"div",
|
|
8568
|
+
{
|
|
8569
|
+
style: {
|
|
8570
|
+
flex: 1,
|
|
8571
|
+
overflowY: "auto",
|
|
8572
|
+
display: "flex",
|
|
8573
|
+
flexDirection: "column",
|
|
8574
|
+
gap: "8px",
|
|
8575
|
+
paddingRight: "4px"
|
|
8576
|
+
},
|
|
8577
|
+
children: milestones.map((milestoneState) => {
|
|
8578
|
+
const isSelected = selectedMilestoneId === milestoneState.milestone.id;
|
|
8579
|
+
const totalTasks = milestoneState.milestone.tasks.length;
|
|
8580
|
+
const doneTasks = milestoneState.tasks.filter(
|
|
8581
|
+
(t) => {
|
|
8582
|
+
var _a2, _b2;
|
|
8583
|
+
return ((_a2 = t.status) == null ? void 0 : _a2.toLowerCase().includes("done")) || ((_b2 = t.status) == null ? void 0 : _b2.toLowerCase().includes("complete"));
|
|
8584
|
+
}
|
|
8585
|
+
).length;
|
|
8586
|
+
const progress = totalTasks > 0 ? Math.round(doneTasks / totalTasks * 100) : 0;
|
|
8587
|
+
const showProgress = milestoneState.tasks.length > 0 || totalTasks === 0;
|
|
8588
|
+
return /* @__PURE__ */ jsxs(
|
|
8589
|
+
"div",
|
|
8590
|
+
{
|
|
8591
|
+
onClick: () => {
|
|
8592
|
+
setSelectedMilestoneId(milestoneState.milestone.id);
|
|
8593
|
+
setMilestoneStatusFilter(null);
|
|
8594
|
+
},
|
|
8595
|
+
style: {
|
|
8596
|
+
padding: "12px 16px",
|
|
8597
|
+
background: isSelected ? theme2.colors.primary + "15" : theme2.colors.surface,
|
|
8598
|
+
border: `1px solid ${isSelected ? theme2.colors.primary : theme2.colors.border}`,
|
|
8599
|
+
borderRadius: theme2.radii[2],
|
|
8600
|
+
cursor: "pointer",
|
|
8601
|
+
transition: "all 0.2s ease"
|
|
8602
|
+
},
|
|
8603
|
+
children: [
|
|
8604
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "12px" }, children: [
|
|
8605
|
+
/* @__PURE__ */ jsx(
|
|
8606
|
+
"h3",
|
|
8607
|
+
{
|
|
8608
|
+
style: {
|
|
8609
|
+
margin: 0,
|
|
8610
|
+
fontSize: theme2.fontSizes[2],
|
|
8611
|
+
fontWeight: theme2.fontWeights.semibold,
|
|
8612
|
+
color: theme2.colors.text,
|
|
8613
|
+
overflow: "hidden",
|
|
8614
|
+
textOverflow: "ellipsis",
|
|
8615
|
+
whiteSpace: "nowrap"
|
|
8616
|
+
},
|
|
8617
|
+
children: milestoneState.milestone.title
|
|
8618
|
+
}
|
|
8619
|
+
),
|
|
8620
|
+
/* @__PURE__ */ jsxs(
|
|
8621
|
+
"span",
|
|
8622
|
+
{
|
|
8623
|
+
style: {
|
|
8624
|
+
fontSize: theme2.fontSizes[1],
|
|
8625
|
+
color: theme2.colors.textSecondary,
|
|
8626
|
+
background: theme2.colors.backgroundSecondary,
|
|
8627
|
+
padding: "2px 8px",
|
|
8628
|
+
borderRadius: theme2.radii[1],
|
|
8629
|
+
flexShrink: 0
|
|
8630
|
+
},
|
|
8631
|
+
children: [
|
|
8632
|
+
totalTasks,
|
|
8633
|
+
" task",
|
|
8634
|
+
totalTasks !== 1 ? "s" : "",
|
|
8635
|
+
showProgress && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8636
|
+
" · ",
|
|
8637
|
+
/* @__PURE__ */ jsxs("span", { style: { color: progress === 100 ? theme2.colors.success : theme2.colors.text }, children: [
|
|
8638
|
+
progress,
|
|
8639
|
+
"%"
|
|
8640
|
+
] })
|
|
8641
|
+
] })
|
|
8642
|
+
]
|
|
8643
|
+
}
|
|
8644
|
+
)
|
|
8645
|
+
] }),
|
|
8646
|
+
isSelected && milestoneState.milestone.description && /* @__PURE__ */ jsx(
|
|
8647
|
+
"p",
|
|
8648
|
+
{
|
|
8649
|
+
style: {
|
|
8650
|
+
margin: "8px 0 0 0",
|
|
8651
|
+
fontSize: theme2.fontSizes[1],
|
|
8652
|
+
color: theme2.colors.textSecondary,
|
|
8653
|
+
lineHeight: "1.4"
|
|
8654
|
+
},
|
|
8655
|
+
children: milestoneState.milestone.description
|
|
8656
|
+
}
|
|
8657
|
+
)
|
|
8658
|
+
]
|
|
8659
|
+
},
|
|
8660
|
+
milestoneState.milestone.id
|
|
8661
|
+
);
|
|
8662
|
+
})
|
|
8663
|
+
}
|
|
8664
|
+
)
|
|
8665
|
+
}
|
|
8666
|
+
),
|
|
8667
|
+
/* @__PURE__ */ jsx(
|
|
8668
|
+
"div",
|
|
8669
|
+
{
|
|
8670
|
+
style: {
|
|
8671
|
+
flex: 1,
|
|
8672
|
+
minWidth: 0,
|
|
8673
|
+
display: "flex",
|
|
8674
|
+
flexDirection: "column",
|
|
8675
|
+
background: theme2.colors.surface,
|
|
8676
|
+
borderRadius: theme2.radii[2],
|
|
8677
|
+
border: `1px solid ${theme2.colors.border}`,
|
|
8678
|
+
overflow: "hidden"
|
|
8679
|
+
},
|
|
8680
|
+
children: (() => {
|
|
8681
|
+
const selectedMilestone = milestones.find((m) => m.milestone.id === selectedMilestoneId);
|
|
8682
|
+
if (!selectedMilestone) {
|
|
8683
|
+
return /* @__PURE__ */ jsxs(
|
|
8684
|
+
"div",
|
|
8685
|
+
{
|
|
8686
|
+
style: {
|
|
8687
|
+
flex: 1,
|
|
8688
|
+
display: "flex",
|
|
8689
|
+
flexDirection: "column",
|
|
8690
|
+
alignItems: "center",
|
|
8691
|
+
justifyContent: "center",
|
|
8692
|
+
gap: "8px",
|
|
8693
|
+
color: theme2.colors.textMuted,
|
|
8694
|
+
padding: "24px"
|
|
8695
|
+
},
|
|
8696
|
+
children: [
|
|
8697
|
+
/* @__PURE__ */ jsx(Milestone, { size: 32, color: theme2.colors.border }),
|
|
8698
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: theme2.fontSizes[1] }, children: "Select a milestone to view tasks" })
|
|
8699
|
+
]
|
|
8700
|
+
}
|
|
8701
|
+
);
|
|
8702
|
+
}
|
|
8703
|
+
const tasks = selectedMilestone.tasks;
|
|
8704
|
+
const getPriorityColor = (priority) => {
|
|
8705
|
+
switch (priority) {
|
|
8706
|
+
case "high":
|
|
8707
|
+
return theme2.colors.error;
|
|
8708
|
+
case "medium":
|
|
8709
|
+
return theme2.colors.warning;
|
|
8710
|
+
case "low":
|
|
8711
|
+
return theme2.colors.info;
|
|
8712
|
+
default:
|
|
8713
|
+
return theme2.colors.border;
|
|
8714
|
+
}
|
|
8715
|
+
};
|
|
8716
|
+
const todoCount = tasks.filter((t) => t.status === "To Do").length;
|
|
8717
|
+
const inProgressCount = tasks.filter((t) => t.status === "In Progress").length;
|
|
8718
|
+
const doneCount = tasks.filter(
|
|
8719
|
+
(t) => {
|
|
8720
|
+
var _a2, _b2;
|
|
8721
|
+
return ((_a2 = t.status) == null ? void 0 : _a2.toLowerCase().includes("done")) || ((_b2 = t.status) == null ? void 0 : _b2.toLowerCase().includes("complete"));
|
|
8722
|
+
}
|
|
8723
|
+
).length;
|
|
8724
|
+
const filteredTasks = milestoneStatusFilter ? tasks.filter((t) => {
|
|
8725
|
+
var _a2, _b2;
|
|
8726
|
+
if (milestoneStatusFilter === "Done") {
|
|
8727
|
+
return ((_a2 = t.status) == null ? void 0 : _a2.toLowerCase().includes("done")) || ((_b2 = t.status) == null ? void 0 : _b2.toLowerCase().includes("complete"));
|
|
8728
|
+
}
|
|
8729
|
+
return t.status === milestoneStatusFilter;
|
|
8730
|
+
}) : tasks;
|
|
8731
|
+
const getFilterButtonStyle = (status, count, color2) => {
|
|
8732
|
+
const isActive = milestoneStatusFilter === status;
|
|
8733
|
+
return {
|
|
8734
|
+
flex: 1,
|
|
8735
|
+
padding: "8px 12px",
|
|
8736
|
+
border: "none",
|
|
8737
|
+
borderBottom: isActive ? `2px solid ${color2}` : "2px solid transparent",
|
|
8738
|
+
background: isActive ? `${color2}15` : "transparent",
|
|
8739
|
+
color: isActive ? color2 : theme2.colors.textSecondary,
|
|
8740
|
+
fontSize: theme2.fontSizes[1],
|
|
8741
|
+
fontWeight: isActive ? theme2.fontWeights.medium : theme2.fontWeights.body,
|
|
8742
|
+
cursor: count > 0 ? "pointer" : "default",
|
|
8743
|
+
transition: "all 0.2s ease",
|
|
8744
|
+
textAlign: "center",
|
|
8745
|
+
opacity: count === 0 ? 0.5 : 1
|
|
8746
|
+
};
|
|
8747
|
+
};
|
|
8748
|
+
const handleFilterClick = (status, count) => {
|
|
8749
|
+
if (count === 0) return;
|
|
8750
|
+
setMilestoneStatusFilter(milestoneStatusFilter === status ? null : status);
|
|
8751
|
+
};
|
|
8752
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8753
|
+
/* @__PURE__ */ jsxs(
|
|
8754
|
+
"div",
|
|
8755
|
+
{
|
|
8756
|
+
style: {
|
|
8757
|
+
borderBottom: `1px solid ${theme2.colors.border}`,
|
|
8758
|
+
background: theme2.colors.backgroundSecondary,
|
|
8759
|
+
display: "flex"
|
|
8760
|
+
},
|
|
8761
|
+
children: [
|
|
8762
|
+
/* @__PURE__ */ jsxs(
|
|
8763
|
+
"button",
|
|
8764
|
+
{
|
|
8765
|
+
onClick: () => handleFilterClick("To Do", todoCount),
|
|
8766
|
+
style: getFilterButtonStyle("To Do", todoCount, theme2.colors.textSecondary),
|
|
8767
|
+
children: [
|
|
8768
|
+
todoCount,
|
|
8769
|
+
" To Do"
|
|
8770
|
+
]
|
|
8771
|
+
}
|
|
8772
|
+
),
|
|
8773
|
+
/* @__PURE__ */ jsxs(
|
|
8774
|
+
"button",
|
|
8775
|
+
{
|
|
8776
|
+
onClick: () => handleFilterClick("In Progress", inProgressCount),
|
|
8777
|
+
style: getFilterButtonStyle("In Progress", inProgressCount, theme2.colors.warning),
|
|
8778
|
+
children: [
|
|
8779
|
+
inProgressCount,
|
|
8780
|
+
" In Progress"
|
|
8781
|
+
]
|
|
8782
|
+
}
|
|
8783
|
+
),
|
|
8784
|
+
/* @__PURE__ */ jsxs(
|
|
8785
|
+
"button",
|
|
8786
|
+
{
|
|
8787
|
+
onClick: () => handleFilterClick("Done", doneCount),
|
|
8788
|
+
style: getFilterButtonStyle("Done", doneCount, theme2.colors.success),
|
|
8789
|
+
children: [
|
|
8790
|
+
doneCount,
|
|
8791
|
+
" Done"
|
|
8792
|
+
]
|
|
8793
|
+
}
|
|
8794
|
+
)
|
|
8795
|
+
]
|
|
8796
|
+
}
|
|
8797
|
+
),
|
|
8798
|
+
/* @__PURE__ */ jsx(
|
|
8799
|
+
"div",
|
|
8800
|
+
{
|
|
8801
|
+
style: {
|
|
8802
|
+
flex: 1,
|
|
8803
|
+
overflowY: "auto",
|
|
8804
|
+
padding: "12px",
|
|
8805
|
+
display: "flex",
|
|
8806
|
+
flexDirection: "column",
|
|
8807
|
+
gap: "8px"
|
|
8808
|
+
},
|
|
8809
|
+
children: filteredTasks.length === 0 ? /* @__PURE__ */ jsx(
|
|
8810
|
+
"div",
|
|
8811
|
+
{
|
|
8812
|
+
style: {
|
|
8813
|
+
flex: 1,
|
|
8814
|
+
display: "flex",
|
|
8815
|
+
alignItems: "center",
|
|
8816
|
+
justifyContent: "center",
|
|
8817
|
+
color: theme2.colors.textMuted,
|
|
8818
|
+
fontSize: theme2.fontSizes[1]
|
|
8819
|
+
},
|
|
8820
|
+
children: milestoneStatusFilter ? `No ${milestoneStatusFilter.toLowerCase()} tasks` : "No tasks in this milestone"
|
|
8821
|
+
}
|
|
8822
|
+
) : filteredTasks.map((task) => {
|
|
8823
|
+
var _a2;
|
|
8824
|
+
return /* @__PURE__ */ jsxs(
|
|
8825
|
+
"div",
|
|
8826
|
+
{
|
|
8827
|
+
onClick: () => handleMilestoneTaskClick(task),
|
|
8828
|
+
style: {
|
|
8829
|
+
padding: "10px 12px",
|
|
8830
|
+
background: selectedTaskId === task.id ? `${theme2.colors.primary}10` : theme2.colors.background,
|
|
8831
|
+
border: `1px solid ${selectedTaskId === task.id ? theme2.colors.primary : theme2.colors.border}`,
|
|
8832
|
+
borderLeft: `3px solid ${getPriorityColor(task.priority)}`,
|
|
8833
|
+
borderRadius: theme2.radii[1],
|
|
8834
|
+
cursor: "pointer",
|
|
8835
|
+
transition: "all 0.2s ease",
|
|
8836
|
+
display: "flex",
|
|
8837
|
+
alignItems: "center",
|
|
8838
|
+
justifyContent: "space-between",
|
|
8839
|
+
gap: "12px",
|
|
8840
|
+
...selectedTaskId === task.id && {
|
|
8841
|
+
boxShadow: `0 0 0 1px ${theme2.colors.primary}`
|
|
8842
|
+
}
|
|
8843
|
+
},
|
|
8844
|
+
children: [
|
|
8845
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", flex: 1, minWidth: 0 }, children: [
|
|
8846
|
+
/* @__PURE__ */ jsxs(
|
|
8847
|
+
"span",
|
|
8848
|
+
{
|
|
8849
|
+
style: {
|
|
8850
|
+
fontFamily: theme2.fonts.monospace,
|
|
8851
|
+
fontSize: theme2.fontSizes[0],
|
|
8852
|
+
color: theme2.colors.textMuted,
|
|
8853
|
+
flexShrink: 0
|
|
8854
|
+
},
|
|
8855
|
+
children: [
|
|
8856
|
+
"#",
|
|
8857
|
+
task.id
|
|
8858
|
+
]
|
|
8859
|
+
}
|
|
8860
|
+
),
|
|
8861
|
+
/* @__PURE__ */ jsx(
|
|
8862
|
+
"span",
|
|
8863
|
+
{
|
|
8864
|
+
style: {
|
|
8865
|
+
fontSize: theme2.fontSizes[1],
|
|
8866
|
+
color: theme2.colors.text,
|
|
8867
|
+
overflow: "hidden",
|
|
8868
|
+
textOverflow: "ellipsis",
|
|
8869
|
+
whiteSpace: "nowrap"
|
|
8870
|
+
},
|
|
8871
|
+
children: task.title
|
|
8872
|
+
}
|
|
8873
|
+
)
|
|
8874
|
+
] }),
|
|
8875
|
+
/* @__PURE__ */ jsx(
|
|
8876
|
+
"span",
|
|
8877
|
+
{
|
|
8878
|
+
style: {
|
|
8879
|
+
fontSize: theme2.fontSizes[0],
|
|
8880
|
+
color: ((_a2 = task.status) == null ? void 0 : _a2.toLowerCase().includes("done")) ? theme2.colors.success : theme2.colors.textSecondary,
|
|
8881
|
+
background: theme2.colors.backgroundSecondary,
|
|
8882
|
+
padding: "2px 8px",
|
|
8883
|
+
borderRadius: theme2.radii[1],
|
|
8884
|
+
flexShrink: 0
|
|
8885
|
+
},
|
|
8886
|
+
children: task.status
|
|
8887
|
+
}
|
|
8888
|
+
)
|
|
8889
|
+
]
|
|
8890
|
+
},
|
|
8891
|
+
task.id
|
|
8892
|
+
);
|
|
8893
|
+
})
|
|
8894
|
+
}
|
|
8895
|
+
)
|
|
8896
|
+
] });
|
|
8897
|
+
})()
|
|
8898
|
+
}
|
|
8899
|
+
)
|
|
8900
|
+
] })
|
|
8849
8901
|
}
|
|
8850
8902
|
)
|
|
8851
8903
|
),
|
|
@@ -8857,7 +8909,9 @@ const KanbanPanel = ({
|
|
|
8857
8909
|
onSave: handleSaveTask,
|
|
8858
8910
|
task: editingTask,
|
|
8859
8911
|
defaultStatus: "To Do",
|
|
8860
|
-
|
|
8912
|
+
defaultMilestone: viewMode === "milestones" ? selectedMilestoneId || "" : "",
|
|
8913
|
+
availableStatuses,
|
|
8914
|
+
availableMilestones: milestones.map((m) => ({ id: m.milestone.id, title: m.milestone.title }))
|
|
8861
8915
|
}
|
|
8862
8916
|
),
|
|
8863
8917
|
/* @__PURE__ */ jsx(
|