@linxin666/dsh-client-ui-task-board 0.3.4 → 0.3.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.
package/lib/client.js CHANGED
@@ -58,6 +58,10 @@ window.__ModuleLoader__.load({
58
58
  function isTaskStatus(value) {
59
59
  return typeof value === "string" && ALL_STATUSES.includes(value);
60
60
  }
61
+ /** Whether a manual move target is allowed from the given status. */
62
+ function canMoveManually(from, to) {
63
+ return from !== "running" && MANUAL_STATUSES.includes(to);
64
+ }
61
65
  /** Normalize one optional execution-target string: trim; blank collapses to undefined. */
62
66
  function normalizeTargetId(value) {
63
67
  const trimmed = value?.trim();
@@ -527,10 +531,6 @@ window.__ModuleLoader__.load({
527
531
  const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
528
532
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
529
533
  }
530
- /** Read the current selection off a session-list snapshot (structural). */
531
- function currentOf(sessions) {
532
- return sessions.list.getSnapshot().current;
533
- }
534
534
  function messageOf(error) {
535
535
  return error instanceof Error ? error.message : String(error);
536
536
  }
@@ -611,7 +611,6 @@ window.__ModuleLoader__.load({
611
611
  }
612
612
  openBoard() {
613
613
  if (this.boardOpen) return;
614
- this.lastCurrent = currentOf(this.deps.sessions);
615
614
  this.boardOpen = true;
616
615
  this.notify();
617
616
  }
@@ -831,14 +830,17 @@ window.__ModuleLoader__.load({
831
830
  taskId: id
832
831
  }, id);
833
832
  }
834
- /** Close the board when the user navigates to another session. */
835
- onSessionsChanged() {
836
- if (!this.boardOpen) return;
837
- const current = currentOf(this.deps.sessions);
838
- if (current !== this.lastCurrent) this.closeBoard();
839
- this.lastCurrent = current;
840
- }
841
- lastCurrent = void 0;
833
+ /**
834
+ * Session-list notifications fire for all kinds of incidental churn
835
+ * (background navigation, the Host runner creating and selecting a fresh
836
+ * execution session, settlement, other plugins), so closing on `current`
837
+ * changes would evict the board without the user asking. The board closes
838
+ * only on explicit user navigation: a sidebar session/workspace row click
839
+ * (board-mount onClickSidebarRow) or the board's own actions
840
+ * (openSession / close). Keeping the hook preserves the subscription
841
+ * contract for future listeners.
842
+ */
843
+ onSessionsChanged() {}
842
844
  persistAndNotify() {
843
845
  if (this.deps.transport === void 0) this.deps.store.save(this.tasks);
844
846
  this.notify();
@@ -1799,17 +1801,22 @@ window.__ModuleLoader__.load({
1799
1801
  if (timeZone !== void 0) return formatHostTimestamp(ms, timeZone);
1800
1802
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
1801
1803
  }
1802
- /** One card in a column. */
1803
1804
  function TaskCardInner({ task, pending, timeZone, onClick }) {
1804
1805
  const latest = task.executions[task.executions.length - 1];
1805
1806
  const runs = task.executions.length;
1806
1807
  const archived = task.archivedAt !== void 0;
1808
+ const isDraggable = !archived && task.status !== "running" && !pending;
1807
1809
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1808
1810
  type: "button",
1809
1811
  className: board_module_css_default.card,
1810
1812
  "data-status": archived ? "archived" : task.status,
1811
1813
  "data-dsh-part": "card",
1812
1814
  "data-pending": pending || void 0,
1815
+ draggable: isDraggable,
1816
+ onDragStart: isDraggable ? (event) => {
1817
+ event.dataTransfer.setData("text/plain", task.id);
1818
+ event.dataTransfer.effectAllowed = "move";
1819
+ } : void 0,
1813
1820
  onClick,
1814
1821
  title: task.description !== "" ? task.description : task.title,
1815
1822
  children: [
@@ -2669,10 +2676,22 @@ window.__ModuleLoader__.load({
2669
2676
  })]
2670
2677
  }) : COLUMNS.map((column) => {
2671
2678
  const tasks = visible.filter((task) => task.status === column.status);
2679
+ const isManualDropTarget = column.status === "backlog" || column.status === "todo";
2672
2680
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2673
2681
  className: board_module_css_default.column,
2674
2682
  "data-status": column.status,
2675
2683
  "data-dsh-part": "column",
2684
+ onDragOver: isManualDropTarget ? (event) => {
2685
+ event.preventDefault();
2686
+ event.dataTransfer.dropEffect = "move";
2687
+ } : void 0,
2688
+ onDrop: isManualDropTarget ? (event) => {
2689
+ event.preventDefault();
2690
+ const taskId = event.dataTransfer.getData("text/plain");
2691
+ if (!taskId) return;
2692
+ const dropped = snapshot.tasks.find((t) => t.id === taskId);
2693
+ if (dropped && canMoveManually(dropped.status, column.status) && dropped.status !== column.status) controller.moveTask(taskId, column.status);
2694
+ } : void 0,
2676
2695
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2677
2696
  className: board_module_css_default.columnHeader,
2678
2697
  children: [
@@ -3854,7 +3873,7 @@ window.__ModuleLoader__.load({
3854
3873
  /** The building package's version, when the bundle carries it. */
3855
3874
  function bakedVersion() {
3856
3875
  try {
3857
- return "0.3.4";
3876
+ return "0.3.5";
3858
3877
  } catch {
3859
3878
  return;
3860
3879
  }