@parallelworks/ui 0.18.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.
- package/README.md +86 -6
- package/dist/ai/adapter/memoryStore.d.ts +8 -0
- package/dist/ai/adapter/mock/index.d.ts +2 -0
- package/dist/ai/adapter/mock/index.js +81 -0
- package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
- package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
- package/dist/ai/adapter/openai/errors.d.ts +3 -0
- package/dist/ai/adapter/openai/index.d.ts +6 -0
- package/dist/ai/adapter/openai/index.js +334 -0
- package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
- package/dist/ai/adapter/openai/responses.d.ts +4 -0
- package/dist/ai/adapter/openai/sse.d.ts +24 -0
- package/dist/ai/adapter/openai/wire.d.ts +40 -0
- package/dist/ai/adapter/types.d.ts +131 -0
- package/dist/ai/agent/classifier.d.ts +2 -0
- package/dist/ai/agent/diff.d.ts +35 -0
- package/dist/ai/agent/diffHighlight.d.ts +6 -0
- package/dist/ai/agent/index.d.ts +6 -0
- package/dist/ai/agent/permissions.d.ts +11 -0
- package/dist/ai/agent/toolfmt.d.ts +18 -0
- package/dist/ai/agent/transcript.d.ts +38 -0
- package/dist/ai/ai.css +325 -0
- package/dist/ai/components/AllocationSelector.d.ts +4 -0
- package/dist/ai/components/AttachmentManager.d.ts +1 -0
- package/dist/ai/components/AttachmentUpload.d.ts +24 -0
- package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
- package/dist/ai/components/BranchNavigator.d.ts +8 -0
- package/dist/ai/components/ChatEmptyState.d.ts +3 -0
- package/dist/ai/components/ChatInput.d.ts +45 -0
- package/dist/ai/components/ChatLayout.d.ts +5 -0
- package/dist/ai/components/ChatMessage.d.ts +24 -0
- package/dist/ai/components/ChatMessageList.d.ts +35 -0
- package/dist/ai/components/ChatSidebar.d.ts +5 -0
- package/dist/ai/components/ChatThread.d.ts +3 -0
- package/dist/ai/components/ComposerChrome.d.ts +18 -0
- package/dist/ai/components/ComposerFrame.d.ts +16 -0
- package/dist/ai/components/DragOverlay.d.ts +5 -0
- package/dist/ai/components/ModelSelector.d.ts +6 -0
- package/dist/ai/components/ShareDialog.d.ts +11 -0
- package/dist/ai/components/SlashMenu.d.ts +28 -0
- package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
- package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
- package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
- package/dist/ai/components/attachmentKeys.d.ts +4 -0
- package/dist/ai/core/ChatProvider.d.ts +66 -0
- package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
- package/dist/ai/core/chatReducer.d.ts +114 -0
- package/dist/ai/core/config.d.ts +47 -0
- package/dist/ai/core/events.d.ts +1 -0
- package/dist/ai/core/exportConversation.d.ts +4 -0
- package/dist/ai/core/greeting.d.ts +3 -0
- package/dist/ai/core/parts.d.ts +11 -0
- package/dist/ai/core/useDragDrop.d.ts +14 -0
- package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
- package/dist/ai/core/useSSEStream.d.ts +34 -0
- package/dist/ai/index.d.ts +40 -0
- package/dist/ai/index.js +6645 -0
- package/dist/ai/strings.d.ts +167 -0
- package/dist/ai/types.d.ts +236 -0
- package/dist/ai/ui/Avatar.d.ts +8 -0
- package/dist/ai/ui/Dropdown.d.ts +31 -0
- package/dist/ai/ui/Markdown.d.ts +8 -0
- package/dist/ai/ui/Notice.d.ts +21 -0
- package/dist/ai/ui/buttons.d.ts +1 -0
- package/dist/ai/ui/codeBreaks.d.ts +16 -0
- package/dist/ai/ui/prose.d.ts +1 -0
- package/dist/ai/ui/sidebar.d.ts +81 -0
- package/dist/ai/utils.d.ts +4 -0
- package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
- package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
- package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
- package/dist/chunks/{CodePreviewEditor-4lx3kE-w.js → CodePreviewEditor-YqQBz1YL.js} +1 -1
- package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
- package/dist/chunks/{FieldWrapper-Bef01EWO.js → FieldWrapper-Cszwg-4B.js} +3 -7
- package/dist/chunks/{CreateModal-BY6DLmur.js → Markdown-CM-FenNE.js} +19 -91
- package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
- package/dist/chunks/{PageHeader-l49p1nM9.js → PageHeader-0kG_iypP.js} +67 -65
- package/dist/chunks/{Provider-Ghua9PkN.js → Provider-CDYurraE.js} +54 -20
- package/dist/chunks/{SwitchToggle-CHPP8uZQ.js → SwitchToggle-DShNdcao.js} +135 -132
- package/dist/chunks/{Table-4OHjdKdO.js → Table-DU2MW8xz.js} +5 -3
- package/dist/chunks/{Tooltip-Crxo_eU_.js → Tooltip-K5HJr4_p.js} +31 -4
- package/dist/chunks/duration-BOv8Phl8.js +17 -0
- package/dist/chunks/{editor-9_uVtUyy.js → editor-Dk1rbV75.js} +32 -18
- package/dist/chunks/focus-D_iZJTW1.js +7 -0
- package/dist/chunks/{list-qrojZZNv.js → list-CJm875m7.js} +377 -370
- package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
- package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
- package/dist/chunks/types-Yy0NrerF.js +11 -0
- package/dist/components/Avatar.d.ts +1 -1
- package/dist/components/Breadcrumbs.d.ts +1 -1
- package/dist/components/Dropdown.d.ts +1 -1
- package/dist/components/EmptyState.d.ts +1 -1
- package/dist/components/Indicator.d.ts +2 -2
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/LetterBadge.d.ts +1 -1
- package/dist/components/MarkdownImpl.d.ts +1 -1
- package/dist/components/Provider.d.ts +16 -65
- package/dist/components/SettingRow.d.ts +1 -1
- package/dist/components/SettingsGroup.d.ts +1 -1
- package/dist/components/focus.d.ts +2 -0
- package/dist/components/keys.d.ts +12 -0
- package/dist/duration.d.ts +3 -0
- package/dist/editor/Monaco.d.ts +1 -20
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/index.js +2 -2
- package/dist/editor/yaml.d.ts +5 -0
- package/dist/engine.d.ts +98 -0
- package/dist/file-explorer/FileExplorer.d.ts +11 -2
- package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
- package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
- package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
- package/dist/file-explorer/FileRow.d.ts +1 -1
- package/dist/file-explorer/helpers.d.ts +4 -4
- package/dist/file-explorer/index.d.ts +3 -3
- package/dist/file-explorer/index.js +613 -647
- package/dist/file-explorer/lib/types.d.ts +6 -1
- package/dist/file-explorer/lib/utils.d.ts +1 -3
- package/dist/file-explorer/useNearEnd.d.ts +1 -1
- package/dist/form/FieldWrapper.d.ts +2 -2
- package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
- package/dist/form/Form.d.ts +4 -21
- package/dist/form/index.d.ts +11 -12
- package/dist/form/index.js +1488 -1611
- package/dist/form/lib.d.ts +6 -1
- package/dist/form/types/fieldComponentTypes.d.ts +3 -2
- package/dist/form/types/fieldTypes.d.ts +6 -20
- package/dist/form/useParsedOpts.d.ts +1 -1
- package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
- package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
- package/dist/{workflow → graph}/index.d.ts +1 -1
- package/dist/{workflow → graph}/index.js +215 -180
- package/dist/{workflow → graph}/types.d.ts +3 -3
- package/dist/icons.d.ts +20 -21
- package/dist/index.d.ts +38 -40
- package/dist/index.js +347 -346
- package/dist/list/ListTable.d.ts +1 -1
- package/dist/list/ListViewControls.d.ts +2 -2
- package/dist/list/index.d.ts +9 -9
- package/dist/list/index.js +2 -2
- package/dist/logviewer/LogViewer.d.ts +1 -1
- package/dist/logviewer/index.d.ts +1 -0
- package/dist/logviewer/index.js +2 -742
- package/dist/logviewer/segments.d.ts +9 -0
- package/dist/styles/fonts.css +4 -4
- package/dist/styles/theme.css +6 -4
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +2 -2
- package/package.json +38 -14
- package/LICENSE +0 -202
- package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
- package/dist/editor/usesGitlab.d.ts +0 -97
- package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
- package/dist/form/types/workflow-schema.d.ts +0 -1145
- package/dist/form/utils/pwResolver.d.ts +0 -18
- package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
- /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
- /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
- /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
- /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
- /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
- /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useContext, useMemo } from "react";
|
|
1
|
+
import { createContext, use, useCallback, useContext, useEffect, useMemo } from "react";
|
|
2
2
|
import { useLocalStorage } from "usehooks-ts";
|
|
3
3
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/Provider.tsx
|
|
@@ -85,7 +85,7 @@ var DEFAULTS = {
|
|
|
85
85
|
timeRangeActive: "Time range active",
|
|
86
86
|
timeRangeOn: "ON",
|
|
87
87
|
filterByTimeRange: "Filter by time range",
|
|
88
|
-
timeRangeHelp: "Times are interpreted in your local timezone. Applying a range re-queries the
|
|
88
|
+
timeRangeHelp: "Times are interpreted in your local timezone. Applying a range re-queries the log source and replaces what is loaded. Setting an end time stops live tailing until you clear it.",
|
|
89
89
|
timeRangeFrom: "From",
|
|
90
90
|
timeRangeTo: "To",
|
|
91
91
|
apply: "Apply",
|
|
@@ -188,7 +188,7 @@ var DEFAULTS = {
|
|
|
188
188
|
},
|
|
189
189
|
propagating: {
|
|
190
190
|
title: "Propagating CORS rules",
|
|
191
|
-
description: "
|
|
191
|
+
description: "The storage provider is rolling out the new rules to its endpoints. This usually completes within a minute.",
|
|
192
192
|
stages: {
|
|
193
193
|
submitted: "Submitted",
|
|
194
194
|
propagating: "Propagating",
|
|
@@ -246,6 +246,7 @@ var DEFAULTS = {
|
|
|
246
246
|
collapse: "Collapse",
|
|
247
247
|
upload: "Upload",
|
|
248
248
|
download: "Download",
|
|
249
|
+
downloadFromBrowser: "From browser",
|
|
249
250
|
access: "Access",
|
|
250
251
|
manageAccess: "Manage Access",
|
|
251
252
|
delete: "Delete",
|
|
@@ -319,11 +320,7 @@ var DEFAULTS = {
|
|
|
319
320
|
form: {
|
|
320
321
|
invalidDuration: "Enter a duration as DD-HH:MM:SS or HH:MM:SS.",
|
|
321
322
|
durationOutOfRange: (min, max) => `Must be between ${min} and ${max}.`,
|
|
322
|
-
durationBelowMin: (min) => `Must be at least ${min}
|
|
323
|
-
readOnly: "Read-only",
|
|
324
|
-
readWrite: "Read-write",
|
|
325
|
-
readOnlyDescription: "Read-only mounts can list and download objects, but cannot upload, modify, or delete them.",
|
|
326
|
-
readOnlyForced: "Your access to this bucket is read-only, so this mount cannot be writable."
|
|
323
|
+
durationBelowMin: (min) => `Must be at least ${min}.`
|
|
327
324
|
},
|
|
328
325
|
time: {
|
|
329
326
|
now: "now",
|
|
@@ -392,8 +389,8 @@ var DEFAULTS = {
|
|
|
392
389
|
className: "font-medium",
|
|
393
390
|
children: startTime
|
|
394
391
|
}),
|
|
392
|
+
" to",
|
|
395
393
|
" ",
|
|
396
|
-
"to ",
|
|
397
394
|
/* @__PURE__ */ jsx("span", {
|
|
398
395
|
className: "font-medium",
|
|
399
396
|
children: endTime
|
|
@@ -403,8 +400,9 @@ var DEFAULTS = {
|
|
|
403
400
|
},
|
|
404
401
|
navigation: {
|
|
405
402
|
goTo: (to) => window.location.assign(to),
|
|
406
|
-
|
|
407
|
-
|
|
403
|
+
openStepSource: (_uses, sourceUrl) => {
|
|
404
|
+
if (sourceUrl) window.open(sourceUrl, "_blank");
|
|
405
|
+
},
|
|
408
406
|
openExternal: (href) => window.open(href, "_blank")
|
|
409
407
|
},
|
|
410
408
|
data: {
|
|
@@ -426,15 +424,46 @@ function useNavigation() {
|
|
|
426
424
|
function useSlots() {
|
|
427
425
|
return useContext(UIContext).slots;
|
|
428
426
|
}
|
|
429
|
-
|
|
430
|
-
|
|
427
|
+
var loadedEngines = /* @__PURE__ */ new WeakMap();
|
|
428
|
+
function loadEngine(load) {
|
|
429
|
+
let entry = loadedEngines.get(load);
|
|
430
|
+
if (!entry) {
|
|
431
|
+
const created = { promise: load() };
|
|
432
|
+
created.promise.then((engine) => {
|
|
433
|
+
created.engine = engine;
|
|
434
|
+
});
|
|
435
|
+
loadedEngines.set(load, created);
|
|
436
|
+
entry = created;
|
|
437
|
+
}
|
|
438
|
+
return entry;
|
|
439
|
+
}
|
|
440
|
+
function resolveEngine(source) {
|
|
441
|
+
if (typeof source !== "function") return source;
|
|
442
|
+
const entry = loadEngine(source);
|
|
443
|
+
return entry.engine ?? use(entry.promise);
|
|
444
|
+
}
|
|
445
|
+
/** The engine when one is provided and `enabled`; suspends while a loader resolves. */
|
|
446
|
+
function useOptionalWorkflowEngine(enabled = true) {
|
|
447
|
+
const source = useContext(UIContext).engine;
|
|
448
|
+
if (!enabled || !source) return;
|
|
449
|
+
return resolveEngine(source);
|
|
450
|
+
}
|
|
451
|
+
function useWorkflowEngine() {
|
|
452
|
+
const source = useContext(UIContext).engine;
|
|
453
|
+
if (!source) throw new Error("Workflow forms and graphs need a UIProvider with an engine.");
|
|
454
|
+
return resolveEngine(source);
|
|
455
|
+
}
|
|
456
|
+
/** Resolves the engine without suspending, for async callers such as editor completions. */
|
|
457
|
+
function useWorkflowEngineLoader() {
|
|
458
|
+
const source = useContext(UIContext).engine;
|
|
459
|
+
return useCallback(async () => {
|
|
460
|
+
if (!source) return;
|
|
461
|
+
return typeof source === "function" ? loadEngine(source).promise : source;
|
|
462
|
+
}, [source]);
|
|
431
463
|
}
|
|
432
464
|
function useProvisionCorsRules() {
|
|
433
465
|
return useContext(UIContext).data.provisionCorsRules;
|
|
434
466
|
}
|
|
435
|
-
function useRepoSuggestions() {
|
|
436
|
-
return useContext(UIContext).data.repoSuggestions;
|
|
437
|
-
}
|
|
438
467
|
function useRunFile(slug, path, options) {
|
|
439
468
|
const { useRunFile: boundUseRunFile } = useContext(UIContext).data;
|
|
440
469
|
return boundUseRunFile(slug, path, options);
|
|
@@ -443,7 +472,10 @@ function usePersistedState(key, defaultValue) {
|
|
|
443
472
|
const { usePersistedState: boundUsePersistedState } = useContext(UIContext).data;
|
|
444
473
|
return boundUsePersistedState(key, defaultValue);
|
|
445
474
|
}
|
|
446
|
-
function UIProvider({ notify, strings, navigation, data, slots, children }) {
|
|
475
|
+
function UIProvider({ notify, strings, navigation, data, slots, engine, children }) {
|
|
476
|
+
useEffect(() => {
|
|
477
|
+
if (typeof engine === "function") loadEngine(engine);
|
|
478
|
+
}, [engine]);
|
|
447
479
|
const value = useMemo(() => ({
|
|
448
480
|
notify: {
|
|
449
481
|
...DEFAULTS.notify,
|
|
@@ -500,13 +532,15 @@ function UIProvider({ notify, strings, navigation, data, slots, children }) {
|
|
|
500
532
|
...DEFAULTS.data,
|
|
501
533
|
...data
|
|
502
534
|
},
|
|
503
|
-
slots: slots ?? DEFAULTS.slots
|
|
535
|
+
slots: slots ?? DEFAULTS.slots,
|
|
536
|
+
engine
|
|
504
537
|
}), [
|
|
505
538
|
notify,
|
|
506
539
|
strings,
|
|
507
540
|
navigation,
|
|
508
541
|
data,
|
|
509
|
-
slots
|
|
542
|
+
slots,
|
|
543
|
+
engine
|
|
510
544
|
]);
|
|
511
545
|
return /* @__PURE__ */ jsx(UIContext.Provider, {
|
|
512
546
|
value,
|
|
@@ -514,4 +548,4 @@ function UIProvider({ notify, strings, navigation, data, slots, children }) {
|
|
|
514
548
|
});
|
|
515
549
|
}
|
|
516
550
|
//#endregion
|
|
517
|
-
export {
|
|
551
|
+
export { useOptionalWorkflowEngine as a, useRunFile as c, useWorkflowEngine as d, useWorkflowEngineLoader as f, useNotify as i, useSlots as l, useLink as n, usePersistedState as o, useNavigation as r, useProvisionCorsRules as s, UIProvider as t, useStrings as u };
|
|
@@ -1,22 +1,91 @@
|
|
|
1
|
-
import { u as useStrings } from "./Provider-
|
|
1
|
+
import { u as useStrings } from "./Provider-CDYurraE.js";
|
|
2
2
|
import { AngleDownIcon, AngleRightIcon, CaretDownIcon } from "../icons.js";
|
|
3
|
-
import { a as truncationTooltipProps, n as TOOLTIP_ID } from "./Tooltip-
|
|
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
8
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
7
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
10
|
import { createPortal } from "react-dom";
|
|
9
|
-
import
|
|
11
|
+
import AnimateHeight from "react-animate-height";
|
|
10
12
|
import deepEqual from "fast-deep-equal";
|
|
11
13
|
import { usePopper } from "react-popper";
|
|
12
|
-
|
|
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
|
|
16
|
-
|
|
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)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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:
|
|
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:
|
|
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
|
}
|
|
@@ -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:
|
|
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) => {
|
|
@@ -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
|
-
|
|
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((
|
|
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
|
-
}
|
|
424
|
-
},
|
|
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",
|
|
@@ -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
|
-
|
|
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((
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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$1, { 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 {
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { u as useStrings } from "./Provider-
|
|
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
4
|
import React from "react";
|
|
@@ -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", !
|
|
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", !
|
|
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", {
|
|
@@ -2,6 +2,32 @@ import { TooltipIcon } from "../icons.js";
|
|
|
2
2
|
import { Fragment } from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
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, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] },
|
|
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:
|
|
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
|
-
})] },
|
|
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 };
|