@flanksource/clicky-ui 0.2.4 → 0.2.6
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/components/Combobox.cjs +291 -0
- package/dist/components/Combobox.cjs.map +1 -0
- package/dist/components/Combobox.d.ts +59 -0
- package/dist/components/Combobox.d.ts.map +1 -0
- package/dist/components/Combobox.js +291 -0
- package/dist/components/Combobox.js.map +1 -0
- package/dist/components/FilterBar.cjs +153 -124
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +25 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +153 -124
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/FormatOptionsDropdown.cjs +62 -0
- package/dist/components/FormatOptionsDropdown.cjs.map +1 -0
- package/dist/components/FormatOptionsDropdown.d.ts +37 -0
- package/dist/components/FormatOptionsDropdown.d.ts.map +1 -0
- package/dist/components/FormatOptionsDropdown.js +62 -0
- package/dist/components/FormatOptionsDropdown.js.map +1 -0
- package/dist/components/SplitButton.cjs +87 -0
- package/dist/components/SplitButton.cjs.map +1 -0
- package/dist/components/SplitButton.d.ts +32 -0
- package/dist/components/SplitButton.d.ts.map +1 -0
- package/dist/components/SplitButton.js +87 -0
- package/dist/components/SplitButton.js.map +1 -0
- package/dist/components/icon-menu-picker.cjs +1 -1
- package/dist/components/icon-menu-picker.cjs.map +1 -1
- package/dist/components/icon-menu-picker.js +1 -1
- package/dist/components/icon-menu-picker.js.map +1 -1
- package/dist/components.cjs +7 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +7 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Badge.d.ts +1 -1
- package/dist/data/ProgressBar.cjs +4 -2
- package/dist/data/ProgressBar.cjs.map +1 -1
- package/dist/data/ProgressBar.d.ts +1 -1
- package/dist/data/ProgressBar.d.ts.map +1 -1
- package/dist/data/ProgressBar.js +4 -2
- package/dist/data/ProgressBar.js.map +1 -1
- package/dist/data/StatusBreakdown.cjs +80 -0
- package/dist/data/StatusBreakdown.cjs.map +1 -0
- package/dist/data/StatusBreakdown.d.ts +36 -0
- package/dist/data/StatusBreakdown.d.ts.map +1 -0
- package/dist/data/StatusBreakdown.js +80 -0
- package/dist/data/StatusBreakdown.js.map +1 -0
- package/dist/data/TaskManager.cjs +162 -0
- package/dist/data/TaskManager.cjs.map +1 -0
- package/dist/data/TaskManager.d.ts +21 -0
- package/dist/data/TaskManager.d.ts.map +1 -0
- package/dist/data/TaskManager.js +162 -0
- package/dist/data/TaskManager.js.map +1 -0
- package/dist/data/TaskProgress.cjs +125 -0
- package/dist/data/TaskProgress.cjs.map +1 -0
- package/dist/data/TaskProgress.d.ts +20 -0
- package/dist/data/TaskProgress.d.ts.map +1 -0
- package/dist/data/TaskProgress.js +125 -0
- package/dist/data/TaskProgress.js.map +1 -0
- package/dist/data/TaskSnapshot.cjs +23 -0
- package/dist/data/TaskSnapshot.cjs.map +1 -0
- package/dist/data/TaskSnapshot.d.ts +49 -0
- package/dist/data/TaskSnapshot.d.ts.map +1 -0
- package/dist/data/TaskSnapshot.js +23 -0
- package/dist/data/TaskSnapshot.js.map +1 -0
- package/dist/data/TimeseriesGauge.cjs +144 -0
- package/dist/data/TimeseriesGauge.cjs.map +1 -0
- package/dist/data/TimeseriesGauge.d.ts +56 -0
- package/dist/data/TimeseriesGauge.d.ts.map +1 -0
- package/dist/data/TimeseriesGauge.js +144 -0
- package/dist/data/TimeseriesGauge.js.map +1 -0
- package/dist/data/TimeseriesPanel.axes.cjs +39 -0
- package/dist/data/TimeseriesPanel.axes.cjs.map +1 -0
- package/dist/data/TimeseriesPanel.axes.d.ts +28 -0
- package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -0
- package/dist/data/TimeseriesPanel.axes.js +39 -0
- package/dist/data/TimeseriesPanel.axes.js.map +1 -0
- package/dist/data/TimeseriesPanel.cjs +324 -0
- package/dist/data/TimeseriesPanel.cjs.map +1 -0
- package/dist/data/TimeseriesPanel.d.ts +141 -0
- package/dist/data/TimeseriesPanel.d.ts.map +1 -0
- package/dist/data/TimeseriesPanel.js +324 -0
- package/dist/data/TimeseriesPanel.js.map +1 -0
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/TreeNode.cjs +44 -7
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts +19 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +44 -7
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +66 -44
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +21 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +65 -43
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs +2 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.js +2 -1
- package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +37 -0
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -0
- package/dist/data/diagnostics/FrameSourceWindow.d.ts +15 -0
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -0
- package/dist/data/diagnostics/FrameSourceWindow.js +37 -0
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -0
- package/dist/data/diagnostics/JvmStackTrace.cjs +25 -12
- package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.d.ts +8 -1
- package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
- package/dist/data/diagnostics/JvmStackTrace.js +26 -13
- package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
- package/dist/data/diagnostics/ThreadCard.cjs +9 -2
- package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
- package/dist/data/diagnostics/ThreadCard.d.ts +3 -1
- package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
- package/dist/data/diagnostics/ThreadCard.js +9 -2
- package/dist/data/diagnostics/ThreadCard.js.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.cjs +10 -1
- package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/jvm-stacktrace.js +10 -1
- package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
- package/dist/data/diagnostics/utils.cjs +0 -12
- package/dist/data/diagnostics/utils.cjs.map +1 -1
- package/dist/data/diagnostics/utils.d.ts +1 -1
- package/dist/data/diagnostics/utils.d.ts.map +1 -1
- package/dist/data/diagnostics/utils.js +0 -12
- package/dist/data/diagnostics/utils.js.map +1 -1
- package/dist/data/task-status.cjs +108 -0
- package/dist/data/task-status.cjs.map +1 -0
- package/dist/data/task-status.d.ts +21 -0
- package/dist/data/task-status.d.ts.map +1 -0
- package/dist/data/task-status.js +108 -0
- package/dist/data/task-status.js.map +1 -0
- package/dist/data.cjs +27 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +9 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +27 -0
- package/dist/data.js.map +1 -1
- package/dist/hooks/use-task-run.cjs +137 -0
- package/dist/hooks/use-task-run.cjs.map +1 -0
- package/dist/hooks/use-task-run.d.ts +35 -0
- package/dist/hooks/use-task-run.d.ts.map +1 -0
- package/dist/hooks/use-task-run.js +137 -0
- package/dist/hooks/use-task-run.js.map +1 -0
- package/dist/hooks.cjs +3 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +3 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +43 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/color.cjs +33 -0
- package/dist/lib/color.cjs.map +1 -0
- package/dist/lib/color.d.ts +10 -0
- package/dist/lib/color.d.ts.map +1 -0
- package/dist/lib/color.js +33 -0
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/format.cjs +77 -0
- package/dist/lib/format.cjs.map +1 -0
- package/dist/lib/format.d.ts +30 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +77 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/overlay/DropdownMenu.cjs +18 -2
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +3 -1
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +18 -2
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +4 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils.cjs +6 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +6 -0
- package/dist/utils.js.map +1 -1
- package/package.json +4 -1
package/dist/components.d.ts
CHANGED
|
@@ -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';
|
package/dist/components.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/components.js
CHANGED
|
@@ -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,
|
package/dist/components.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
|
package/dist/data/Badge.d.ts
CHANGED
|
@@ -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?: "
|
|
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
|
|
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
|
|
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":"
|
|
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"}
|
package/dist/data/ProgressBar.js
CHANGED
|
@@ -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
|
|
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,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
require("react");
|
|
5
|
+
const utils = require("../lib/utils.cjs");
|
|
6
|
+
const button = require("../components/button.cjs");
|
|
7
|
+
function segment(key, label, count, className) {
|
|
8
|
+
return { key, label, count: Math.max(0, count || 0), className };
|
|
9
|
+
}
|
|
10
|
+
const defaultRenderLink = ({ to, className, title, children }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href: to, className, title, children });
|
|
11
|
+
function StackedStatusBar({
|
|
12
|
+
segments,
|
|
13
|
+
ariaLabel
|
|
14
|
+
}) {
|
|
15
|
+
const visible = segments.filter((s) => s.count > 0);
|
|
16
|
+
const total = visible.reduce((sum, s) => sum + s.count, 0);
|
|
17
|
+
if (visible.length === 0 || total <= 0) {
|
|
18
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded border border-dashed p-3 text-xs text-muted-foreground", children: "No status data" });
|
|
19
|
+
}
|
|
20
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-2 overflow-hidden rounded bg-muted", "aria-label": ariaLabel, children: visible.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
+
"div",
|
|
22
|
+
{
|
|
23
|
+
className: s.className,
|
|
24
|
+
title: `${s.label}: ${s.count}`,
|
|
25
|
+
style: { width: `${Math.max(1, s.count / total * 100)}%` }
|
|
26
|
+
},
|
|
27
|
+
s.key
|
|
28
|
+
)) });
|
|
29
|
+
}
|
|
30
|
+
function StatusRows({
|
|
31
|
+
segments,
|
|
32
|
+
ariaLabel,
|
|
33
|
+
onRetry,
|
|
34
|
+
retryingKey,
|
|
35
|
+
isRetryable,
|
|
36
|
+
renderLink = defaultRenderLink
|
|
37
|
+
}) {
|
|
38
|
+
const visible = segments.filter((s) => s.count > 0);
|
|
39
|
+
const total = visible.reduce((sum, s) => sum + s.count, 0);
|
|
40
|
+
if (visible.length === 0 || total <= 0) {
|
|
41
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded border border-dashed p-3 text-xs text-muted-foreground", children: "No status data" });
|
|
42
|
+
}
|
|
43
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", "aria-label": ariaLabel, children: visible.map((s) => {
|
|
44
|
+
const retryable = !!onRetry && ((isRetryable == null ? void 0 : isRetryable(s)) ?? false);
|
|
45
|
+
const meta = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
46
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("h-2.5 w-2.5 shrink-0 rounded-sm", s.className), "aria-hidden": "true" }),
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: s.label }),
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0 font-mono text-xs text-muted-foreground", children: s.count })
|
|
49
|
+
] });
|
|
50
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
51
|
+
s.href ? renderLink({
|
|
52
|
+
to: s.href,
|
|
53
|
+
className: "flex min-w-0 flex-1 rounded hover:bg-accent/40",
|
|
54
|
+
title: `View ${s.label} records`,
|
|
55
|
+
children: meta
|
|
56
|
+
}) : meta,
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-32 shrink-0 overflow-hidden rounded bg-muted sm:w-48", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("h-full", s.className), style: { width: `${Math.max(1, s.count / total * 100)}%` } }) }),
|
|
58
|
+
retryable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
59
|
+
button.Button,
|
|
60
|
+
{
|
|
61
|
+
type: "button",
|
|
62
|
+
variant: "outline",
|
|
63
|
+
size: "sm",
|
|
64
|
+
className: "h-6 shrink-0 px-2 text-[11px]",
|
|
65
|
+
disabled: retryingKey === s.key,
|
|
66
|
+
onClick: (e) => {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
e.stopPropagation();
|
|
69
|
+
onRetry == null ? void 0 : onRetry(s);
|
|
70
|
+
},
|
|
71
|
+
children: retryingKey === s.key ? "Retrying…" : "Retry"
|
|
72
|
+
}
|
|
73
|
+
) : null
|
|
74
|
+
] }, s.key);
|
|
75
|
+
}) });
|
|
76
|
+
}
|
|
77
|
+
exports.StackedStatusBar = StackedStatusBar;
|
|
78
|
+
exports.StatusRows = StatusRows;
|
|
79
|
+
exports.segment = segment;
|
|
80
|
+
//# sourceMappingURL=StatusBreakdown.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBreakdown.cjs","sources":["../../src/data/StatusBreakdown.tsx"],"sourcesContent":["import { type ReactElement, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\n\n// A status-breakdown family: one StatusSegment list rendered either as a single\n// horizontal StackedStatusBar (scan a mix at a glance) or as vertical StatusRows\n// (each status on its own line with a proportional bar, optional drill-down link\n// and retry). Shared by monitor/intake/cycle breakdowns and any panel that shows\n// a count mix.\n\nexport interface StatusSegment {\n key: string;\n label: string;\n count: number;\n /** Tailwind background class for the swatch/bar fill, e.g. \"bg-green-500\". */\n className: string;\n /**\n * When set, the row links here (the breakdown points each status at its\n * filtered records/members view). Rendered via the `renderLink` prop so the\n * component stays router-agnostic.\n */\n href?: string;\n}\n\n/** Builds a StatusSegment, clamping the count to a non-negative integer. */\nexport function segment(key: string, label: string, count: number, className: string): StatusSegment {\n return { key, label, count: Math.max(0, count || 0), className };\n}\n\n/** Render-prop for a status row's link, so callers supply their router's Link (or a plain <a>). */\nexport type StatusRenderLink = (args: {\n to: string;\n className?: string;\n title?: string;\n children: ReactNode;\n}) => ReactElement;\n\nconst defaultRenderLink: StatusRenderLink = ({ to, className, title, children }) => (\n <a href={to} className={className} title={title}>\n {children}\n </a>\n);\n\n// StackedStatusBar renders the segments as a single horizontal multi-color bar —\n// segments share one track sized proportionally to the visible-segment total.\nexport function StackedStatusBar({\n segments,\n ariaLabel,\n}: {\n segments: StatusSegment[];\n ariaLabel?: string;\n}) {\n const visible = segments.filter((s) => s.count > 0);\n const total = visible.reduce((sum, s) => sum + s.count, 0);\n if (visible.length === 0 || total <= 0) {\n return <div className=\"rounded border border-dashed p-3 text-xs text-muted-foreground\">No status data</div>;\n }\n return (\n <div className=\"flex h-2 overflow-hidden rounded bg-muted\" aria-label={ariaLabel}>\n {visible.map((s) => (\n <div\n key={s.key}\n className={s.className}\n title={`${s.label}: ${s.count}`}\n style={{ width: `${Math.max(1, (s.count / total) * 100)}%` }}\n />\n ))}\n </div>\n );\n}\n\n// StatusRows renders each status as its own row — a colored swatch + label, the\n// count, and a horizontal bar sized proportionally to the visible-segment total.\n// The vertical counterpart to StackedStatusBar. An optional onRetry surfaces a\n// Retry button per row; callers that omit it get no button. When a segment\n// carries an href the whole row links there via renderLink (defaults to a plain\n// <a>); the Retry button stops propagation so it stays independently clickable.\nexport function StatusRows({\n segments,\n ariaLabel,\n onRetry,\n retryingKey,\n isRetryable,\n renderLink = defaultRenderLink,\n}: {\n segments: StatusSegment[];\n ariaLabel?: string;\n onRetry?: (segment: StatusSegment) => void;\n retryingKey?: string;\n isRetryable?: (segment: StatusSegment) => boolean;\n renderLink?: StatusRenderLink;\n}) {\n const visible = segments.filter((s) => s.count > 0);\n const total = visible.reduce((sum, s) => sum + s.count, 0);\n if (visible.length === 0 || total <= 0) {\n return <div className=\"rounded border border-dashed p-3 text-xs text-muted-foreground\">No status data</div>;\n }\n return (\n <div className=\"space-y-2\" aria-label={ariaLabel}>\n {visible.map((s) => {\n const retryable = !!onRetry && (isRetryable?.(s) ?? false);\n const meta = (\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className={cn(\"h-2.5 w-2.5 shrink-0 rounded-sm\", s.className)} aria-hidden=\"true\" />\n <span className=\"truncate text-xs\">{s.label}</span>\n <span className=\"ml-auto shrink-0 font-mono text-xs text-muted-foreground\">{s.count}</span>\n </div>\n );\n return (\n <div key={s.key} className=\"flex items-center gap-3\">\n {s.href\n ? renderLink({\n to: s.href,\n className: \"flex min-w-0 flex-1 rounded hover:bg-accent/40\",\n title: `View ${s.label} records`,\n children: meta,\n })\n : meta}\n <div className=\"h-2 w-32 shrink-0 overflow-hidden rounded bg-muted sm:w-48\">\n <div className={cn(\"h-full\", s.className)} style={{ width: `${Math.max(1, (s.count / total) * 100)}%` }} />\n </div>\n {retryable ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-[11px]\"\n disabled={retryingKey === s.key}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onRetry?.(s);\n }}\n >\n {retryingKey === s.key ? \"Retrying…\" : \"Retry\"}\n </Button>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["jsx","jsxs","cn","Button"],"mappings":";;;;;;AAyBO,SAAS,QAAQ,KAAa,OAAe,OAAe,WAAkC;AACnG,SAAO,EAAE,KAAK,OAAO,OAAO,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG,UAAA;AACvD;AAUA,MAAM,oBAAsC,CAAC,EAAE,IAAI,WAAW,OAAO,SAAA,MACnEA,2BAAAA,IAAC,KAAA,EAAE,MAAM,IAAI,WAAsB,OAChC,SAAA,CACH;AAKK,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GAGG;AACD,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AAClD,QAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AACzD,MAAI,QAAQ,WAAW,KAAK,SAAS,GAAG;AACtC,WAAOA,2BAAAA,IAAC,OAAA,EAAI,WAAU,kEAAiE,UAAA,kBAAc;AAAA,EACvG;AACA,SACEA,+BAAC,SAAI,WAAU,6CAA4C,cAAY,WACpE,UAAA,QAAQ,IAAI,CAAC,MACZA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MAEC,WAAW,EAAE;AAAA,MACb,OAAO,GAAG,EAAE,KAAK,KAAK,EAAE,KAAK;AAAA,MAC7B,OAAO,EAAE,OAAO,GAAG,KAAK,IAAI,GAAI,EAAE,QAAQ,QAAS,GAAG,CAAC,IAAA;AAAA,IAAI;AAAA,IAHtD,EAAE;AAAA,EAAA,CAKV,GACH;AAEJ;AAQO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAOG;AACD,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AAClD,QAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AACzD,MAAI,QAAQ,WAAW,KAAK,SAAS,GAAG;AACtC,WAAOA,2BAAAA,IAAC,OAAA,EAAI,WAAU,kEAAiE,UAAA,kBAAc;AAAA,EACvG;AACA,SACEA,+BAAC,SAAI,WAAU,aAAY,cAAY,WACpC,UAAA,QAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,YAAY,CAAC,CAAC,aAAY,2CAAc,OAAM;AACpD,UAAM,OACJC,2BAAAA,KAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAAD,2BAAAA,IAAC,QAAA,EAAK,WAAWE,SAAG,mCAAmC,EAAE,SAAS,GAAG,eAAY,QAAO;AAAA,MACxFF,2BAAAA,IAAC,QAAA,EAAK,WAAU,oBAAoB,YAAE,OAAM;AAAA,MAC5CA,2BAAAA,IAAC,QAAA,EAAK,WAAU,4DAA4D,YAAE,MAAA,CAAM;AAAA,IAAA,GACtF;AAEF,WACEC,2BAAAA,KAAC,OAAA,EAAgB,WAAU,2BACxB,UAAA;AAAA,MAAA,EAAE,OACC,WAAW;AAAA,QACT,IAAI,EAAE;AAAA,QACN,WAAW;AAAA,QACX,OAAO,QAAQ,EAAE,KAAK;AAAA,QACtB,UAAU;AAAA,MAAA,CACX,IACD;AAAA,MACJD,2BAAAA,IAAC,OAAA,EAAI,WAAU,8DACb,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAWE,MAAAA,GAAG,UAAU,EAAE,SAAS,GAAG,OAAO,EAAE,OAAO,GAAG,KAAK,IAAI,GAAI,EAAE,QAAQ,QAAS,GAAG,CAAC,IAAA,EAAI,CAAG,EAAA,CAC3G;AAAA,MACC,YACCF,2BAAAA;AAAAA,QAACG,OAAAA;AAAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,gBAAgB,EAAE;AAAA,UAC5B,SAAS,CAAC,MAAM;AACd,cAAE,eAAA;AACF,cAAE,gBAAA;AACF,+CAAU;AAAA,UACZ;AAAA,UAEC,UAAA,gBAAgB,EAAE,MAAM,cAAc;AAAA,QAAA;AAAA,MAAA,IAEvC;AAAA,IAAA,EAAA,GA3BI,EAAE,GA4BZ;AAAA,EAEJ,CAAC,EAAA,CACH;AAEJ;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface StatusSegment {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
count: number;
|
|
6
|
+
/** Tailwind background class for the swatch/bar fill, e.g. "bg-green-500". */
|
|
7
|
+
className: string;
|
|
8
|
+
/**
|
|
9
|
+
* When set, the row links here (the breakdown points each status at its
|
|
10
|
+
* filtered records/members view). Rendered via the `renderLink` prop so the
|
|
11
|
+
* component stays router-agnostic.
|
|
12
|
+
*/
|
|
13
|
+
href?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Builds a StatusSegment, clamping the count to a non-negative integer. */
|
|
16
|
+
export declare function segment(key: string, label: string, count: number, className: string): StatusSegment;
|
|
17
|
+
/** Render-prop for a status row's link, so callers supply their router's Link (or a plain <a>). */
|
|
18
|
+
export type StatusRenderLink = (args: {
|
|
19
|
+
to: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}) => ReactElement;
|
|
24
|
+
export declare function StackedStatusBar({ segments, ariaLabel, }: {
|
|
25
|
+
segments: StatusSegment[];
|
|
26
|
+
ariaLabel?: string;
|
|
27
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function StatusRows({ segments, ariaLabel, onRetry, retryingKey, isRetryable, renderLink, }: {
|
|
29
|
+
segments: StatusSegment[];
|
|
30
|
+
ariaLabel?: string;
|
|
31
|
+
onRetry?: (segment: StatusSegment) => void;
|
|
32
|
+
retryingKey?: string;
|
|
33
|
+
isRetryable?: (segment: StatusSegment) => boolean;
|
|
34
|
+
renderLink?: StatusRenderLink;
|
|
35
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=StatusBreakdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBreakdown.d.ts","sourceRoot":"","sources":["../../src/data/StatusBreakdown.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAU1D,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CAEnG;AAED,mGAAmG;AACnG,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB,KAAK,YAAY,CAAC;AAUnB,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAkBA;AAQD,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,WAAW,EACX,WAAW,EACX,UAA8B,GAC/B,EAAE;IACD,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC;IAClD,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,2CAmDA"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Button } from "../components/button.js";
|
|
5
|
+
function segment(key, label, count, className) {
|
|
6
|
+
return { key, label, count: Math.max(0, count || 0), className };
|
|
7
|
+
}
|
|
8
|
+
const defaultRenderLink = ({ to, className, title, children }) => /* @__PURE__ */ jsx("a", { href: to, className, title, children });
|
|
9
|
+
function StackedStatusBar({
|
|
10
|
+
segments,
|
|
11
|
+
ariaLabel
|
|
12
|
+
}) {
|
|
13
|
+
const visible = segments.filter((s) => s.count > 0);
|
|
14
|
+
const total = visible.reduce((sum, s) => sum + s.count, 0);
|
|
15
|
+
if (visible.length === 0 || total <= 0) {
|
|
16
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded border border-dashed p-3 text-xs text-muted-foreground", children: "No status data" });
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-2 overflow-hidden rounded bg-muted", "aria-label": ariaLabel, children: visible.map((s) => /* @__PURE__ */ jsx(
|
|
19
|
+
"div",
|
|
20
|
+
{
|
|
21
|
+
className: s.className,
|
|
22
|
+
title: `${s.label}: ${s.count}`,
|
|
23
|
+
style: { width: `${Math.max(1, s.count / total * 100)}%` }
|
|
24
|
+
},
|
|
25
|
+
s.key
|
|
26
|
+
)) });
|
|
27
|
+
}
|
|
28
|
+
function StatusRows({
|
|
29
|
+
segments,
|
|
30
|
+
ariaLabel,
|
|
31
|
+
onRetry,
|
|
32
|
+
retryingKey,
|
|
33
|
+
isRetryable,
|
|
34
|
+
renderLink = defaultRenderLink
|
|
35
|
+
}) {
|
|
36
|
+
const visible = segments.filter((s) => s.count > 0);
|
|
37
|
+
const total = visible.reduce((sum, s) => sum + s.count, 0);
|
|
38
|
+
if (visible.length === 0 || total <= 0) {
|
|
39
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded border border-dashed p-3 text-xs text-muted-foreground", children: "No status data" });
|
|
40
|
+
}
|
|
41
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-2", "aria-label": ariaLabel, children: visible.map((s) => {
|
|
42
|
+
const retryable = !!onRetry && ((isRetryable == null ? void 0 : isRetryable(s)) ?? false);
|
|
43
|
+
const meta = /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
44
|
+
/* @__PURE__ */ jsx("span", { className: cn("h-2.5 w-2.5 shrink-0 rounded-sm", s.className), "aria-hidden": "true" }),
|
|
45
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: s.label }),
|
|
46
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 font-mono text-xs text-muted-foreground", children: s.count })
|
|
47
|
+
] });
|
|
48
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
49
|
+
s.href ? renderLink({
|
|
50
|
+
to: s.href,
|
|
51
|
+
className: "flex min-w-0 flex-1 rounded hover:bg-accent/40",
|
|
52
|
+
title: `View ${s.label} records`,
|
|
53
|
+
children: meta
|
|
54
|
+
}) : meta,
|
|
55
|
+
/* @__PURE__ */ jsx("div", { className: "h-2 w-32 shrink-0 overflow-hidden rounded bg-muted sm:w-48", children: /* @__PURE__ */ jsx("div", { className: cn("h-full", s.className), style: { width: `${Math.max(1, s.count / total * 100)}%` } }) }),
|
|
56
|
+
retryable ? /* @__PURE__ */ jsx(
|
|
57
|
+
Button,
|
|
58
|
+
{
|
|
59
|
+
type: "button",
|
|
60
|
+
variant: "outline",
|
|
61
|
+
size: "sm",
|
|
62
|
+
className: "h-6 shrink-0 px-2 text-[11px]",
|
|
63
|
+
disabled: retryingKey === s.key,
|
|
64
|
+
onClick: (e) => {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
e.stopPropagation();
|
|
67
|
+
onRetry == null ? void 0 : onRetry(s);
|
|
68
|
+
},
|
|
69
|
+
children: retryingKey === s.key ? "Retrying…" : "Retry"
|
|
70
|
+
}
|
|
71
|
+
) : null
|
|
72
|
+
] }, s.key);
|
|
73
|
+
}) });
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
StackedStatusBar,
|
|
77
|
+
StatusRows,
|
|
78
|
+
segment
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=StatusBreakdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBreakdown.js","sources":["../../src/data/StatusBreakdown.tsx"],"sourcesContent":["import { type ReactElement, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\n\n// A status-breakdown family: one StatusSegment list rendered either as a single\n// horizontal StackedStatusBar (scan a mix at a glance) or as vertical StatusRows\n// (each status on its own line with a proportional bar, optional drill-down link\n// and retry). Shared by monitor/intake/cycle breakdowns and any panel that shows\n// a count mix.\n\nexport interface StatusSegment {\n key: string;\n label: string;\n count: number;\n /** Tailwind background class for the swatch/bar fill, e.g. \"bg-green-500\". */\n className: string;\n /**\n * When set, the row links here (the breakdown points each status at its\n * filtered records/members view). Rendered via the `renderLink` prop so the\n * component stays router-agnostic.\n */\n href?: string;\n}\n\n/** Builds a StatusSegment, clamping the count to a non-negative integer. */\nexport function segment(key: string, label: string, count: number, className: string): StatusSegment {\n return { key, label, count: Math.max(0, count || 0), className };\n}\n\n/** Render-prop for a status row's link, so callers supply their router's Link (or a plain <a>). */\nexport type StatusRenderLink = (args: {\n to: string;\n className?: string;\n title?: string;\n children: ReactNode;\n}) => ReactElement;\n\nconst defaultRenderLink: StatusRenderLink = ({ to, className, title, children }) => (\n <a href={to} className={className} title={title}>\n {children}\n </a>\n);\n\n// StackedStatusBar renders the segments as a single horizontal multi-color bar —\n// segments share one track sized proportionally to the visible-segment total.\nexport function StackedStatusBar({\n segments,\n ariaLabel,\n}: {\n segments: StatusSegment[];\n ariaLabel?: string;\n}) {\n const visible = segments.filter((s) => s.count > 0);\n const total = visible.reduce((sum, s) => sum + s.count, 0);\n if (visible.length === 0 || total <= 0) {\n return <div className=\"rounded border border-dashed p-3 text-xs text-muted-foreground\">No status data</div>;\n }\n return (\n <div className=\"flex h-2 overflow-hidden rounded bg-muted\" aria-label={ariaLabel}>\n {visible.map((s) => (\n <div\n key={s.key}\n className={s.className}\n title={`${s.label}: ${s.count}`}\n style={{ width: `${Math.max(1, (s.count / total) * 100)}%` }}\n />\n ))}\n </div>\n );\n}\n\n// StatusRows renders each status as its own row — a colored swatch + label, the\n// count, and a horizontal bar sized proportionally to the visible-segment total.\n// The vertical counterpart to StackedStatusBar. An optional onRetry surfaces a\n// Retry button per row; callers that omit it get no button. When a segment\n// carries an href the whole row links there via renderLink (defaults to a plain\n// <a>); the Retry button stops propagation so it stays independently clickable.\nexport function StatusRows({\n segments,\n ariaLabel,\n onRetry,\n retryingKey,\n isRetryable,\n renderLink = defaultRenderLink,\n}: {\n segments: StatusSegment[];\n ariaLabel?: string;\n onRetry?: (segment: StatusSegment) => void;\n retryingKey?: string;\n isRetryable?: (segment: StatusSegment) => boolean;\n renderLink?: StatusRenderLink;\n}) {\n const visible = segments.filter((s) => s.count > 0);\n const total = visible.reduce((sum, s) => sum + s.count, 0);\n if (visible.length === 0 || total <= 0) {\n return <div className=\"rounded border border-dashed p-3 text-xs text-muted-foreground\">No status data</div>;\n }\n return (\n <div className=\"space-y-2\" aria-label={ariaLabel}>\n {visible.map((s) => {\n const retryable = !!onRetry && (isRetryable?.(s) ?? false);\n const meta = (\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className={cn(\"h-2.5 w-2.5 shrink-0 rounded-sm\", s.className)} aria-hidden=\"true\" />\n <span className=\"truncate text-xs\">{s.label}</span>\n <span className=\"ml-auto shrink-0 font-mono text-xs text-muted-foreground\">{s.count}</span>\n </div>\n );\n return (\n <div key={s.key} className=\"flex items-center gap-3\">\n {s.href\n ? renderLink({\n to: s.href,\n className: \"flex min-w-0 flex-1 rounded hover:bg-accent/40\",\n title: `View ${s.label} records`,\n children: meta,\n })\n : meta}\n <div className=\"h-2 w-32 shrink-0 overflow-hidden rounded bg-muted sm:w-48\">\n <div className={cn(\"h-full\", s.className)} style={{ width: `${Math.max(1, (s.count / total) * 100)}%` }} />\n </div>\n {retryable ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-6 shrink-0 px-2 text-[11px]\"\n disabled={retryingKey === s.key}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onRetry?.(s);\n }}\n >\n {retryingKey === s.key ? \"Retrying…\" : \"Retry\"}\n </Button>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -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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"}
|