@flanksource/clicky-ui 0.2.4 → 0.2.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.
Files changed (177) hide show
  1. package/dist/components/Combobox.cjs +291 -0
  2. package/dist/components/Combobox.cjs.map +1 -0
  3. package/dist/components/Combobox.d.ts +59 -0
  4. package/dist/components/Combobox.d.ts.map +1 -0
  5. package/dist/components/Combobox.js +291 -0
  6. package/dist/components/Combobox.js.map +1 -0
  7. package/dist/components/FilterBar.cjs +153 -124
  8. package/dist/components/FilterBar.cjs.map +1 -1
  9. package/dist/components/FilterBar.d.ts +25 -1
  10. package/dist/components/FilterBar.d.ts.map +1 -1
  11. package/dist/components/FilterBar.js +153 -124
  12. package/dist/components/FilterBar.js.map +1 -1
  13. package/dist/components/FormatOptionsDropdown.cjs +62 -0
  14. package/dist/components/FormatOptionsDropdown.cjs.map +1 -0
  15. package/dist/components/FormatOptionsDropdown.d.ts +37 -0
  16. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -0
  17. package/dist/components/FormatOptionsDropdown.js +62 -0
  18. package/dist/components/FormatOptionsDropdown.js.map +1 -0
  19. package/dist/components/SplitButton.cjs +87 -0
  20. package/dist/components/SplitButton.cjs.map +1 -0
  21. package/dist/components/SplitButton.d.ts +32 -0
  22. package/dist/components/SplitButton.d.ts.map +1 -0
  23. package/dist/components/SplitButton.js +87 -0
  24. package/dist/components/SplitButton.js.map +1 -0
  25. package/dist/components/icon-menu-picker.cjs +1 -1
  26. package/dist/components/icon-menu-picker.cjs.map +1 -1
  27. package/dist/components/icon-menu-picker.js +1 -1
  28. package/dist/components/icon-menu-picker.js.map +1 -1
  29. package/dist/components.cjs +7 -0
  30. package/dist/components.cjs.map +1 -1
  31. package/dist/components.d.ts +3 -0
  32. package/dist/components.d.ts.map +1 -1
  33. package/dist/components.js +7 -0
  34. package/dist/components.js.map +1 -1
  35. package/dist/data/Badge.d.ts +1 -1
  36. package/dist/data/ProgressBar.cjs +4 -2
  37. package/dist/data/ProgressBar.cjs.map +1 -1
  38. package/dist/data/ProgressBar.d.ts +1 -1
  39. package/dist/data/ProgressBar.d.ts.map +1 -1
  40. package/dist/data/ProgressBar.js +4 -2
  41. package/dist/data/ProgressBar.js.map +1 -1
  42. package/dist/data/TaskManager.cjs +162 -0
  43. package/dist/data/TaskManager.cjs.map +1 -0
  44. package/dist/data/TaskManager.d.ts +21 -0
  45. package/dist/data/TaskManager.d.ts.map +1 -0
  46. package/dist/data/TaskManager.js +162 -0
  47. package/dist/data/TaskManager.js.map +1 -0
  48. package/dist/data/TaskProgress.cjs +125 -0
  49. package/dist/data/TaskProgress.cjs.map +1 -0
  50. package/dist/data/TaskProgress.d.ts +20 -0
  51. package/dist/data/TaskProgress.d.ts.map +1 -0
  52. package/dist/data/TaskProgress.js +125 -0
  53. package/dist/data/TaskProgress.js.map +1 -0
  54. package/dist/data/TaskSnapshot.cjs +23 -0
  55. package/dist/data/TaskSnapshot.cjs.map +1 -0
  56. package/dist/data/TaskSnapshot.d.ts +49 -0
  57. package/dist/data/TaskSnapshot.d.ts.map +1 -0
  58. package/dist/data/TaskSnapshot.js +23 -0
  59. package/dist/data/TaskSnapshot.js.map +1 -0
  60. package/dist/data/TimeseriesPanel.axes.cjs +39 -0
  61. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -0
  62. package/dist/data/TimeseriesPanel.axes.d.ts +28 -0
  63. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -0
  64. package/dist/data/TimeseriesPanel.axes.js +39 -0
  65. package/dist/data/TimeseriesPanel.axes.js.map +1 -0
  66. package/dist/data/TimeseriesPanel.cjs +324 -0
  67. package/dist/data/TimeseriesPanel.cjs.map +1 -0
  68. package/dist/data/TimeseriesPanel.d.ts +141 -0
  69. package/dist/data/TimeseriesPanel.d.ts.map +1 -0
  70. package/dist/data/TimeseriesPanel.js +324 -0
  71. package/dist/data/TimeseriesPanel.js.map +1 -0
  72. package/dist/data/Tree.cjs.map +1 -1
  73. package/dist/data/Tree.d.ts.map +1 -1
  74. package/dist/data/Tree.js.map +1 -1
  75. package/dist/data/TreeNode.cjs +44 -7
  76. package/dist/data/TreeNode.cjs.map +1 -1
  77. package/dist/data/TreeNode.d.ts +19 -1
  78. package/dist/data/TreeNode.d.ts.map +1 -1
  79. package/dist/data/TreeNode.js +44 -7
  80. package/dist/data/TreeNode.js.map +1 -1
  81. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +66 -44
  82. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  83. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +21 -1
  84. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  85. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +65 -43
  86. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  87. package/dist/data/diagnostics/DiagnosticsTree.cjs +2 -1
  88. package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
  89. package/dist/data/diagnostics/DiagnosticsTree.js +2 -1
  90. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
  91. package/dist/data/diagnostics/FrameSourceWindow.cjs +37 -0
  92. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -0
  93. package/dist/data/diagnostics/FrameSourceWindow.d.ts +15 -0
  94. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -0
  95. package/dist/data/diagnostics/FrameSourceWindow.js +37 -0
  96. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -0
  97. package/dist/data/diagnostics/JvmStackTrace.cjs +25 -12
  98. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  99. package/dist/data/diagnostics/JvmStackTrace.d.ts +8 -1
  100. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  101. package/dist/data/diagnostics/JvmStackTrace.js +26 -13
  102. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  103. package/dist/data/diagnostics/ThreadCard.cjs +9 -2
  104. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  105. package/dist/data/diagnostics/ThreadCard.d.ts +3 -1
  106. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  107. package/dist/data/diagnostics/ThreadCard.js +9 -2
  108. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  109. package/dist/data/diagnostics/jvm-stacktrace.cjs +10 -1
  110. package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
  111. package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
  112. package/dist/data/diagnostics/jvm-stacktrace.js +10 -1
  113. package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
  114. package/dist/data/diagnostics/utils.cjs +0 -12
  115. package/dist/data/diagnostics/utils.cjs.map +1 -1
  116. package/dist/data/diagnostics/utils.d.ts +1 -1
  117. package/dist/data/diagnostics/utils.d.ts.map +1 -1
  118. package/dist/data/diagnostics/utils.js +0 -12
  119. package/dist/data/diagnostics/utils.js.map +1 -1
  120. package/dist/data/task-status.cjs +108 -0
  121. package/dist/data/task-status.cjs.map +1 -0
  122. package/dist/data/task-status.d.ts +21 -0
  123. package/dist/data/task-status.d.ts.map +1 -0
  124. package/dist/data/task-status.js +108 -0
  125. package/dist/data/task-status.js.map +1 -0
  126. package/dist/data.cjs +21 -0
  127. package/dist/data.cjs.map +1 -1
  128. package/dist/data.d.ts +7 -1
  129. package/dist/data.d.ts.map +1 -1
  130. package/dist/data.js +21 -0
  131. package/dist/data.js.map +1 -1
  132. package/dist/hooks/use-task-run.cjs +137 -0
  133. package/dist/hooks/use-task-run.cjs.map +1 -0
  134. package/dist/hooks/use-task-run.d.ts +35 -0
  135. package/dist/hooks/use-task-run.d.ts.map +1 -0
  136. package/dist/hooks/use-task-run.js +137 -0
  137. package/dist/hooks/use-task-run.js.map +1 -0
  138. package/dist/hooks.cjs +3 -0
  139. package/dist/hooks.cjs.map +1 -1
  140. package/dist/hooks.d.ts +1 -0
  141. package/dist/hooks.d.ts.map +1 -1
  142. package/dist/hooks.js +3 -0
  143. package/dist/hooks.js.map +1 -1
  144. package/dist/index.cjs +37 -0
  145. package/dist/index.cjs.map +1 -1
  146. package/dist/index.js +37 -0
  147. package/dist/index.js.map +1 -1
  148. package/dist/lib/color.cjs +33 -0
  149. package/dist/lib/color.cjs.map +1 -0
  150. package/dist/lib/color.d.ts +10 -0
  151. package/dist/lib/color.d.ts.map +1 -0
  152. package/dist/lib/color.js +33 -0
  153. package/dist/lib/color.js.map +1 -0
  154. package/dist/lib/format.cjs +77 -0
  155. package/dist/lib/format.cjs.map +1 -0
  156. package/dist/lib/format.d.ts +30 -0
  157. package/dist/lib/format.d.ts.map +1 -0
  158. package/dist/lib/format.js +77 -0
  159. package/dist/lib/format.js.map +1 -0
  160. package/dist/overlay/DropdownMenu.cjs +18 -2
  161. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  162. package/dist/overlay/DropdownMenu.d.ts +3 -1
  163. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  164. package/dist/overlay/DropdownMenu.js +18 -2
  165. package/dist/overlay/DropdownMenu.js.map +1 -1
  166. package/dist/rpc/types.cjs.map +1 -1
  167. package/dist/rpc/types.d.ts +4 -0
  168. package/dist/rpc/types.d.ts.map +1 -1
  169. package/dist/rpc/types.js.map +1 -1
  170. package/dist/styles.css +1 -1
  171. package/dist/utils.cjs +6 -0
  172. package/dist/utils.cjs.map +1 -1
  173. package/dist/utils.d.ts +1 -0
  174. package/dist/utils.d.ts.map +1 -1
  175. package/dist/utils.js +6 -0
  176. package/dist/utils.js.map +1 -1
  177. package/package.json +4 -1
@@ -1,4 +1,6 @@
1
1
  export { Button, buttonVariants, type ButtonProps } from './components/button';
2
+ export { SplitButton, type SplitButtonProps } from './components/SplitButton';
3
+ export { FormatOptionsDropdown, CLICKY_FORMAT_OPTIONS, type FormatOptionsDropdownProps, type FormatOption, } from './components/FormatOptionsDropdown';
2
4
  export { DateField, type DateFieldMode, type DateFieldProps } from './components/DateField';
3
5
  export { DatePicker, type DatePickerProps } from './components/DatePicker';
4
6
  export { DateTimePicker, type DateTimePickerProps } from './components/DateTimePicker';
@@ -7,6 +9,7 @@ export { RangeSlider, type RangeSliderProps, type RangeSliderValue, } from './co
7
9
  export { FilterBar, type FilterBarBooleanFilter, type FilterBarEnumFilter, type FilterBarFilter, type FilterBarLookupFilter, type FilterBarLookupInputType, type FilterBarLookupMultiFilter, type FilterBarLookupOption, type FilterBarMultiFilter, type FilterBarMultiFilterMode, type FilterBarNestedMultiFilter, type FilterBarNestedMultiGroup, type FilterBarNumberFilter, type FilterBarNumberValue, type FilterBarProps, type FilterBarRangePreset, type FilterBarRangeProps, type FilterBarSearchProps, type FilterBarSelectMultiFilter, type FilterBarTextFilter, } from './components/FilterBar';
8
10
  export { MultiSelect, type MultiSelectOption, type MultiSelectProps, } from './components/MultiSelect';
9
11
  export { Select, type SelectProps, type SelectOption } from './components/select';
12
+ export { Combobox, type ComboboxProps, type ComboboxOption, type ComboboxSingleProps, type ComboboxMultiProps, } from './components/Combobox';
10
13
  export { ThemeSwitcher, type ThemeSwitcherProps } from './components/theme-switcher';
11
14
  export { DensitySwitcher, type DensitySwitcherProps } from './components/density-switcher';
12
15
  export { IconMenuPicker, type IconMenuPickerProps, type IconMenuOption, } from './components/icon-menu-picker';
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,OAAO,EACP,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,qBAAqB,GAC3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,YAAY,GAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EACL,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,OAAO,EACP,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,qBAAqB,GAC3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { Button, buttonVariants } from "./components/button.js";
2
+ import { SplitButton } from "./components/SplitButton.js";
3
+ import { CLICKY_FORMAT_OPTIONS, FormatOptionsDropdown } from "./components/FormatOptionsDropdown.js";
2
4
  import { DateField } from "./components/DateField.js";
3
5
  import { DatePicker } from "./components/DatePicker.js";
4
6
  import { DateTimePicker } from "./components/DateTimePicker.js";
@@ -7,6 +9,7 @@ import { RangeSlider } from "./components/RangeSlider.js";
7
9
  import { FilterBar } from "./components/FilterBar.js";
8
10
  import { MultiSelect } from "./components/MultiSelect.js";
9
11
  import { Select } from "./components/select.js";
12
+ import { Combobox } from "./components/Combobox.js";
10
13
  import { ThemeSwitcher } from "./components/theme-switcher.js";
11
14
  import { DensitySwitcher } from "./components/density-switcher.js";
12
15
  import { IconMenuPicker } from "./components/icon-menu-picker.js";
@@ -17,6 +20,8 @@ import { HoverCard } from "./overlay/HoverCard.js";
17
20
  import { Modal } from "./overlay/Modal.js";
18
21
  export {
19
22
  Button,
23
+ CLICKY_FORMAT_OPTIONS,
24
+ Combobox,
20
25
  DateField,
21
26
  DatePicker,
22
27
  DateTimePicker,
@@ -24,6 +29,7 @@ export {
24
29
  DetailEmptyState,
25
30
  DropdownMenu,
26
31
  FilterBar,
32
+ FormatOptionsDropdown,
27
33
  HoverCard,
28
34
  IconMenuPicker,
29
35
  Modal,
@@ -31,6 +37,7 @@ export {
31
37
  RangeSlider,
32
38
  Section,
33
39
  Select,
40
+ SplitButton,
34
41
  SplitPane,
35
42
  ThemeSwitcher,
36
43
  TimeRange,
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
@@ -2,7 +2,7 @@ import { AnchorHTMLAttributes, ReactNode } from 'react';
2
2
  import { VariantProps } from 'class-variance-authority';
3
3
  import { StaticIconComponent } from './Icon';
4
4
  export declare const badgeVariants: (props?: ({
5
- tone?: "neutral" | "info" | "danger" | "warning" | "success" | null | undefined;
5
+ tone?: "success" | "warning" | "neutral" | "info" | "danger" | null | undefined;
6
6
  variant?: "outline" | "solid" | "soft" | null | undefined;
7
7
  size?: "xs" | "sm" | "md" | "lg" | "xxs" | null | undefined;
8
8
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const utils = require("../lib/utils.cjs");
5
+ const color = require("../lib/color.cjs");
5
6
  function ProgressBar({ segments, total, height = "h-2", className }) {
6
7
  if (total === 0) return null;
7
8
  const tooltip = segments.filter((s) => s.count > 0).map((s) => `${s.count} ${s.label}`).join(", ");
@@ -17,11 +18,12 @@ function ProgressBar({ segments, total, height = "h-2", className }) {
17
18
  children: segments.map((seg, i) => {
18
19
  if (seg.count === 0) return null;
19
20
  const pct = seg.count / total * 100;
21
+ const asClass = color.isTailwindColorClass(seg.color);
20
22
  return /* @__PURE__ */ jsxRuntime.jsx(
21
23
  "div",
22
24
  {
23
- className: utils.cn(seg.color, height, "transition-all duration-300"),
24
- style: { width: `${pct}%` },
25
+ className: utils.cn(asClass ? seg.color : void 0, height, "transition-all duration-300"),
26
+ style: { width: `${pct}%`, ...asClass ? {} : { backgroundColor: seg.color } },
25
27
  title: `${seg.count} ${seg.label}`
26
28
  },
27
29
  i
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.cjs","sources":["../../src/data/ProgressBar.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\n\nexport type ProgressSegment = {\n /** Numeric amount represented by this segment. */\n count: number;\n /** Tailwind/background class applied to this segment. */\n color: string;\n /** Label used in the tooltip. */\n label: string;\n};\n\nexport type ProgressBarProps = {\n /** Segments rendered in order from left to right. */\n segments: ProgressSegment[];\n /** Total value used to calculate segment percentages. */\n total: number;\n /** Height utility class, e.g. `h-2`. */\n height?: string;\n /** Classes applied to the progressbar root. */\n className?: string;\n};\n\nexport function ProgressBar({ segments, total, height = \"h-2\", className }: ProgressBarProps) {\n if (total === 0) return null;\n\n const tooltip = segments\n .filter((s) => s.count > 0)\n .map((s) => `${s.count} ${s.label}`)\n .join(\", \");\n\n return (\n <div\n className={cn(\"w-full bg-muted rounded-full flex overflow-hidden\", height, className)}\n title={tooltip}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={segments.reduce((acc, s) => acc + s.count, 0)}\n >\n {segments.map((seg, i) => {\n if (seg.count === 0) return null;\n const pct = (seg.count / total) * 100;\n return (\n <div\n key={i}\n className={cn(seg.color, height, \"transition-all duration-300\")}\n style={{ width: `${pct}%` }}\n title={`${seg.count} ${seg.label}`}\n />\n );\n })}\n </div>\n );\n}\n"],"names":["jsx","cn"],"mappings":";;;;AAsBO,SAAS,YAAY,EAAE,UAAU,OAAO,SAAS,OAAO,aAA+B;AAC5F,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,UAAU,SACb,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,EAClC,KAAK,IAAI;AAEZ,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,MAAAA,GAAG,qDAAqD,QAAQ,SAAS;AAAA,MACpF,OAAO;AAAA,MACP,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,MAE1D,UAAA,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,YAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,cAAM,MAAO,IAAI,QAAQ,QAAS;AAClC,eACED,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWC,MAAAA,GAAG,IAAI,OAAO,QAAQ,6BAA6B;AAAA,YAC9D,OAAO,EAAE,OAAO,GAAG,GAAG,IAAA;AAAA,YACtB,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,UAAA;AAAA,UAH3B;AAAA,QAAA;AAAA,MAMX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
1
+ {"version":3,"file":"ProgressBar.cjs","sources":["../../src/data/ProgressBar.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { isTailwindColorClass } from \"../lib/color\";\n\nexport type ProgressSegment = {\n /** Numeric amount represented by this segment. */\n count: number;\n /** Segment fill: a Tailwind bg class (e.g. \"bg-green-500\") or a CSS color value. */\n color: string;\n /** Label used in the tooltip. */\n label: string;\n};\n\nexport type ProgressBarProps = {\n /** Segments rendered in order from left to right. */\n segments: ProgressSegment[];\n /** Total value used to calculate segment percentages. */\n total: number;\n /** Height utility class, e.g. `h-2`. */\n height?: string;\n /** Classes applied to the progressbar root. */\n className?: string;\n};\n\nexport function ProgressBar({ segments, total, height = \"h-2\", className }: ProgressBarProps) {\n if (total === 0) return null;\n\n const tooltip = segments\n .filter((s) => s.count > 0)\n .map((s) => `${s.count} ${s.label}`)\n .join(\", \");\n\n return (\n <div\n className={cn(\"w-full bg-muted rounded-full flex overflow-hidden\", height, className)}\n title={tooltip}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={segments.reduce((acc, s) => acc + s.count, 0)}\n >\n {segments.map((seg, i) => {\n if (seg.count === 0) return null;\n const pct = (seg.count / total) * 100;\n const asClass = isTailwindColorClass(seg.color);\n return (\n <div\n key={i}\n className={cn(asClass ? seg.color : undefined, height, \"transition-all duration-300\")}\n style={{ width: `${pct}%`, ...(asClass ? {} : { backgroundColor: seg.color }) }}\n title={`${seg.count} ${seg.label}`}\n />\n );\n })}\n </div>\n );\n}\n"],"names":["jsx","cn","isTailwindColorClass"],"mappings":";;;;;AAuBO,SAAS,YAAY,EAAE,UAAU,OAAO,SAAS,OAAO,aAA+B;AAC5F,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,UAAU,SACb,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,EAClC,KAAK,IAAI;AAEZ,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,MAAAA,GAAG,qDAAqD,QAAQ,SAAS;AAAA,MACpF,OAAO;AAAA,MACP,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,MAE1D,UAAA,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,YAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,cAAM,MAAO,IAAI,QAAQ,QAAS;AAClC,cAAM,UAAUC,MAAAA,qBAAqB,IAAI,KAAK;AAC9C,eACEF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWC,MAAAA,GAAG,UAAU,IAAI,QAAQ,QAAW,QAAQ,6BAA6B;AAAA,YACpF,OAAO,EAAE,OAAO,GAAG,GAAG,KAAK,GAAI,UAAU,CAAA,IAAK,EAAE,iBAAiB,IAAI,QAAM;AAAA,YAC3E,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,UAAA;AAAA,UAH3B;AAAA,QAAA;AAAA,MAMX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
@@ -1,7 +1,7 @@
1
1
  export type ProgressSegment = {
2
2
  /** Numeric amount represented by this segment. */
3
3
  count: number;
4
- /** Tailwind/background class applied to this segment. */
4
+ /** Segment fill: a Tailwind bg class (e.g. "bg-green-500") or a CSS color value. */
5
5
  color: string;
6
6
  /** Label used in the tooltip. */
7
7
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/data/ProgressBar.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG;IAC5B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAc,EAAE,SAAS,EAAE,EAAE,gBAAgB,kDA+B3F"}
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/data/ProgressBar.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG;IAC5B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAc,EAAE,SAAS,EAAE,EAAE,gBAAgB,kDAgC3F"}
@@ -1,5 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
+ import { isTailwindColorClass } from "../lib/color.js";
3
4
  function ProgressBar({ segments, total, height = "h-2", className }) {
4
5
  if (total === 0) return null;
5
6
  const tooltip = segments.filter((s) => s.count > 0).map((s) => `${s.count} ${s.label}`).join(", ");
@@ -15,11 +16,12 @@ function ProgressBar({ segments, total, height = "h-2", className }) {
15
16
  children: segments.map((seg, i) => {
16
17
  if (seg.count === 0) return null;
17
18
  const pct = seg.count / total * 100;
19
+ const asClass = isTailwindColorClass(seg.color);
18
20
  return /* @__PURE__ */ jsx(
19
21
  "div",
20
22
  {
21
- className: cn(seg.color, height, "transition-all duration-300"),
22
- style: { width: `${pct}%` },
23
+ className: cn(asClass ? seg.color : void 0, height, "transition-all duration-300"),
24
+ style: { width: `${pct}%`, ...asClass ? {} : { backgroundColor: seg.color } },
23
25
  title: `${seg.count} ${seg.label}`
24
26
  },
25
27
  i
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.js","sources":["../../src/data/ProgressBar.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\n\nexport type ProgressSegment = {\n /** Numeric amount represented by this segment. */\n count: number;\n /** Tailwind/background class applied to this segment. */\n color: string;\n /** Label used in the tooltip. */\n label: string;\n};\n\nexport type ProgressBarProps = {\n /** Segments rendered in order from left to right. */\n segments: ProgressSegment[];\n /** Total value used to calculate segment percentages. */\n total: number;\n /** Height utility class, e.g. `h-2`. */\n height?: string;\n /** Classes applied to the progressbar root. */\n className?: string;\n};\n\nexport function ProgressBar({ segments, total, height = \"h-2\", className }: ProgressBarProps) {\n if (total === 0) return null;\n\n const tooltip = segments\n .filter((s) => s.count > 0)\n .map((s) => `${s.count} ${s.label}`)\n .join(\", \");\n\n return (\n <div\n className={cn(\"w-full bg-muted rounded-full flex overflow-hidden\", height, className)}\n title={tooltip}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={segments.reduce((acc, s) => acc + s.count, 0)}\n >\n {segments.map((seg, i) => {\n if (seg.count === 0) return null;\n const pct = (seg.count / total) * 100;\n return (\n <div\n key={i}\n className={cn(seg.color, height, \"transition-all duration-300\")}\n style={{ width: `${pct}%` }}\n title={`${seg.count} ${seg.label}`}\n />\n );\n })}\n </div>\n );\n}\n"],"names":[],"mappings":";;AAsBO,SAAS,YAAY,EAAE,UAAU,OAAO,SAAS,OAAO,aAA+B;AAC5F,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,UAAU,SACb,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,EAClC,KAAK,IAAI;AAEZ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,GAAG,qDAAqD,QAAQ,SAAS;AAAA,MACpF,OAAO;AAAA,MACP,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,MAE1D,UAAA,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,YAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,cAAM,MAAO,IAAI,QAAQ,QAAS;AAClC,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW,GAAG,IAAI,OAAO,QAAQ,6BAA6B;AAAA,YAC9D,OAAO,EAAE,OAAO,GAAG,GAAG,IAAA;AAAA,YACtB,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,UAAA;AAAA,UAH3B;AAAA,QAAA;AAAA,MAMX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"ProgressBar.js","sources":["../../src/data/ProgressBar.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { isTailwindColorClass } from \"../lib/color\";\n\nexport type ProgressSegment = {\n /** Numeric amount represented by this segment. */\n count: number;\n /** Segment fill: a Tailwind bg class (e.g. \"bg-green-500\") or a CSS color value. */\n color: string;\n /** Label used in the tooltip. */\n label: string;\n};\n\nexport type ProgressBarProps = {\n /** Segments rendered in order from left to right. */\n segments: ProgressSegment[];\n /** Total value used to calculate segment percentages. */\n total: number;\n /** Height utility class, e.g. `h-2`. */\n height?: string;\n /** Classes applied to the progressbar root. */\n className?: string;\n};\n\nexport function ProgressBar({ segments, total, height = \"h-2\", className }: ProgressBarProps) {\n if (total === 0) return null;\n\n const tooltip = segments\n .filter((s) => s.count > 0)\n .map((s) => `${s.count} ${s.label}`)\n .join(\", \");\n\n return (\n <div\n className={cn(\"w-full bg-muted rounded-full flex overflow-hidden\", height, className)}\n title={tooltip}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={segments.reduce((acc, s) => acc + s.count, 0)}\n >\n {segments.map((seg, i) => {\n if (seg.count === 0) return null;\n const pct = (seg.count / total) * 100;\n const asClass = isTailwindColorClass(seg.color);\n return (\n <div\n key={i}\n className={cn(asClass ? seg.color : undefined, height, \"transition-all duration-300\")}\n style={{ width: `${pct}%`, ...(asClass ? {} : { backgroundColor: seg.color }) }}\n title={`${seg.count} ${seg.label}`}\n />\n );\n })}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AAuBO,SAAS,YAAY,EAAE,UAAU,OAAO,SAAS,OAAO,aAA+B;AAC5F,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,UAAU,SACb,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EACzB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,EAClC,KAAK,IAAI;AAEZ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,GAAG,qDAAqD,QAAQ,SAAS;AAAA,MACpF,OAAO;AAAA,MACP,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,MAE1D,UAAA,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,YAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,cAAM,MAAO,IAAI,QAAQ,QAAS;AAClC,cAAM,UAAU,qBAAqB,IAAI,KAAK;AAC9C,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW,GAAG,UAAU,IAAI,QAAQ,QAAW,QAAQ,6BAA6B;AAAA,YACpF,OAAO,EAAE,OAAO,GAAG,GAAG,KAAK,GAAI,UAAU,CAAA,IAAK,EAAE,iBAAiB,IAAI,QAAM;AAAA,YAC3E,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,UAAA;AAAA,UAH3B;AAAA,QAAA;AAAA,MAMX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const utils = require("../lib/utils.cjs");
6
+ const useTaskRun = require("../hooks/use-task-run.cjs");
7
+ const ProgressBar = require("./ProgressBar.cjs");
8
+ const Timestamp = require("./cells/Timestamp.cjs");
9
+ const TaskProgress = require("./TaskProgress.cjs");
10
+ const taskStatus = require("./task-status.cjs");
11
+ function TaskManager({
12
+ basePath,
13
+ kind,
14
+ pollMs,
15
+ className,
16
+ selectedId,
17
+ onSelectRun
18
+ }) {
19
+ const [kindFilter, setKindFilter] = react.useState(kind ?? "");
20
+ const [statusFilter, setStatusFilter] = react.useState("");
21
+ const { runs, status } = useTaskRun.useTaskRuns({
22
+ basePath,
23
+ kind: kind ?? (kindFilter || void 0),
24
+ status: statusFilter || void 0,
25
+ pollMs
26
+ });
27
+ const kinds = react.useMemo(() => {
28
+ const set = /* @__PURE__ */ new Set();
29
+ for (const r of runs) if (r.kind) set.add(r.kind);
30
+ return [...set].sort();
31
+ }, [runs]);
32
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("space-y-3", className), children: [
33
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
34
+ !kind && /* @__PURE__ */ jsxRuntime.jsxs(
35
+ "select",
36
+ {
37
+ className: "rounded-md border bg-background px-2 py-1 text-xs",
38
+ value: kindFilter,
39
+ onChange: (e) => setKindFilter(e.target.value),
40
+ children: [
41
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "All kinds" }),
42
+ kinds.map((k) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: k, children: k }, k))
43
+ ]
44
+ }
45
+ ),
46
+ /* @__PURE__ */ jsxRuntime.jsxs(
47
+ "select",
48
+ {
49
+ className: "rounded-md border bg-background px-2 py-1 text-xs",
50
+ value: statusFilter,
51
+ onChange: (e) => setStatusFilter(e.target.value),
52
+ children: [
53
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Any status" }),
54
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "running", children: "Running" }),
55
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
56
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "success", children: "Success" }),
57
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "failed", children: "Failed" }),
58
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "warning", children: "Warning" })
59
+ ]
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: status })
63
+ ] }),
64
+ runs.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-dashed p-6 text-center text-sm text-muted-foreground", children: "No background tasks." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border bg-card", children: runs.map((run) => /* @__PURE__ */ jsxRuntime.jsx(
65
+ RunRow,
66
+ {
67
+ run,
68
+ basePath,
69
+ pollMs,
70
+ selectedId,
71
+ onSelectRun
72
+ },
73
+ run.id
74
+ )) })
75
+ ] });
76
+ }
77
+ function RunRow({
78
+ run,
79
+ basePath,
80
+ pollMs,
81
+ selectedId,
82
+ onSelectRun
83
+ }) {
84
+ const [localOpen, setLocalOpen] = react.useState(false);
85
+ const controlled = onSelectRun !== void 0;
86
+ const open = controlled ? selectedId === run.id : localOpen;
87
+ const toggle = () => {
88
+ if (controlled) onSelectRun(open ? null : run.id);
89
+ else setLocalOpen((v) => !v);
90
+ };
91
+ const isTerminal = run.status !== "running" && run.status !== "pending";
92
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b last:border-0", children: [
93
+ /* @__PURE__ */ jsxRuntime.jsxs(
94
+ "button",
95
+ {
96
+ type: "button",
97
+ className: "flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-muted/50",
98
+ onClick: toggle,
99
+ children: [
100
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
101
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
102
+ /* @__PURE__ */ jsxRuntime.jsx("iconify-icon", { icon: taskStatus.taskStatusIcon(run.status), class: taskStatus.taskStatusColor(run.status) }),
103
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: run.name }),
104
+ run.kind && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground", children: run.kind }),
105
+ isTerminal && /* @__PURE__ */ jsxRuntime.jsx(
106
+ "span",
107
+ {
108
+ className: utils.cn(
109
+ "rounded-full px-2 py-0.5 text-xs",
110
+ taskStatus.taskStatusColor(run.status),
111
+ taskStatus.taskStatusBg(run.status)
112
+ ),
113
+ children: run.status
114
+ }
115
+ )
116
+ ] }),
117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground", children: [
118
+ run.startedAt && /* @__PURE__ */ jsxRuntime.jsx(Timestamp.Timestamp, { value: run.startedAt, format: "relative" }),
119
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
120
+ run.completed + run.failed,
121
+ "/",
122
+ run.total,
123
+ " done",
124
+ run.failed > 0 ? `, ${run.failed} failed` : ""
125
+ ] }),
126
+ Object.entries(run.labels ?? {}).map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
127
+ k,
128
+ "=",
129
+ v
130
+ ] }, k))
131
+ ] })
132
+ ] }),
133
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-40 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
134
+ ProgressBar.ProgressBar,
135
+ {
136
+ segments: taskStatus.taskSegments({
137
+ ok: run.completed,
138
+ warn: 0,
139
+ fail: run.failed,
140
+ run: run.running,
141
+ pending: Math.max(0, run.total - run.completed - run.failed - run.running)
142
+ }),
143
+ total: run.total || 1,
144
+ height: "h-1.5"
145
+ }
146
+ ) })
147
+ ]
148
+ }
149
+ ),
150
+ open && /* @__PURE__ */ jsxRuntime.jsx(ExpandedRun, { runId: run.id, basePath, pollMs })
151
+ ] });
152
+ }
153
+ function ExpandedRun({
154
+ runId,
155
+ basePath,
156
+ pollMs
157
+ }) {
158
+ const { snapshots } = useTaskRun.useTaskRun({ id: runId, basePath, pollMs });
159
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t bg-muted/30 px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(TaskProgress.TaskProgress, { snapshots, compact: true }) });
160
+ }
161
+ exports.TaskManager = TaskManager;
162
+ //# sourceMappingURL=TaskManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskManager.cjs","sources":["../../src/data/TaskManager.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useTaskRun, useTaskRuns } from \"../hooks/use-task-run\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport { TaskProgress } from \"./TaskProgress\";\nimport type { TaskRunMeta } from \"./TaskSnapshot\";\nimport { taskSegments, taskStatusBg, taskStatusColor, taskStatusIcon } from \"./task-status\";\n\n// TaskManager is the generic clicky-ui task-manager view: it lists every run\n// (TaskRunMeta) from GET {basePath}/tasks with kind/status filters, and expands\n// each row into a live <TaskProgress> for that run id. Fully generic — no\n// application concepts.\n\nexport interface TaskManagerProps {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string;\n /** Restrict the listing to a single kind (also hides the kind filter). */\n kind?: string;\n pollMs?: number;\n className?: string;\n /**\n * Currently-selected (expanded) run id, e.g. driven from the URL. When set,\n * the matching run renders expanded and selection is controlled — otherwise\n * each row manages its own expand/collapse state.\n */\n selectedId?: string;\n /**\n * Called when a run row is toggled: the new selection id, or null when the\n * open row is collapsed. Pair with selectedId for URL-driven deep links.\n */\n onSelectRun?: (id: string | null) => void;\n}\n\nexport function TaskManager({\n basePath,\n kind,\n pollMs,\n className,\n selectedId,\n onSelectRun,\n}: TaskManagerProps) {\n const [kindFilter, setKindFilter] = useState<string>(kind ?? \"\");\n const [statusFilter, setStatusFilter] = useState<string>(\"\");\n const { runs, status } = useTaskRuns({\n basePath,\n kind: kind ?? (kindFilter || undefined),\n status: statusFilter || undefined,\n pollMs,\n });\n\n const kinds = useMemo(() => {\n const set = new Set<string>();\n for (const r of runs) if (r.kind) set.add(r.kind);\n return [...set].sort();\n }, [runs]);\n\n return (\n <div className={cn(\"space-y-3\", className)}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {!kind && (\n <select\n className=\"rounded-md border bg-background px-2 py-1 text-xs\"\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value)}\n >\n <option value=\"\">All kinds</option>\n {kinds.map((k) => (\n <option key={k} value={k}>\n {k}\n </option>\n ))}\n </select>\n )}\n <select\n className=\"rounded-md border bg-background px-2 py-1 text-xs\"\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value)}\n >\n <option value=\"\">Any status</option>\n <option value=\"running\">Running</option>\n <option value=\"pending\">Pending</option>\n <option value=\"success\">Success</option>\n <option value=\"failed\">Failed</option>\n <option value=\"warning\">Warning</option>\n </select>\n <span className=\"text-xs text-muted-foreground\">{status}</span>\n </div>\n\n {runs.length === 0 ? (\n <div className=\"rounded-lg border border-dashed p-6 text-center text-sm text-muted-foreground\">\n No background tasks.\n </div>\n ) : (\n <div className=\"overflow-hidden rounded-lg border bg-card\">\n {runs.map((run) => (\n <RunRow\n key={run.id}\n run={run}\n basePath={basePath}\n pollMs={pollMs}\n selectedId={selectedId}\n onSelectRun={onSelectRun}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction RunRow({\n run,\n basePath,\n pollMs,\n selectedId,\n onSelectRun,\n}: {\n run: TaskRunMeta;\n basePath: string | undefined;\n pollMs: number | undefined;\n selectedId: string | undefined;\n onSelectRun: ((id: string | null) => void) | undefined;\n}) {\n const [localOpen, setLocalOpen] = useState(false);\n // Controlled by selectedId when a selection handler is wired; otherwise the\n // row owns its expand state (backward compatible for router-less consumers).\n const controlled = onSelectRun !== undefined;\n const open = controlled ? selectedId === run.id : localOpen;\n const toggle = () => {\n if (controlled) onSelectRun(open ? null : run.id);\n else setLocalOpen((v) => !v);\n };\n const isTerminal = run.status !== \"running\" && run.status !== \"pending\";\n\n return (\n <div className=\"border-b last:border-0\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-muted/50\"\n onClick={toggle}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <iconify-icon icon={taskStatusIcon(run.status)} class={taskStatusColor(run.status)} />\n <span className=\"truncate font-medium\">{run.name}</span>\n {run.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {run.kind}\n </span>\n )}\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(run.status),\n taskStatusBg(run.status),\n )}\n >\n {run.status}\n </span>\n )}\n </div>\n <div className=\"mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground\">\n {run.startedAt && <Timestamp value={run.startedAt} format=\"relative\" />}\n <span>\n {run.completed + run.failed}/{run.total} done\n {run.failed > 0 ? `, ${run.failed} failed` : \"\"}\n </span>\n {Object.entries(run.labels ?? {}).map(([k, v]) => (\n <span key={k} className=\"font-mono\">\n {k}={v}\n </span>\n ))}\n </div>\n </div>\n <div className=\"w-40 shrink-0\">\n <ProgressBar\n segments={taskSegments({\n ok: run.completed,\n warn: 0,\n fail: run.failed,\n run: run.running,\n pending: Math.max(0, run.total - run.completed - run.failed - run.running),\n })}\n total={run.total || 1}\n height=\"h-1.5\"\n />\n </div>\n </button>\n {open && <ExpandedRun runId={run.id} basePath={basePath} pollMs={pollMs} />}\n </div>\n );\n}\n\nfunction ExpandedRun({\n runId,\n basePath,\n pollMs,\n}: {\n runId: string;\n basePath: string | undefined;\n pollMs: number | undefined;\n}) {\n const { snapshots } = useTaskRun({ id: runId, basePath, pollMs });\n return (\n <div className=\"border-t bg-muted/30 px-4 py-3\">\n <TaskProgress snapshots={snapshots} compact />\n </div>\n );\n}\n"],"names":["useState","useTaskRuns","useMemo","cn","jsxs","jsx","taskStatusIcon","taskStatusColor","taskStatusBg","Timestamp","ProgressBar","taskSegments","useTaskRun","TaskProgress"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface TaskManagerProps {
2
+ /** Base path of the clicky task API, e.g. "/api/v1". */
3
+ basePath?: string;
4
+ /** Restrict the listing to a single kind (also hides the kind filter). */
5
+ kind?: string;
6
+ pollMs?: number;
7
+ className?: string;
8
+ /**
9
+ * Currently-selected (expanded) run id, e.g. driven from the URL. When set,
10
+ * the matching run renders expanded and selection is controlled — otherwise
11
+ * each row manages its own expand/collapse state.
12
+ */
13
+ selectedId?: string;
14
+ /**
15
+ * Called when a run row is toggled: the new selection id, or null when the
16
+ * open row is collapsed. Pair with selectedId for URL-driven deep links.
17
+ */
18
+ onSelectRun?: (id: string | null) => void;
19
+ }
20
+ export declare function TaskManager({ basePath, kind, pollMs, className, selectedId, onSelectRun, }: TaskManagerProps): import("react/jsx-runtime").JSX.Element;
21
+ //# sourceMappingURL=TaskManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskManager.d.ts","sourceRoot":"","sources":["../../src/data/TaskManager.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,SAAS,EACT,UAAU,EACV,WAAW,GACZ,EAAE,gBAAgB,2CAoElB"}
@@ -0,0 +1,162 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useMemo } from "react";
3
+ import { cn } from "../lib/utils.js";
4
+ import { useTaskRuns, useTaskRun } from "../hooks/use-task-run.js";
5
+ import { ProgressBar } from "./ProgressBar.js";
6
+ import { Timestamp } from "./cells/Timestamp.js";
7
+ import { TaskProgress } from "./TaskProgress.js";
8
+ import { taskStatusColor, taskStatusIcon, taskStatusBg, taskSegments } from "./task-status.js";
9
+ function TaskManager({
10
+ basePath,
11
+ kind,
12
+ pollMs,
13
+ className,
14
+ selectedId,
15
+ onSelectRun
16
+ }) {
17
+ const [kindFilter, setKindFilter] = useState(kind ?? "");
18
+ const [statusFilter, setStatusFilter] = useState("");
19
+ const { runs, status } = useTaskRuns({
20
+ basePath,
21
+ kind: kind ?? (kindFilter || void 0),
22
+ status: statusFilter || void 0,
23
+ pollMs
24
+ });
25
+ const kinds = useMemo(() => {
26
+ const set = /* @__PURE__ */ new Set();
27
+ for (const r of runs) if (r.kind) set.add(r.kind);
28
+ return [...set].sort();
29
+ }, [runs]);
30
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
31
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
32
+ !kind && /* @__PURE__ */ jsxs(
33
+ "select",
34
+ {
35
+ className: "rounded-md border bg-background px-2 py-1 text-xs",
36
+ value: kindFilter,
37
+ onChange: (e) => setKindFilter(e.target.value),
38
+ children: [
39
+ /* @__PURE__ */ jsx("option", { value: "", children: "All kinds" }),
40
+ kinds.map((k) => /* @__PURE__ */ jsx("option", { value: k, children: k }, k))
41
+ ]
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsxs(
45
+ "select",
46
+ {
47
+ className: "rounded-md border bg-background px-2 py-1 text-xs",
48
+ value: statusFilter,
49
+ onChange: (e) => setStatusFilter(e.target.value),
50
+ children: [
51
+ /* @__PURE__ */ jsx("option", { value: "", children: "Any status" }),
52
+ /* @__PURE__ */ jsx("option", { value: "running", children: "Running" }),
53
+ /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
54
+ /* @__PURE__ */ jsx("option", { value: "success", children: "Success" }),
55
+ /* @__PURE__ */ jsx("option", { value: "failed", children: "Failed" }),
56
+ /* @__PURE__ */ jsx("option", { value: "warning", children: "Warning" })
57
+ ]
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: status })
61
+ ] }),
62
+ runs.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed p-6 text-center text-sm text-muted-foreground", children: "No background tasks." }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border bg-card", children: runs.map((run) => /* @__PURE__ */ jsx(
63
+ RunRow,
64
+ {
65
+ run,
66
+ basePath,
67
+ pollMs,
68
+ selectedId,
69
+ onSelectRun
70
+ },
71
+ run.id
72
+ )) })
73
+ ] });
74
+ }
75
+ function RunRow({
76
+ run,
77
+ basePath,
78
+ pollMs,
79
+ selectedId,
80
+ onSelectRun
81
+ }) {
82
+ const [localOpen, setLocalOpen] = useState(false);
83
+ const controlled = onSelectRun !== void 0;
84
+ const open = controlled ? selectedId === run.id : localOpen;
85
+ const toggle = () => {
86
+ if (controlled) onSelectRun(open ? null : run.id);
87
+ else setLocalOpen((v) => !v);
88
+ };
89
+ const isTerminal = run.status !== "running" && run.status !== "pending";
90
+ return /* @__PURE__ */ jsxs("div", { className: "border-b last:border-0", children: [
91
+ /* @__PURE__ */ jsxs(
92
+ "button",
93
+ {
94
+ type: "button",
95
+ className: "flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-muted/50",
96
+ onClick: toggle,
97
+ children: [
98
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
99
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
100
+ /* @__PURE__ */ jsx("iconify-icon", { icon: taskStatusIcon(run.status), class: taskStatusColor(run.status) }),
101
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: run.name }),
102
+ run.kind && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground", children: run.kind }),
103
+ isTerminal && /* @__PURE__ */ jsx(
104
+ "span",
105
+ {
106
+ className: cn(
107
+ "rounded-full px-2 py-0.5 text-xs",
108
+ taskStatusColor(run.status),
109
+ taskStatusBg(run.status)
110
+ ),
111
+ children: run.status
112
+ }
113
+ )
114
+ ] }),
115
+ /* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground", children: [
116
+ run.startedAt && /* @__PURE__ */ jsx(Timestamp, { value: run.startedAt, format: "relative" }),
117
+ /* @__PURE__ */ jsxs("span", { children: [
118
+ run.completed + run.failed,
119
+ "/",
120
+ run.total,
121
+ " done",
122
+ run.failed > 0 ? `, ${run.failed} failed` : ""
123
+ ] }),
124
+ Object.entries(run.labels ?? {}).map(([k, v]) => /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
125
+ k,
126
+ "=",
127
+ v
128
+ ] }, k))
129
+ ] })
130
+ ] }),
131
+ /* @__PURE__ */ jsx("div", { className: "w-40 shrink-0", children: /* @__PURE__ */ jsx(
132
+ ProgressBar,
133
+ {
134
+ segments: taskSegments({
135
+ ok: run.completed,
136
+ warn: 0,
137
+ fail: run.failed,
138
+ run: run.running,
139
+ pending: Math.max(0, run.total - run.completed - run.failed - run.running)
140
+ }),
141
+ total: run.total || 1,
142
+ height: "h-1.5"
143
+ }
144
+ ) })
145
+ ]
146
+ }
147
+ ),
148
+ open && /* @__PURE__ */ jsx(ExpandedRun, { runId: run.id, basePath, pollMs })
149
+ ] });
150
+ }
151
+ function ExpandedRun({
152
+ runId,
153
+ basePath,
154
+ pollMs
155
+ }) {
156
+ const { snapshots } = useTaskRun({ id: runId, basePath, pollMs });
157
+ return /* @__PURE__ */ jsx("div", { className: "border-t bg-muted/30 px-4 py-3", children: /* @__PURE__ */ jsx(TaskProgress, { snapshots, compact: true }) });
158
+ }
159
+ export {
160
+ TaskManager
161
+ };
162
+ //# sourceMappingURL=TaskManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskManager.js","sources":["../../src/data/TaskManager.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useTaskRun, useTaskRuns } from \"../hooks/use-task-run\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport { TaskProgress } from \"./TaskProgress\";\nimport type { TaskRunMeta } from \"./TaskSnapshot\";\nimport { taskSegments, taskStatusBg, taskStatusColor, taskStatusIcon } from \"./task-status\";\n\n// TaskManager is the generic clicky-ui task-manager view: it lists every run\n// (TaskRunMeta) from GET {basePath}/tasks with kind/status filters, and expands\n// each row into a live <TaskProgress> for that run id. Fully generic — no\n// application concepts.\n\nexport interface TaskManagerProps {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string;\n /** Restrict the listing to a single kind (also hides the kind filter). */\n kind?: string;\n pollMs?: number;\n className?: string;\n /**\n * Currently-selected (expanded) run id, e.g. driven from the URL. When set,\n * the matching run renders expanded and selection is controlled — otherwise\n * each row manages its own expand/collapse state.\n */\n selectedId?: string;\n /**\n * Called when a run row is toggled: the new selection id, or null when the\n * open row is collapsed. Pair with selectedId for URL-driven deep links.\n */\n onSelectRun?: (id: string | null) => void;\n}\n\nexport function TaskManager({\n basePath,\n kind,\n pollMs,\n className,\n selectedId,\n onSelectRun,\n}: TaskManagerProps) {\n const [kindFilter, setKindFilter] = useState<string>(kind ?? \"\");\n const [statusFilter, setStatusFilter] = useState<string>(\"\");\n const { runs, status } = useTaskRuns({\n basePath,\n kind: kind ?? (kindFilter || undefined),\n status: statusFilter || undefined,\n pollMs,\n });\n\n const kinds = useMemo(() => {\n const set = new Set<string>();\n for (const r of runs) if (r.kind) set.add(r.kind);\n return [...set].sort();\n }, [runs]);\n\n return (\n <div className={cn(\"space-y-3\", className)}>\n <div className=\"flex flex-wrap items-center gap-2\">\n {!kind && (\n <select\n className=\"rounded-md border bg-background px-2 py-1 text-xs\"\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value)}\n >\n <option value=\"\">All kinds</option>\n {kinds.map((k) => (\n <option key={k} value={k}>\n {k}\n </option>\n ))}\n </select>\n )}\n <select\n className=\"rounded-md border bg-background px-2 py-1 text-xs\"\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value)}\n >\n <option value=\"\">Any status</option>\n <option value=\"running\">Running</option>\n <option value=\"pending\">Pending</option>\n <option value=\"success\">Success</option>\n <option value=\"failed\">Failed</option>\n <option value=\"warning\">Warning</option>\n </select>\n <span className=\"text-xs text-muted-foreground\">{status}</span>\n </div>\n\n {runs.length === 0 ? (\n <div className=\"rounded-lg border border-dashed p-6 text-center text-sm text-muted-foreground\">\n No background tasks.\n </div>\n ) : (\n <div className=\"overflow-hidden rounded-lg border bg-card\">\n {runs.map((run) => (\n <RunRow\n key={run.id}\n run={run}\n basePath={basePath}\n pollMs={pollMs}\n selectedId={selectedId}\n onSelectRun={onSelectRun}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction RunRow({\n run,\n basePath,\n pollMs,\n selectedId,\n onSelectRun,\n}: {\n run: TaskRunMeta;\n basePath: string | undefined;\n pollMs: number | undefined;\n selectedId: string | undefined;\n onSelectRun: ((id: string | null) => void) | undefined;\n}) {\n const [localOpen, setLocalOpen] = useState(false);\n // Controlled by selectedId when a selection handler is wired; otherwise the\n // row owns its expand state (backward compatible for router-less consumers).\n const controlled = onSelectRun !== undefined;\n const open = controlled ? selectedId === run.id : localOpen;\n const toggle = () => {\n if (controlled) onSelectRun(open ? null : run.id);\n else setLocalOpen((v) => !v);\n };\n const isTerminal = run.status !== \"running\" && run.status !== \"pending\";\n\n return (\n <div className=\"border-b last:border-0\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-4 px-4 py-3 text-left hover:bg-muted/50\"\n onClick={toggle}\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <iconify-icon icon={taskStatusIcon(run.status)} class={taskStatusColor(run.status)} />\n <span className=\"truncate font-medium\">{run.name}</span>\n {run.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {run.kind}\n </span>\n )}\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(run.status),\n taskStatusBg(run.status),\n )}\n >\n {run.status}\n </span>\n )}\n </div>\n <div className=\"mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground\">\n {run.startedAt && <Timestamp value={run.startedAt} format=\"relative\" />}\n <span>\n {run.completed + run.failed}/{run.total} done\n {run.failed > 0 ? `, ${run.failed} failed` : \"\"}\n </span>\n {Object.entries(run.labels ?? {}).map(([k, v]) => (\n <span key={k} className=\"font-mono\">\n {k}={v}\n </span>\n ))}\n </div>\n </div>\n <div className=\"w-40 shrink-0\">\n <ProgressBar\n segments={taskSegments({\n ok: run.completed,\n warn: 0,\n fail: run.failed,\n run: run.running,\n pending: Math.max(0, run.total - run.completed - run.failed - run.running),\n })}\n total={run.total || 1}\n height=\"h-1.5\"\n />\n </div>\n </button>\n {open && <ExpandedRun runId={run.id} basePath={basePath} pollMs={pollMs} />}\n </div>\n );\n}\n\nfunction ExpandedRun({\n runId,\n basePath,\n pollMs,\n}: {\n runId: string;\n basePath: string | undefined;\n pollMs: number | undefined;\n}) {\n const { snapshots } = useTaskRun({ id: runId, basePath, pollMs });\n return (\n <div className=\"border-t bg-muted/30 px-4 py-3\">\n <TaskProgress snapshots={snapshots} compact />\n </div>\n );\n}\n"],"names":[],"mappings":"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"}