@parallelworks/ui 0.17.0 → 0.19.0

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 (169) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/mock/index.d.ts +2 -0
  4. package/dist/ai/adapter/mock/index.js +81 -0
  5. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  6. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  7. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  8. package/dist/ai/adapter/openai/index.d.ts +6 -0
  9. package/dist/ai/adapter/openai/index.js +334 -0
  10. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  11. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  12. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  13. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  14. package/dist/ai/adapter/types.d.ts +131 -0
  15. package/dist/ai/agent/classifier.d.ts +2 -0
  16. package/dist/ai/agent/diff.d.ts +35 -0
  17. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  18. package/dist/ai/agent/index.d.ts +6 -0
  19. package/dist/ai/agent/permissions.d.ts +11 -0
  20. package/dist/ai/agent/toolfmt.d.ts +18 -0
  21. package/dist/ai/agent/transcript.d.ts +38 -0
  22. package/dist/ai/ai.css +325 -0
  23. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  24. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  25. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  26. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  27. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  28. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  29. package/dist/ai/components/ChatInput.d.ts +45 -0
  30. package/dist/ai/components/ChatLayout.d.ts +5 -0
  31. package/dist/ai/components/ChatMessage.d.ts +24 -0
  32. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  33. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  34. package/dist/ai/components/ChatThread.d.ts +3 -0
  35. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  36. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  37. package/dist/ai/components/DragOverlay.d.ts +5 -0
  38. package/dist/ai/components/ModelSelector.d.ts +6 -0
  39. package/dist/ai/components/ShareDialog.d.ts +11 -0
  40. package/dist/ai/components/SlashMenu.d.ts +28 -0
  41. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  42. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  43. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  44. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  45. package/dist/ai/core/ChatProvider.d.ts +66 -0
  46. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  47. package/dist/ai/core/chatReducer.d.ts +114 -0
  48. package/dist/ai/core/config.d.ts +47 -0
  49. package/dist/ai/core/events.d.ts +1 -0
  50. package/dist/ai/core/exportConversation.d.ts +4 -0
  51. package/dist/ai/core/greeting.d.ts +3 -0
  52. package/dist/ai/core/parts.d.ts +11 -0
  53. package/dist/ai/core/useDragDrop.d.ts +14 -0
  54. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  55. package/dist/ai/core/useSSEStream.d.ts +34 -0
  56. package/dist/ai/index.d.ts +40 -0
  57. package/dist/ai/index.js +6645 -0
  58. package/dist/ai/strings.d.ts +167 -0
  59. package/dist/ai/types.d.ts +236 -0
  60. package/dist/ai/ui/Avatar.d.ts +8 -0
  61. package/dist/ai/ui/Dropdown.d.ts +31 -0
  62. package/dist/ai/ui/Markdown.d.ts +8 -0
  63. package/dist/ai/ui/Notice.d.ts +21 -0
  64. package/dist/ai/ui/buttons.d.ts +1 -0
  65. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  66. package/dist/ai/ui/prose.d.ts +1 -0
  67. package/dist/ai/ui/sidebar.d.ts +81 -0
  68. package/dist/ai/utils.d.ts +4 -0
  69. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  70. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  71. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  72. package/dist/chunks/{CodePreviewEditor-UAtnpmOV.js → CodePreviewEditor-YqQBz1YL.js} +2 -2
  73. package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
  74. package/dist/chunks/{lib-CUTRDpa6.js → FieldWrapper-Cszwg-4B.js} +52 -55
  75. package/dist/chunks/{CreateModal-BbV5cTj7.js → Markdown-CM-FenNE.js} +25 -97
  76. package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
  77. package/dist/chunks/{PageHeader-MxuOs9cH.js → PageHeader-0kG_iypP.js} +170 -105
  78. package/dist/chunks/{Provider-DHmZ3v9i.js → Provider-CDYurraE.js} +60 -24
  79. package/dist/chunks/{SwitchToggle-BRQoEwLZ.js → SwitchToggle-DShNdcao.js} +143 -140
  80. package/dist/chunks/{Table-C6JdFFiJ.js → Table-DU2MW8xz.js} +6 -4
  81. package/dist/chunks/{Tooltip-n9w7Tkt1.js → Tooltip-K5HJr4_p.js} +32 -5
  82. package/dist/chunks/duration-BOv8Phl8.js +17 -0
  83. package/dist/chunks/{editor-mNznodJN.js → editor-Dk1rbV75.js} +33 -19
  84. package/dist/chunks/focus-D_iZJTW1.js +7 -0
  85. package/dist/chunks/{list-7k0eaI5N.js → list-CJm875m7.js} +497 -379
  86. package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
  87. package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
  88. package/dist/chunks/types-Yy0NrerF.js +11 -0
  89. package/dist/components/AddMenu.d.ts +1 -0
  90. package/dist/components/Avatar.d.ts +13 -0
  91. package/dist/components/Breadcrumbs.d.ts +1 -1
  92. package/dist/components/Dropdown.d.ts +3 -1
  93. package/dist/components/EmptyState.d.ts +1 -1
  94. package/dist/components/Indicator.d.ts +2 -2
  95. package/dist/components/Input.d.ts +1 -1
  96. package/dist/components/LetterBadge.d.ts +1 -1
  97. package/dist/components/MarkdownImpl.d.ts +1 -1
  98. package/dist/components/Provider.d.ts +18 -65
  99. package/dist/components/SettingRow.d.ts +1 -1
  100. package/dist/components/SettingsGroup.d.ts +1 -1
  101. package/dist/components/focus.d.ts +2 -0
  102. package/dist/components/keys.d.ts +12 -0
  103. package/dist/duration.d.ts +3 -0
  104. package/dist/editor/Monaco.d.ts +1 -20
  105. package/dist/editor/index.d.ts +2 -1
  106. package/dist/editor/index.js +2 -2
  107. package/dist/editor/yaml.d.ts +5 -0
  108. package/dist/engine.d.ts +98 -0
  109. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  110. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  111. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  112. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  113. package/dist/file-explorer/FileRow.d.ts +1 -1
  114. package/dist/file-explorer/helpers.d.ts +4 -4
  115. package/dist/file-explorer/index.d.ts +3 -3
  116. package/dist/file-explorer/index.js +632 -665
  117. package/dist/file-explorer/lib/types.d.ts +6 -1
  118. package/dist/file-explorer/lib/utils.d.ts +1 -3
  119. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  120. package/dist/form/FieldWrapper.d.ts +2 -1
  121. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  122. package/dist/form/Form.d.ts +7 -22
  123. package/dist/form/index.d.ts +11 -12
  124. package/dist/form/index.js +1333 -1454
  125. package/dist/form/lib.d.ts +6 -1
  126. package/dist/form/types/fieldComponentTypes.d.ts +4 -2
  127. package/dist/form/types/fieldTypes.d.ts +6 -20
  128. package/dist/form/useParsedOpts.d.ts +2 -2
  129. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  130. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  131. package/dist/{workflow → graph}/index.d.ts +1 -1
  132. package/dist/{workflow → graph}/index.js +220 -185
  133. package/dist/{workflow → graph}/types.d.ts +3 -3
  134. package/dist/icons.d.ts +20 -21
  135. package/dist/icons.js +3 -3
  136. package/dist/index.d.ts +38 -39
  137. package/dist/index.js +355 -354
  138. package/dist/list/ListTable.d.ts +1 -1
  139. package/dist/list/ListViewControls.d.ts +2 -2
  140. package/dist/list/RowContextMenu.d.ts +9 -9
  141. package/dist/list/UserHoverCard.d.ts +45 -0
  142. package/dist/list/index.d.ts +9 -8
  143. package/dist/list/index.js +3 -3
  144. package/dist/logviewer/LogViewer.d.ts +1 -1
  145. package/dist/logviewer/index.d.ts +1 -0
  146. package/dist/logviewer/index.js +2 -742
  147. package/dist/logviewer/segments.d.ts +9 -0
  148. package/dist/styles/Geist-Variable.woff2 +0 -0
  149. package/dist/styles/GeistMono-Variable.woff2 +0 -0
  150. package/dist/styles/base.css +57 -0
  151. package/dist/styles/fonts.css +15 -0
  152. package/dist/styles/theme.css +9 -41
  153. package/dist/styles.css +1 -1
  154. package/dist/theme/index.js +2 -2
  155. package/package.json +45 -20
  156. package/LICENSE +0 -21
  157. package/dist/chunks/Monaco-DVyIpyv4.js +0 -1046
  158. package/dist/editor/usesGitlab.d.ts +0 -97
  159. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  160. package/dist/form/types/workflow-schema.d.ts +0 -1145
  161. package/dist/form/utils/pwResolver.d.ts +0 -18
  162. package/dist/chunks/{BareModal-BqroLbZ5.js → BareModal-BtRiQezg.js} +1 -1
  163. package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
  164. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  165. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  166. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  167. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  168. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  169. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -1,22 +1,91 @@
1
+ import { u as useStrings } from "./Provider-CDYurraE.js";
1
2
  import { AngleDownIcon, AngleRightIcon, CaretDownIcon } from "../icons.js";
2
- import { u as useStrings } from "./Provider-DHmZ3v9i.js";
3
- import { a as truncationTooltipProps, n as TOOLTIP_ID } from "./Tooltip-n9w7Tkt1.js";
3
+ import { a as truncationTooltipProps, n as TOOLTIP_ID, o as keyedByContent } from "./Tooltip-K5HJr4_p.js";
4
4
  import { a as filterOption, c as isCategory, i as DropdownCaret, l as isOption, o as flattenDisplayOptions, s as flattenOptions, u as toggleSetMember } from "./StatusBadge-C1Blx_cW.js";
5
+ import { t as focusOnMount } from "./focus-D_iZJTW1.js";
6
+ import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Listbox, ListboxButton, ListboxOption, ListboxOptions, Switch, Transition } from "@headlessui/react";
5
7
  import cx from "classnames";
6
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
8
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
10
  import { createPortal } from "react-dom";
9
- import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Listbox, ListboxButton, ListboxOption, ListboxOptions, Switch, Transition } from "@headlessui/react";
11
+ import AnimateHeight from "react-animate-height";
10
12
  import deepEqual from "fast-deep-equal";
11
13
  import { usePopper } from "react-popper";
12
- import AnimateHeight from "react-animate-height";
14
+ //#region src/components/CollapsiblePanel.tsx
15
+ var noop = () => {};
16
+ function ControlledCollapsiblePanel({ title = "", children, open, setOpen, onClick = noop, wrapperElement, customizedButton = null, titleAction, className }) {
17
+ const toggleOpen = useCallback(() => {
18
+ if (onClick) onClick();
19
+ setOpen?.((open) => !open);
20
+ }, [setOpen, onClick]);
21
+ const contentId = React.useId();
22
+ const Wrapper = wrapperElement ? wrapperElement : React.Fragment;
23
+ return React.isValidElement(title) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [title, /* @__PURE__ */ jsx(Wrapper, { children: /* @__PURE__ */ jsx(AnimateHeight, {
24
+ duration: 300,
25
+ height: open ? "auto" : 0,
26
+ children
27
+ }) })] }) : /* @__PURE__ */ jsxs("div", {
28
+ className: cx("border border-solid rounded-2xl border-(--theme-border) bg-(--theme-panel-bg) text-(--theme-panel) mb-1 w-full", className),
29
+ children: [/* @__PURE__ */ jsxs("div", {
30
+ className: cx(!open && "text-(--theme-muted-text-color)", "w-full flex items-center transform ease-in transition text-sm py-3 px-2 cursor-pointer"),
31
+ children: [
32
+ /* @__PURE__ */ jsxs("button", {
33
+ type: "button",
34
+ "aria-expanded": !!open,
35
+ "aria-controls": contentId,
36
+ className: cx("flex items-center text-left cursor-pointer", !titleAction && "w-full"),
37
+ onClick: toggleOpen,
38
+ children: [/* @__PURE__ */ jsx(AngleRightIcon, { className: cx(open && "transform rotate-90", "px-1 ml-1 text-[1.25rem] transition ease-in") }), /* @__PURE__ */ jsx("span", {
39
+ className: "px-2 font-bold select-none",
40
+ children: title?.toString()
41
+ })]
42
+ }),
43
+ titleAction,
44
+ /* @__PURE__ */ jsx("div", {
45
+ className: "ml-auto",
46
+ children: customizedButton
47
+ })
48
+ ]
49
+ }), /* @__PURE__ */ jsx(AnimateHeight, {
50
+ id: contentId,
51
+ duration: 300,
52
+ height: open ? "auto" : 0,
53
+ children
54
+ })]
55
+ });
56
+ }
57
+ function UncontrolledCollapsiblePanel({ title, children, onClick, wrapperElement, initialState = true, className, customizedButton = null }) {
58
+ const [open, setOpen] = React.useState(initialState);
59
+ const passTitle = typeof title === "function" ? title(open, setOpen) : title;
60
+ return /* @__PURE__ */ jsx(ControlledCollapsiblePanel, {
61
+ title: passTitle,
62
+ open,
63
+ setOpen,
64
+ onClick,
65
+ wrapperElement,
66
+ className,
67
+ customizedButton,
68
+ children
69
+ });
70
+ }
71
+ function MaybeCollapsible({ className, initialState, children, title, customizedButton, collapsible }) {
72
+ if (collapsible) return /* @__PURE__ */ jsx(UncontrolledCollapsiblePanel, {
73
+ className,
74
+ initialState,
75
+ title,
76
+ customizedButton,
77
+ children
78
+ });
79
+ return /* @__PURE__ */ jsx("div", {
80
+ className,
81
+ children
82
+ });
83
+ }
84
+ //#endregion
13
85
  //#region src/components/Dropdown.tsx
14
86
  var defaultCollapsedLabel = (count) => `${count} more`;
15
- function isResourceValue(value) {
16
- if (typeof value !== "object" || value === null || !("name" in value)) return false;
17
- if (typeof value.name !== "string") return false;
18
- if ("$type" in value && value.$type === "computeResource") return true;
19
- return "type" in value && (value.type === "computeResource" || value.type === "bucket");
87
+ function isNamedValue(value) {
88
+ return typeof value === "object" && value !== null && "name" in value && typeof value.name === "string";
20
89
  }
21
90
  var checkEquals = (val, opt) => {
22
91
  if (typeof val === "object" && !Array.isArray(val)) return deepEqual(val, opt);
@@ -32,20 +101,22 @@ function getOptionFromValue(value, options) {
32
101
  else if (isCategory(option)) return option.options.find((opt) => checkEquals(value, opt.value));
33
102
  else return checkEquals(value, option.value);
34
103
  });
35
- if (found) if (typeof found === "string") return {
36
- label: found,
37
- value: found
38
- };
39
- else if (isCategory(found)) return found.options.find((opt) => checkEquals(value, opt.value)) || {
40
- label: JSON.stringify(value),
41
- value
42
- };
43
- else return found;
44
- const isResourceObject = isResourceValue(value);
45
- const fallbackLabel = typeof value === "string" ? value : isResourceObject ? value.name : JSON.stringify(value);
104
+ if (found) {
105
+ if (typeof found === "string") return {
106
+ label: found,
107
+ value: found
108
+ };
109
+ else if (isCategory(found)) return found.options.find((opt) => checkEquals(value, opt.value)) || {
110
+ label: JSON.stringify(value),
111
+ value
112
+ };
113
+ else return found;
114
+ }
115
+ const isNamedObject = isNamedValue(value);
116
+ const fallbackLabel = typeof value === "string" ? value : isNamedObject ? value.name : JSON.stringify(value);
46
117
  return {
47
118
  label: fallbackLabel,
48
- value: isResourceObject ? value : fallbackLabel
119
+ value: isNamedObject ? value : fallbackLabel
49
120
  };
50
121
  }
51
122
  function Dropdown(props) {
@@ -56,29 +127,30 @@ function Dropdown(props) {
56
127
  const wrapperOnchange = (value) => {
57
128
  if (onChange) onChange(value?.value);
58
129
  };
130
+ const transformedOptions = useMemo(() => {
131
+ if (!options || options.length === 0) return [];
132
+ return options.map((item) => {
133
+ if (isCategory(item)) return {
134
+ ...item,
135
+ options: item.options.map((opt) => {
136
+ if (typeof opt === "string") return {
137
+ label: opt,
138
+ value: opt
139
+ };
140
+ return opt;
141
+ })
142
+ };
143
+ else if (typeof item === "string") return {
144
+ label: item,
145
+ value: item
146
+ };
147
+ return item;
148
+ });
149
+ }, [options]);
59
150
  return /* @__PURE__ */ jsx(DropdownHelper, {
60
151
  value: val,
61
152
  onChange: wrapperOnchange,
62
- options: useMemo(() => {
63
- if (!options || options.length === 0) return [];
64
- return options.map((item) => {
65
- if (isCategory(item)) return {
66
- ...item,
67
- options: item.options.map((opt) => {
68
- if (typeof opt === "string") return {
69
- label: opt,
70
- value: opt
71
- };
72
- return opt;
73
- })
74
- };
75
- else if (typeof item === "string") return {
76
- label: item,
77
- value: item
78
- };
79
- return item;
80
- });
81
- }, [options]),
153
+ options: transformedOptions,
82
154
  ...others
83
155
  });
84
156
  }
@@ -131,7 +203,7 @@ function ToggleOption({ option, category, expanded, onToggle, ...virtualRowProps
131
203
  })
132
204
  });
133
205
  }
134
- function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassName = "w-full", options = [], onChange, onActiveChange, value, id, ariaLabel, "aria-describedby": describedBy, required, disabled = false, placeholder = "", loading = false, allowCustomValue = false, customValueLabel = "Use", collapsedLabel = defaultCollapsedLabel, portalEl }) {
206
+ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassName = "w-full", options = [], onChange, onActiveChange, value, id, ariaLabel, "aria-describedby": describedBy, required, disabled = false, placeholder = "", loading = false, allowCustomValue = false, customValueLabel = "Use", collapsedLabel = defaultCollapsedLabel, portalEl, compact = false }) {
135
207
  const DEBOUNCE_MS = 500;
136
208
  const t = useStrings().dropdown;
137
209
  const [query, setQuery] = useState("");
@@ -180,19 +252,20 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
180
252
  if (reference instanceof HTMLElement) popper.style.width = `${reference.offsetWidth}px`;
181
253
  }
182
254
  }), []);
255
+ const popperModifiers = useMemo(() => boundaryEl ? [
256
+ sameWidthModifier,
257
+ {
258
+ name: "flip",
259
+ options: { boundary: boundaryEl }
260
+ },
261
+ {
262
+ name: "preventOverflow",
263
+ options: { boundary: boundaryEl }
264
+ }
265
+ ] : [sameWidthModifier], [boundaryEl, sameWidthModifier]);
183
266
  const { styles, attributes } = usePopper(referenceElement, popperElement, {
184
267
  strategy: "fixed",
185
- modifiers: useMemo(() => boundaryEl ? [
186
- sameWidthModifier,
187
- {
188
- name: "flip",
189
- options: { boundary: boundaryEl }
190
- },
191
- {
192
- name: "preventOverflow",
193
- options: { boundary: boundaryEl }
194
- }
195
- ] : [sameWidthModifier], [boundaryEl, sameWidthModifier])
268
+ modifiers: popperModifiers
196
269
  });
197
270
  const debounceRef = useRef(null);
198
271
  const buttonRef = useRef(null);
@@ -202,7 +275,7 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
202
275
  useEffect(() => {
203
276
  if (!selectedCategory || checkEquals(lastAutoExpandedValue.current, value.value)) return;
204
277
  lastAutoExpandedValue.current = value.value;
205
- setExpandedCategories((prev) => prev.size === 1 && prev.has(selectedCategory) ? prev : new Set([selectedCategory]));
278
+ setExpandedCategories((prev) => prev.size === 1 && prev.has(selectedCategory) ? prev : /* @__PURE__ */ new Set([selectedCategory]));
206
279
  }, [selectedCategory, value]);
207
280
  const toggleCategory = (category) => setExpandedCategories((prev) => toggleSetMember(prev, category));
208
281
  const flushCustomValue = useCallback((val) => {
@@ -253,11 +326,11 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
253
326
  allowCustomValue,
254
327
  customValueLabel
255
328
  ]);
256
- const comboOptions = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ComboboxOptions, {
329
+ const comboOptions = /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(ComboboxOptions, {
257
330
  modal: false,
258
331
  ref: setPopperElement,
259
332
  style: styles["popper"],
260
- className: "bg-(--theme-input-bg) border-(--theme-border) text-(--theme-app) max-h-60! empty:invisible border overflow-auto rounded-md shadow-lg focus:outline-hidden sm:text-sm z-9999 data-[popper-reference-hidden=true]:invisible data-[popper-reference-hidden=true]:pointer-events-none",
333
+ className: cx("bg-(--theme-input-bg) border-(--theme-border) text-(--theme-app) max-h-60! empty:invisible border overflow-auto rounded-md shadow-lg focus:outline-hidden z-9999 data-[popper-reference-hidden=true]:invisible data-[popper-reference-hidden=true]:pointer-events-none", compact ? "text-xs" : "sm:text-sm"),
261
334
  ...attributes["popper"],
262
335
  children: ({ option }) => {
263
336
  const optionLabel = typeof option === "string" ? option : option.label;
@@ -274,7 +347,7 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
274
347
  return /* @__PURE__ */ jsx(ComboboxOption, {
275
348
  "data-testid": "combobox-option",
276
349
  value: option,
277
- className: cx("w-full group relative flex", optionDescription ? "min-h-10 py-2" : "h-10", isCategoryRow ? "text-[14px] font-bold pl-1 items-center" : "data-disabled:text-(--theme-muted-text-color) data-disabled:bg-(--theme-muted-panel-bg) data-disabled:cursor-not-allowed cursor-pointer items-center pr-9 pl-3 leading-5 data-focus:bg-(--theme-muted-panel-bg) data-focus:text-(--theme-app) data-focus:outline-hidden", "data-selected:border-l-2 data-selected:border-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-app)", isPinned && "border-t border-(--theme-border) font-medium"),
350
+ className: cx("w-full group relative flex", optionDescription ? "min-h-10 py-2" : compact ? "h-8" : "h-10", isCategoryRow ? "text-[14px] font-bold pl-1 items-center" : "data-disabled:text-(--theme-muted-text-color) data-disabled:bg-(--theme-muted-panel-bg) data-disabled:cursor-not-allowed cursor-pointer items-center pr-9 pl-3 leading-5 data-focus:bg-(--theme-muted-panel-bg) data-focus:text-(--theme-app) data-focus:outline-hidden", "data-selected:border-l-2 data-selected:border-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-app)", isPinned && "border-t border-(--theme-border) font-medium"),
278
351
  children: /* @__PURE__ */ jsx(OptionContent, {
279
352
  label: optionLabel,
280
353
  description: optionDescription,
@@ -302,7 +375,7 @@ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassNa
302
375
  disabled: (option) => Boolean(option.disabled)
303
376
  },
304
377
  disabled,
305
- children: ({ activeOption, open }) => /* @__PURE__ */ jsxs(Fragment, { children: [
378
+ children: ({ activeOption, open }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
306
379
  onActiveChange && /* @__PURE__ */ jsx(ActiveWatcher, {
307
380
  active: activeOption,
308
381
  onChange: onActiveChange
@@ -377,7 +450,7 @@ function CustomListbox({ options = [], handleOptionSelected, type, allowSearch =
377
450
  children: /* @__PURE__ */ jsx("input", {
378
451
  autoComplete: "off",
379
452
  type: "search",
380
- autoFocus: true,
453
+ ref: focusOnMount,
381
454
  onChange: (e) => setFilter(e.target.value),
382
455
  value: filter,
383
456
  className: "w-full p-1 theme-input",
@@ -394,7 +467,7 @@ function CustomListbox({ options = [], handleOptionSelected, type, allowSearch =
394
467
  })
395
468
  }), /* @__PURE__ */ jsx("div", {
396
469
  className: "overflow-auto max-h-60 theme-panel",
397
- children: optionsToShow.length > 0 ? optionsToShow.map((option, index) => /* @__PURE__ */ jsx(ListboxOption, {
470
+ children: optionsToShow.length > 0 ? keyedByContent(optionsToShow, (o) => String(o.value)).map(({ key, item: option }) => /* @__PURE__ */ jsx(ListboxOption, {
398
471
  className: "relative hover:theme-hover select-none pl-2 pr-4",
399
472
  value: option.value,
400
473
  children: /* @__PURE__ */ jsx("div", {
@@ -420,8 +493,8 @@ function CustomListbox({ options = [], handleOptionSelected, type, allowSearch =
420
493
  })
421
494
  ]
422
495
  })
423
- }, index)
424
- }, index)) : /* @__PURE__ */ jsx("div", {
496
+ })
497
+ }, key)) : /* @__PURE__ */ jsx("div", {
425
498
  className: "w-full flex flex-row",
426
499
  children: /* @__PURE__ */ jsx("div", {
427
500
  className: "w-3/4 py-2 pl-2 capitalize flex items-center",
@@ -456,7 +529,7 @@ function CustomListbox({ options = [], handleOptionSelected, type, allowSearch =
456
529
  leaveFrom: "opacity-100",
457
530
  leaveTo: "opacity-0",
458
531
  children: optionsElement || null
459
- }) : /* @__PURE__ */ jsx(Fragment, { children: controlledOpen && optionsElement })]
532
+ }) : /* @__PURE__ */ jsx(Fragment$1, { children: controlledOpen && optionsElement })]
460
533
  });
461
534
  }
462
535
  //#endregion
@@ -534,7 +607,7 @@ function MultiSelectDropdown({ options, value, onChange, id, "aria-labelledby":
534
607
  children: loading ? /* @__PURE__ */ jsx("span", {
535
608
  className: "theme-muted-text",
536
609
  children: strings.loading
537
- }) : selectedOptions.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
610
+ }) : selectedOptions.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
538
611
  className: "min-w-0 truncate",
539
612
  children: display.label
540
613
  }), display.overflow > 0 && /* @__PURE__ */ jsxs("span", {
@@ -565,19 +638,19 @@ function MultiSelectDropdown({ options, value, onChange, id, "aria-labelledby":
565
638
  value: query,
566
639
  onChange: (e) => setQuery(e.target.value),
567
640
  onKeyDown: (e) => e.stopPropagation(),
568
- autoFocus: true
641
+ ref: focusOnMount
569
642
  })
570
643
  }), /* @__PURE__ */ jsx("div", {
571
644
  className: "py-1",
572
645
  children: isEmpty ? /* @__PURE__ */ jsx("div", {
573
646
  className: "px-4 py-2 text-sm theme-muted-text",
574
647
  children: strings.dropdown.noOptionsFound
575
- }) : filteredOptions.map((opt, index) => {
648
+ }) : keyedByContent(filteredOptions, (o) => isCategory(o) ? `category-${o.category ?? "uncat"}` : `option-${String(o.value)}`).map(({ key, item: opt }) => {
576
649
  if (isCategory(opt)) return /* @__PURE__ */ jsx("li", {
577
650
  role: "presentation",
578
651
  className: "px-4 py-2 text-sm font-bold theme-muted-text",
579
652
  children: opt.category
580
- }, `category-${opt.category ?? "uncat"}-${index}`);
653
+ }, key);
581
654
  const option = opt;
582
655
  return /* @__PURE__ */ jsx(ComboboxOption, {
583
656
  value: option.value,
@@ -612,7 +685,7 @@ function MultiSelectDropdown({ options, value, onChange, id, "aria-labelledby":
612
685
  })
613
686
  ]
614
687
  })
615
- }, `option-${String(option.value)}`);
688
+ }, key);
616
689
  })
617
690
  })]
618
691
  })
@@ -621,76 +694,6 @@ function MultiSelectDropdown({ options, value, onChange, id, "aria-labelledby":
621
694
  });
622
695
  }
623
696
  //#endregion
624
- //#region src/components/CollapsiblePanel.tsx
625
- var noop = () => {};
626
- function ControlledCollapsiblePanel({ title = "", children, open, setOpen, onClick = noop, wrapperElement, customizedButton = null, titleAction, className }) {
627
- const toggleOpen = useCallback(() => {
628
- if (onClick) onClick();
629
- setOpen?.((open) => !open);
630
- }, [setOpen, onClick]);
631
- const contentId = React.useId();
632
- const Wrapper = wrapperElement ? wrapperElement : React.Fragment;
633
- return React.isValidElement(title) ? /* @__PURE__ */ jsxs(Fragment, { children: [title, /* @__PURE__ */ jsx(Wrapper, { children: /* @__PURE__ */ jsx(AnimateHeight, {
634
- duration: 300,
635
- height: open ? "auto" : 0,
636
- children
637
- }) })] }) : /* @__PURE__ */ jsxs("div", {
638
- className: cx("border border-solid rounded-2xl border-(--theme-border) bg-(--theme-panel-bg) text-(--theme-panel) mb-1 w-full", className),
639
- children: [/* @__PURE__ */ jsxs("div", {
640
- className: cx(!open && "text-(--theme-muted-text-color)", "w-full flex items-center transform ease-in transition text-sm py-3 px-2 cursor-pointer"),
641
- children: [
642
- /* @__PURE__ */ jsxs("button", {
643
- type: "button",
644
- "aria-expanded": !!open,
645
- "aria-controls": contentId,
646
- className: cx("flex items-center text-left cursor-pointer", !titleAction && "w-full"),
647
- onClick: toggleOpen,
648
- children: [/* @__PURE__ */ jsx(AngleRightIcon, { className: cx(open && "transform rotate-90", "px-1 ml-1 text-[1.25rem] transition ease-in") }), /* @__PURE__ */ jsx("span", {
649
- className: "px-2 font-bold select-none",
650
- children: title?.toString()
651
- })]
652
- }),
653
- titleAction,
654
- /* @__PURE__ */ jsx("div", {
655
- className: "ml-auto",
656
- children: customizedButton
657
- })
658
- ]
659
- }), /* @__PURE__ */ jsx(AnimateHeight, {
660
- id: contentId,
661
- duration: 300,
662
- height: open ? "auto" : 0,
663
- children
664
- })]
665
- });
666
- }
667
- function UncontrolledCollapsiblePanel({ title, children, onClick, wrapperElement, initialState = true, className, customizedButton = null }) {
668
- const [open, setOpen] = React.useState(initialState);
669
- return /* @__PURE__ */ jsx(ControlledCollapsiblePanel, {
670
- title: typeof title === "function" ? title(open, setOpen) : title,
671
- open,
672
- setOpen,
673
- onClick,
674
- wrapperElement,
675
- className,
676
- customizedButton,
677
- children
678
- });
679
- }
680
- function MaybeCollapsible({ className, initialState, children, title, customizedButton, collapsible }) {
681
- if (collapsible) return /* @__PURE__ */ jsx(UncontrolledCollapsiblePanel, {
682
- className,
683
- initialState,
684
- title,
685
- customizedButton,
686
- children
687
- });
688
- return /* @__PURE__ */ jsx("div", {
689
- className,
690
- children
691
- });
692
- }
693
- //#endregion
694
697
  //#region src/components/SectionHeader.tsx
695
698
  function SectionHeader({ children, className = "", size = "md" }) {
696
699
  return /* @__PURE__ */ jsx("div", {
@@ -752,4 +755,4 @@ function SwitchToggle({ onChange, id, "aria-describedby": describedBy, value = v
752
755
  });
753
756
  }
754
757
  //#endregion
755
- export { UncontrolledCollapsiblePanel as a, Dropdown as c, MaybeCollapsible as i, SectionHeader as n, MultiSelectDropdown as o, ControlledCollapsiblePanel as r, CustomListbox as s, SwitchToggle as t };
758
+ export { Dropdown as a, UncontrolledCollapsiblePanel as c, CustomListbox as i, SectionHeader as n, ControlledCollapsiblePanel as o, MultiSelectDropdown as r, MaybeCollapsible as s, SwitchToggle as t };
@@ -1,8 +1,8 @@
1
- import { u as useStrings } from "./Provider-DHmZ3v9i.js";
1
+ import { u as useStrings } from "./Provider-CDYurraE.js";
2
2
  import { t as Loader } from "./Loader-BXoXTZGc.js";
3
3
  import cx from "classnames";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
4
  import React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/Table.tsx
7
7
  function Item({ wrap = false, children, className, colspan = 1, ...tdProps }) {
8
8
  const yPadding = className?.includes("py-") ? "" : "py-4";
@@ -49,9 +49,10 @@ function Table({ borderless = false, panel = true, className = "", wrapperClassN
49
49
  const { loading } = useStrings();
50
50
  const ChildrenArr = React.Children.toArray(children);
51
51
  const Headers = getHeaders(ChildrenArr);
52
+ const hasOverflow = wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-"));
52
53
  return /* @__PURE__ */ jsx("div", {
53
54
  "aria-busy": isLoading,
54
- className: cx("flex flex-col w-full", !wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-")) && "overflow-hidden", wrapperClassName),
55
+ className: cx("flex flex-col w-full", !hasOverflow && "overflow-hidden", wrapperClassName),
55
56
  children: isLoading ? /* @__PURE__ */ jsxs("div", {
56
57
  role: "status",
57
58
  "aria-label": loading,
@@ -79,8 +80,9 @@ function Table({ borderless = false, panel = true, className = "", wrapperClassN
79
80
  function CompactTable({ wrapperClassName = "", className = "", tbodyClassName = "divide-y", children, roundedTop = false, rounded = false, roundedBottom = false }) {
80
81
  const ChildrenArr = React.Children.toArray(children);
81
82
  const Headers = getHeaders(ChildrenArr);
83
+ const hasOverflow = wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-"));
82
84
  return /* @__PURE__ */ jsx("div", {
83
- className: cx("flex flex-col w-full", !wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-")) && "overflow-hidden", wrapperClassName),
85
+ className: cx("flex flex-col w-full", !hasOverflow && "overflow-hidden", wrapperClassName),
84
86
  children: /* @__PURE__ */ jsx("div", {
85
87
  className: cx("theme-panel inline-block min-w-full align-middle overflow-x-auto", rounded && "rounded-2xl", roundedBottom && "rounded-b-2xl pb-1", roundedTop && "rounded-t-2xl"),
86
88
  children: /* @__PURE__ */ jsxs("table", {
@@ -1,7 +1,33 @@
1
1
  import { TooltipIcon } from "../icons.js";
2
+ import { Fragment } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Fragment as Fragment$1 } from "react";
4
4
  import { Tooltip } from "react-tooltip";
5
+ //#region src/components/keys.ts
6
+ /** Pairs each item with a React key from its content, suffixing repeats so keys stay unique. */
7
+ function keyedByContent(items, toKey) {
8
+ const seen = /* @__PURE__ */ new Map();
9
+ return items.map((item) => {
10
+ const base = toKey(item);
11
+ const count = (seen.get(base) ?? 0) + 1;
12
+ seen.set(base, count);
13
+ return {
14
+ key: count === 1 ? base : `${base}#${count}`,
15
+ item
16
+ };
17
+ });
18
+ }
19
+ /** Keys for a list whose position is its identity, such as placeholder rows or a fixed grid. */
20
+ function positionKeys(count, prefix = "position") {
21
+ return Array.from({ length: count }, (_, position) => `${prefix}-${position}`);
22
+ }
23
+ /** Pairs each item of a list that never reorders with a key from its position. */
24
+ function withPositionKeys(items, prefix = "position") {
25
+ return items.map((item, position) => ({
26
+ key: `${prefix}-${position}`,
27
+ item
28
+ }));
29
+ }
30
+ //#endregion
5
31
  //#region src/components/Tooltip.tsx
6
32
  var TOOLTIP_ID = "global-tooltip";
7
33
  /** Anchor props that reveal `content` only while the text is ellipsized; `measure` picks the clipped descendant when it isn't the anchor. */
@@ -39,18 +65,19 @@ function formatLine(line) {
39
65
  function formatTooltipContent(content) {
40
66
  if (typeof content !== "string") return content || null;
41
67
  if (!content) return null;
42
- return content.split(/<br\s*\/?>|\n/i).map((line, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] }, idx));
68
+ return keyedByContent(content.split(/<br\s*\/?>|\n/i), (l) => l).map(({ key, item: line }, idx) => /* @__PURE__ */ jsxs(Fragment, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] }, key));
43
69
  }
44
70
  function KbdShortcut({ keys }) {
71
+ const parts = keys.split("+").map((part) => part.trim()).filter(Boolean);
45
72
  return /* @__PURE__ */ jsx("span", {
46
73
  className: "inline-flex items-center gap-1 align-middle",
47
- children: keys.split("+").map((part) => part.trim()).filter(Boolean).map((part, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("span", {
74
+ children: keyedByContent(parts, (p) => p).map(({ key, item: part }, idx) => /* @__PURE__ */ jsxs(Fragment, { children: [idx > 0 && /* @__PURE__ */ jsx("span", {
48
75
  className: "opacity-60 text-[11px]",
49
76
  children: "+"
50
77
  }), /* @__PURE__ */ jsx("kbd", {
51
78
  className: "inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded border border-white/30 bg-white/10 font-sans text-[11px] font-semibold leading-none",
52
79
  children: part
53
- })] }, `${part}-${idx}`))
80
+ })] }, key))
54
81
  });
55
82
  }
56
83
  var globalCloseEvents = { escape: true };
@@ -93,4 +120,4 @@ function TooltipInfo({ text, className = "", children, place = "top", tabIndex }
93
120
  });
94
121
  }
95
122
  //#endregion
96
- export { truncationTooltipProps as a, formatTooltipContent as i, TOOLTIP_ID as n, TooltipInfo as r, GlobalTooltip as t };
123
+ export { truncationTooltipProps as a, withPositionKeys as c, formatTooltipContent as i, TOOLTIP_ID as n, keyedByContent as o, TooltipInfo as r, positionKeys as s, GlobalTooltip as t };
@@ -0,0 +1,17 @@
1
+ import { Duration } from "luxon";
2
+ //#region src/duration.ts
3
+ var UnitDisplay = { ja: "short" };
4
+ function durationToAbsHumanDuration(d) {
5
+ const duration = d.shiftTo("days", "hours", "minutes", "seconds").toObject();
6
+ if ("seconds" in duration) duration.seconds = Math.round(duration.seconds);
7
+ const cleanedDuration = Object.fromEntries(Object.entries(duration).filter(([, value]) => value !== 0).map(([key, value]) => [key, Math.abs(value)]));
8
+ if (Object.keys(cleanedDuration).length === 0) cleanedDuration.seconds = 0;
9
+ const human = Duration.fromObject(cleanedDuration);
10
+ const unitDisplay = UnitDisplay[human.locale] || "narrow";
11
+ return human.toHuman({ unitDisplay }).replaceAll(/[,、]/g, "");
12
+ }
13
+ function toAbsHumanDuration(start, end) {
14
+ return durationToAbsHumanDuration(end.diff(start));
15
+ }
16
+ //#endregion
17
+ export { toAbsHumanDuration as n, durationToAbsHumanDuration as t };