@industry-theme/backlogmd-kanban-panel 1.0.38 → 1.0.39

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":"TaskCard.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/components/TaskCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAe7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAyO5C,CAAC"}
1
+ {"version":3,"file":"TaskCard.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/components/TaskCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAgB7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAgS5C,CAAC"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Task } from '@backlog-md/core';
3
+ export interface TaskContextMenuProps {
4
+ task: Task;
5
+ position: {
6
+ x: number;
7
+ y: number;
8
+ };
9
+ onClose: () => void;
10
+ onCopyPath: (task: Task) => void;
11
+ }
12
+ export declare const TaskContextMenu: React.FC<TaskContextMenuProps>;
13
+ //# sourceMappingURL=TaskContextMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskContextMenu.d.ts","sourceRoot":"","sources":["../../../../src/panels/kanban/components/TaskContextMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4E1D,CAAC"}
@@ -8274,6 +8274,73 @@ function useKanbanData(options) {
8274
8274
  core: coreRef.current
8275
8275
  };
8276
8276
  }
8277
+ const TaskContextMenu = ({
8278
+ task,
8279
+ position: position2,
8280
+ onClose,
8281
+ onCopyPath
8282
+ }) => {
8283
+ const menuRef = useRef(null);
8284
+ useEffect(() => {
8285
+ const handleClickOutside = (e) => {
8286
+ if (menuRef.current && !menuRef.current.contains(e.target)) {
8287
+ onClose();
8288
+ }
8289
+ };
8290
+ const handleEscape = (e) => {
8291
+ if (e.key === "Escape") {
8292
+ onClose();
8293
+ }
8294
+ };
8295
+ document.addEventListener("mousedown", handleClickOutside);
8296
+ document.addEventListener("keydown", handleEscape);
8297
+ return () => {
8298
+ document.removeEventListener("mousedown", handleClickOutside);
8299
+ document.removeEventListener("keydown", handleEscape);
8300
+ };
8301
+ }, [onClose]);
8302
+ const handleCopyPath = () => {
8303
+ onCopyPath(task);
8304
+ onClose();
8305
+ };
8306
+ const menuStyle = {
8307
+ position: "fixed",
8308
+ top: position2.y,
8309
+ left: position2.x,
8310
+ backgroundColor: "#ffffff",
8311
+ border: "1px solid #e0e0e0",
8312
+ borderRadius: "4px",
8313
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
8314
+ padding: "4px 0",
8315
+ minWidth: "180px",
8316
+ zIndex: 1e4
8317
+ };
8318
+ const menuItemStyle = {
8319
+ padding: "8px 16px",
8320
+ cursor: "pointer",
8321
+ fontSize: "14px",
8322
+ color: "#333",
8323
+ transition: "background-color 0.15s ease"
8324
+ };
8325
+ const menuItemHoverStyle = {
8326
+ ...menuItemStyle,
8327
+ backgroundColor: "#f5f5f5"
8328
+ };
8329
+ const [isHovering, setIsHovering] = React2__default.useState(false);
8330
+ return createPortal(
8331
+ /* @__PURE__ */ jsx("div", { ref: menuRef, style: menuStyle, children: /* @__PURE__ */ jsx(
8332
+ "div",
8333
+ {
8334
+ style: isHovering ? menuItemHoverStyle : menuItemStyle,
8335
+ onMouseEnter: () => setIsHovering(true),
8336
+ onMouseLeave: () => setIsHovering(false),
8337
+ onClick: handleCopyPath,
8338
+ children: "Copy Task Path"
8339
+ }
8340
+ ) }),
8341
+ document.body
8342
+ );
8343
+ };
8277
8344
  function getGitHubIssueFromRefs$1(references) {
8278
8345
  if (!references) return null;
8279
8346
  for (const ref of references) {
@@ -8291,6 +8358,8 @@ const TaskCard = ({
8291
8358
  isSelected = false
8292
8359
  }) => {
8293
8360
  const { theme: theme2 } = useTheme();
8361
+ const [contextMenuPosition, setContextMenuPosition] = useState(null);
8362
+ const [copyFeedback, setCopyFeedback] = useState(false);
8294
8363
  const {
8295
8364
  attributes,
8296
8365
  listeners,
@@ -8341,178 +8410,226 @@ const TaskCard = ({
8341
8410
  onClick(task);
8342
8411
  }
8343
8412
  };
8413
+ const handleContextMenu = (e) => {
8414
+ if (isDragging) return;
8415
+ e.preventDefault();
8416
+ e.stopPropagation();
8417
+ setContextMenuPosition({ x: e.clientX, y: e.clientY });
8418
+ };
8419
+ const handleCopyPath = async (task2) => {
8420
+ if (task2.filePath) {
8421
+ try {
8422
+ await navigator.clipboard.writeText(task2.filePath);
8423
+ setCopyFeedback(true);
8424
+ setTimeout(() => setCopyFeedback(false), 2e3);
8425
+ } catch (err) {
8426
+ console.error("Failed to copy task path:", err);
8427
+ }
8428
+ }
8429
+ };
8344
8430
  const displayTitle = task.title.replace(/^Task\s+\d+\s*[:\-–—]?\s*/i, "").trim() || task.title;
8345
- return /* @__PURE__ */ jsxs(
8346
- "div",
8347
- {
8348
- ref: setNodeRef,
8349
- style: style2,
8350
- onClick: handleClick,
8351
- ...listeners,
8352
- ...attributes,
8353
- onMouseEnter: (e) => {
8354
- if (!isDragging && !isDragOverlay) {
8355
- const desc = e.currentTarget.querySelector("p");
8356
- if (desc) {
8357
- desc.style.maxHeight = "20em";
8431
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8432
+ /* @__PURE__ */ jsxs(
8433
+ "div",
8434
+ {
8435
+ ref: setNodeRef,
8436
+ style: style2,
8437
+ onClick: handleClick,
8438
+ onContextMenu: handleContextMenu,
8439
+ ...listeners,
8440
+ ...attributes,
8441
+ onMouseEnter: (e) => {
8442
+ if (!isDragging && !isDragOverlay) {
8443
+ const desc = e.currentTarget.querySelector("p");
8444
+ if (desc) {
8445
+ desc.style.maxHeight = "20em";
8446
+ }
8447
+ e.currentTarget.style.borderLeft = `4px solid ${getPriorityColor(task.priority)}`;
8358
8448
  }
8359
- e.currentTarget.style.borderLeft = `4px solid ${getPriorityColor(task.priority)}`;
8360
- }
8361
- },
8362
- onMouseLeave: (e) => {
8363
- if (!isDragging && !isDragOverlay) {
8364
- const desc = e.currentTarget.querySelector("p");
8365
- if (desc) {
8366
- desc.style.maxHeight = "2.8em";
8449
+ },
8450
+ onMouseLeave: (e) => {
8451
+ if (!isDragging && !isDragOverlay) {
8452
+ const desc = e.currentTarget.querySelector("p");
8453
+ if (desc) {
8454
+ desc.style.maxHeight = "2.8em";
8455
+ }
8456
+ e.currentTarget.style.borderLeft = `4px solid ${getPriorityColor(task.priority)}`;
8367
8457
  }
8368
- e.currentTarget.style.borderLeft = `4px solid ${getPriorityColor(task.priority)}`;
8369
- }
8370
- },
8371
- children: [
8372
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "8px" }, children: [
8373
- /* @__PURE__ */ jsx(
8374
- "h4",
8458
+ },
8459
+ children: [
8460
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "8px" }, children: [
8461
+ /* @__PURE__ */ jsx(
8462
+ "h4",
8463
+ {
8464
+ style: {
8465
+ margin: 0,
8466
+ fontSize: theme2.fontSizes[2],
8467
+ color: isSelected ? getPriorityColor(task.priority) : theme2.colors.text,
8468
+ fontWeight: theme2.fontWeights.medium,
8469
+ flex: 1
8470
+ },
8471
+ children: displayTitle
8472
+ }
8473
+ ),
8474
+ getGitHubIssueFromRefs$1(task.references) && /* @__PURE__ */ jsx(
8475
+ "div",
8476
+ {
8477
+ style: {
8478
+ display: "flex",
8479
+ alignItems: "center",
8480
+ gap: "3px",
8481
+ padding: "2px 6px",
8482
+ borderRadius: theme2.radii[1],
8483
+ background: `${theme2.colors.success}20`,
8484
+ color: theme2.colors.success,
8485
+ fontSize: theme2.fontSizes[0],
8486
+ fontWeight: theme2.fontWeights.medium,
8487
+ flexShrink: 0
8488
+ },
8489
+ title: "Assigned to Claude",
8490
+ children: /* @__PURE__ */ jsx(GitBranch, { size: 10 })
8491
+ }
8492
+ )
8493
+ ] }),
8494
+ task.description && /* @__PURE__ */ jsx(
8495
+ "p",
8375
8496
  {
8376
8497
  style: {
8377
- margin: 0,
8378
- fontSize: theme2.fontSizes[2],
8379
- color: isSelected ? getPriorityColor(task.priority) : theme2.colors.text,
8380
- fontWeight: theme2.fontWeights.medium,
8381
- flex: 1
8498
+ margin: "0 0 8px 0",
8499
+ fontSize: theme2.fontSizes[1],
8500
+ color: theme2.colors.textSecondary,
8501
+ overflow: "hidden",
8502
+ lineHeight: "1.4",
8503
+ maxHeight: "2.8em",
8504
+ // 2 lines (1.4 * 2)
8505
+ transition: "max-height 0.3s ease"
8382
8506
  },
8383
- children: displayTitle
8507
+ children: task.description
8384
8508
  }
8385
8509
  ),
8386
- getGitHubIssueFromRefs$1(task.references) && /* @__PURE__ */ jsx(
8510
+ task.labels && task.labels.length > 0 && /* @__PURE__ */ jsx(
8387
8511
  "div",
8388
8512
  {
8389
8513
  style: {
8390
8514
  display: "flex",
8391
- alignItems: "center",
8392
- gap: "3px",
8393
- padding: "2px 6px",
8394
- borderRadius: theme2.radii[1],
8395
- background: `${theme2.colors.success}20`,
8396
- color: theme2.colors.success,
8397
- fontSize: theme2.fontSizes[0],
8398
- fontWeight: theme2.fontWeights.medium,
8399
- flexShrink: 0
8515
+ gap: "4px",
8516
+ flexWrap: "wrap",
8517
+ marginBottom: "8px"
8400
8518
  },
8401
- title: "Assigned to Claude",
8402
- children: /* @__PURE__ */ jsx(GitBranch, { size: 10 })
8403
- }
8404
- )
8405
- ] }),
8406
- task.description && /* @__PURE__ */ jsx(
8407
- "p",
8408
- {
8409
- style: {
8410
- margin: "0 0 8px 0",
8411
- fontSize: theme2.fontSizes[1],
8412
- color: theme2.colors.textSecondary,
8413
- overflow: "hidden",
8414
- lineHeight: "1.4",
8415
- maxHeight: "2.8em",
8416
- // 2 lines (1.4 * 2)
8417
- transition: "max-height 0.3s ease"
8418
- },
8419
- children: task.description
8420
- }
8421
- ),
8422
- task.labels && task.labels.length > 0 && /* @__PURE__ */ jsx(
8423
- "div",
8424
- {
8425
- style: {
8426
- display: "flex",
8427
- gap: "4px",
8428
- flexWrap: "wrap",
8429
- marginBottom: "8px"
8430
- },
8431
- children: task.labels.map((label) => /* @__PURE__ */ jsx(
8432
- "span",
8433
- {
8434
- style: {
8435
- fontSize: theme2.fontSizes[0],
8436
- color: theme2.colors.primary,
8437
- background: `${theme2.colors.primary}20`,
8438
- padding: "2px 8px",
8439
- borderRadius: theme2.radii[1],
8440
- fontWeight: theme2.fontWeights.medium
8519
+ children: task.labels.map((label) => /* @__PURE__ */ jsx(
8520
+ "span",
8521
+ {
8522
+ style: {
8523
+ fontSize: theme2.fontSizes[0],
8524
+ color: theme2.colors.primary,
8525
+ background: `${theme2.colors.primary}20`,
8526
+ padding: "2px 8px",
8527
+ borderRadius: theme2.radii[1],
8528
+ fontWeight: theme2.fontWeights.medium
8529
+ },
8530
+ children: label
8441
8531
  },
8442
- children: label
8532
+ label
8533
+ ))
8534
+ }
8535
+ ),
8536
+ /* @__PURE__ */ jsxs(
8537
+ "div",
8538
+ {
8539
+ style: {
8540
+ display: "flex",
8541
+ alignItems: "center",
8542
+ justifyContent: "space-between",
8543
+ fontSize: theme2.fontSizes[0],
8544
+ color: theme2.colors.textMuted
8443
8545
  },
8444
- label
8445
- ))
8446
- }
8447
- ),
8448
- /* @__PURE__ */ jsxs(
8449
- "div",
8450
- {
8451
- style: {
8452
- display: "flex",
8453
- alignItems: "center",
8454
- justifyContent: "space-between",
8455
- fontSize: theme2.fontSizes[0],
8456
- color: theme2.colors.textMuted
8457
- },
8458
- children: [
8459
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
8460
- /* @__PURE__ */ jsx(
8546
+ children: [
8547
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
8548
+ /* @__PURE__ */ jsx(
8549
+ "span",
8550
+ {
8551
+ style: {
8552
+ fontFamily: theme2.fonts.monospace
8553
+ },
8554
+ children: task.id
8555
+ }
8556
+ ),
8557
+ (() => {
8558
+ const issue = getGitHubIssueFromRefs$1(task.references);
8559
+ if (!issue) return null;
8560
+ return /* @__PURE__ */ jsxs(
8561
+ "a",
8562
+ {
8563
+ href: issue.url,
8564
+ target: "_blank",
8565
+ rel: "noopener noreferrer",
8566
+ onClick: (e) => e.stopPropagation(),
8567
+ style: {
8568
+ display: "inline-flex",
8569
+ alignItems: "center",
8570
+ gap: "3px",
8571
+ color: theme2.colors.primary,
8572
+ textDecoration: "none",
8573
+ fontSize: theme2.fontSizes[0]
8574
+ },
8575
+ title: `View issue #${issue.number} on GitHub`,
8576
+ children: [
8577
+ /* @__PURE__ */ jsx(ExternalLink, { size: 10 }),
8578
+ "#",
8579
+ issue.number
8580
+ ]
8581
+ }
8582
+ );
8583
+ })()
8584
+ ] }),
8585
+ task.assignee && task.assignee.length > 0 && /* @__PURE__ */ jsxs(
8461
8586
  "span",
8462
8587
  {
8463
8588
  style: {
8464
- fontFamily: theme2.fonts.monospace
8589
+ color: theme2.colors.textSecondary
8465
8590
  },
8466
- children: task.id
8591
+ children: [
8592
+ task.assignee.length,
8593
+ " assignee",
8594
+ task.assignee.length !== 1 ? "s" : ""
8595
+ ]
8467
8596
  }
8468
- ),
8469
- (() => {
8470
- const issue = getGitHubIssueFromRefs$1(task.references);
8471
- if (!issue) return null;
8472
- return /* @__PURE__ */ jsxs(
8473
- "a",
8474
- {
8475
- href: issue.url,
8476
- target: "_blank",
8477
- rel: "noopener noreferrer",
8478
- onClick: (e) => e.stopPropagation(),
8479
- style: {
8480
- display: "inline-flex",
8481
- alignItems: "center",
8482
- gap: "3px",
8483
- color: theme2.colors.primary,
8484
- textDecoration: "none",
8485
- fontSize: theme2.fontSizes[0]
8486
- },
8487
- title: `View issue #${issue.number} on GitHub`,
8488
- children: [
8489
- /* @__PURE__ */ jsx(ExternalLink, { size: 10 }),
8490
- "#",
8491
- issue.number
8492
- ]
8493
- }
8494
- );
8495
- })()
8496
- ] }),
8497
- task.assignee && task.assignee.length > 0 && /* @__PURE__ */ jsxs(
8498
- "span",
8499
- {
8500
- style: {
8501
- color: theme2.colors.textSecondary
8502
- },
8503
- children: [
8504
- task.assignee.length,
8505
- " assignee",
8506
- task.assignee.length !== 1 ? "s" : ""
8507
- ]
8508
- }
8509
- )
8510
- ]
8511
- }
8512
- )
8513
- ]
8514
- }
8515
- );
8597
+ )
8598
+ ]
8599
+ }
8600
+ )
8601
+ ]
8602
+ }
8603
+ ),
8604
+ contextMenuPosition && /* @__PURE__ */ jsx(
8605
+ TaskContextMenu,
8606
+ {
8607
+ task,
8608
+ position: contextMenuPosition,
8609
+ onClose: () => setContextMenuPosition(null),
8610
+ onCopyPath: handleCopyPath
8611
+ }
8612
+ ),
8613
+ copyFeedback && /* @__PURE__ */ jsx(
8614
+ "div",
8615
+ {
8616
+ style: {
8617
+ position: "fixed",
8618
+ bottom: "20px",
8619
+ right: "20px",
8620
+ background: theme2.colors.success,
8621
+ color: "white",
8622
+ padding: "12px 16px",
8623
+ borderRadius: theme2.radii[2],
8624
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
8625
+ zIndex: 10001,
8626
+ fontSize: theme2.fontSizes[1],
8627
+ fontWeight: theme2.fontWeights.medium
8628
+ },
8629
+ children: "Task path copied to clipboard!"
8630
+ }
8631
+ )
8632
+ ] });
8516
8633
  };
8517
8634
  const KanbanColumn = ({
8518
8635
  columnId,