@flamingo-stack/openframe-frontend-core 0.0.716 → 0.0.718
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/chat-protocol/index.cjs +23 -14
- package/dist/chat-protocol/index.js +23 -14
- package/dist/chat-protocol/nats-decoder.d.ts.map +1 -1
- package/dist/chat-protocol/source-metadata.d.ts +11 -2
- package/dist/chat-protocol/source-metadata.d.ts.map +1 -1
- package/dist/{chunk-DPX6244M.js → chunk-45F7PXUI.js} +3 -3
- package/dist/{chunk-KYFNFRSV.js → chunk-67QBMN4R.js} +2 -2
- package/dist/{chunk-3RKBJT6K.cjs → chunk-6A43ZDWV.cjs} +2 -2
- package/dist/chunk-A6P6DHEZ.cjs +130 -0
- package/dist/{chunk-KNOZVVCU.cjs → chunk-BOTM373R.cjs} +9 -9
- package/dist/{chunk-DHMO5GI4.cjs → chunk-BWIN42ZA.cjs} +21 -21
- package/dist/{chunk-YTMV4OBY.js → chunk-DCD5WZUF.js} +4 -4
- package/dist/{chunk-V36WGIYR.js → chunk-DEZDMTBM.js} +5 -5
- package/dist/{chunk-YO5JB3WE.cjs → chunk-DXCBOZVT.cjs} +35 -35
- package/dist/{chunk-ZX7SCPLO.cjs → chunk-E7YCPY7K.cjs} +3 -3
- package/dist/{chunk-I5F2OTFE.cjs → chunk-EZC2F5OT.cjs} +33 -33
- package/dist/{chunk-DLEO53NX.cjs → chunk-GN4A7PMB.cjs} +69 -69
- package/dist/{chunk-6T3BTD6Q.js → chunk-IWCPXJEE.js} +201 -327
- package/dist/{chunk-ROBQ5TR7.js → chunk-JH2SIWPQ.js} +28 -17
- package/dist/{chunk-3AJIQPFG.js → chunk-JIWMBIVZ.js} +6 -6
- package/dist/{chunk-DDWFCWOE.js → chunk-JPD4NXH6.js} +1 -1
- package/dist/{chunk-JVCAK4W3.cjs → chunk-LE5WKGJV.cjs} +3 -3
- package/dist/{chunk-NPAQSMRY.js → chunk-LOYPRJWA.js} +1053 -357
- package/dist/{chunk-5IJXM3RU.cjs → chunk-MIQLUUVF.cjs} +10 -10
- package/dist/{chunk-MXPQMQI3.js → chunk-MM7MCIXL.js} +6 -6
- package/dist/{chunk-C5AGSZBT.js → chunk-N2PF5CFX.js} +4837 -5425
- package/dist/{chunk-STCJYO2Z.cjs → chunk-NDZ5ZXOQ.cjs} +11 -11
- package/dist/{chunk-H5R7U2D2.js → chunk-NZ5BHDFZ.js} +1 -1
- package/dist/{chunk-JCA5MBVY.js → chunk-PQ6HBLZ7.js} +4 -4
- package/dist/{chunk-EOKSKJSS.cjs → chunk-QBCDSTLE.cjs} +13 -13
- package/dist/{chunk-NQWJAOHO.js → chunk-QXZCLQNV.js} +1 -1
- package/dist/{chunk-2V7D5GJX.cjs → chunk-S2FUFMLW.cjs} +25 -25
- package/dist/{chunk-64F6OEEV.js → chunk-SGFTTJKO.js} +1 -1
- package/dist/{chunk-P7IL4CX3.js → chunk-TBCZCRQ5.js} +6 -6
- package/dist/{chunk-HETQETPV.cjs → chunk-UWQWMGJ7.cjs} +28 -17
- package/dist/{chunk-X2MNNV5H.cjs → chunk-WALCXC7J.cjs} +3 -3
- package/dist/{chunk-YBS5QGON.js → chunk-XGHGGBM3.js} +2 -2
- package/dist/{chunk-NKILEG3Y.cjs → chunk-YC5COB5V.cjs} +45 -45
- package/dist/{chunk-BVZ7W4HW.js → chunk-YEMCCYIF.js} +4 -4
- package/dist/chunk-YYYVS7CX.js +130 -0
- package/dist/{chunk-S2VWQX6T.cjs → chunk-Z3CVSPO3.cjs} +842 -1430
- package/dist/{chunk-PPXR22YC.cjs → chunk-Z5UWW3Z2.cjs} +707 -11
- package/dist/{chunk-JO5TLJPM.cjs → chunk-ZXCZYMN4.cjs} +37 -163
- package/dist/{cloud-tenants-2J7CPTKT.cjs → cloud-tenants-PFDF7O5U.cjs} +6 -5
- package/dist/{cloud-tenants-YOY2WLGC.js → cloud-tenants-TAKOWXLD.js} +5 -4
- package/dist/components/case-studies/index.cjs +17 -16
- package/dist/components/case-studies/index.js +6 -5
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/types/message.types.d.ts +20 -16
- package/dist/components/chat/types/message.types.d.ts.map +1 -1
- package/dist/components/chat/types/unified-chat-state.types.d.ts +1 -1
- package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +7 -6
- package/dist/components/contact/index.js +6 -5
- package/dist/components/docs/index.cjs +10 -9
- package/dist/components/docs/index.js +9 -8
- package/dist/components/embeds/index.cjs +7 -6
- package/dist/components/embeds/index.js +6 -5
- package/dist/components/faq/index.cjs +7 -6
- package/dist/components/faq/index.js +6 -5
- package/dist/components/features/index.cjs +10 -5
- package/dist/components/features/index.js +9 -4
- package/dist/components/features/remote-session/index.d.ts +2 -0
- package/dist/components/features/remote-session/index.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-keep-modals.d.ts +3 -3
- package/dist/components/features/remote-session/remote-session-keep-modals.d.ts.map +1 -1
- package/dist/components/features/remote-session/remote-session-ticket-modals.d.ts +29 -0
- package/dist/components/features/remote-session/remote-session-ticket-modals.d.ts.map +1 -0
- package/dist/components/help-center-pages/index.cjs +71 -70
- package/dist/components/help-center-pages/index.js +17 -16
- package/dist/components/index.cjs +44 -39
- package/dist/components/index.js +22 -17
- package/dist/components/meeting-scheduler/index.cjs +33 -32
- package/dist/components/meeting-scheduler/index.js +5 -4
- package/dist/components/navigation/index.cjs +9 -8
- package/dist/components/navigation/index.js +8 -7
- package/dist/components/onboarding-guides/index.cjs +9 -8
- package/dist/components/onboarding-guides/index.js +8 -7
- package/dist/components/product-demo/index.cjs +7 -7
- package/dist/components/product-demo/index.js +7 -7
- package/dist/components/tickets/index.cjs +10 -9
- package/dist/components/tickets/index.js +9 -8
- package/dist/components/ui/autocomplete.d.ts +6 -0
- package/dist/components/ui/autocomplete.d.ts.map +1 -1
- package/dist/components/ui/index.cjs +8 -7
- package/dist/components/ui/index.js +7 -6
- package/dist/{devices-5NADSKDZ.cjs → devices-KRCGZMGA.cjs} +7 -6
- package/dist/{devices-EQXXILXW.js → devices-LHEX7O5T.js} +5 -4
- package/dist/hooks/index.cjs +6 -4
- package/dist/hooks/index.js +5 -3
- package/dist/index.cjs +17 -11
- package/dist/index.js +18 -12
- package/dist/{knowledge-LHQYZJE7.cjs → knowledge-KLVPVEYZ.cjs} +7 -6
- package/dist/{knowledge-YCQITBJB.js → knowledge-RZSFNR33.js} +5 -4
- package/dist/{logs-LZNXGOSW.js → logs-E5DOV5JO.js} +5 -4
- package/dist/{logs-DUVKSQU3.cjs → logs-OX3XTVL2.cjs} +14 -13
- package/dist/{policies-5H74FS4S.cjs → policies-FOSCIZGK.cjs} +10 -9
- package/dist/{policies-VYWOJ7IF.js → policies-MC2S4S5G.js} +5 -4
- package/dist/{remote-session-R6VAFESR.cjs → remote-session-DRFE5XZE.cjs} +4 -3
- package/dist/{remote-session-GSGZOFDX.js → remote-session-JQ2BPIE3.js} +2 -1
- package/dist/{software-update-MSDY3OLX.js → software-update-D4OEIH65.js} +7 -5
- package/dist/{software-update-VRRX5U4W.cjs → software-update-HOBSTWVO.cjs} +12 -10
- package/package.json +1 -1
- package/src/chat-protocol/nats-decoder.ts +10 -8
- package/src/chat-protocol/source-metadata.ts +25 -2
- package/src/components/chat/types/message.types.ts +21 -15
- package/src/components/chat/types/unified-chat-state.types.ts +1 -1
- package/src/components/chat/utils/process-historical-messages.ts +12 -4
- package/src/components/features/remote-session/index.ts +2 -0
- package/src/components/features/remote-session/remote-session-keep-modals.tsx +4 -4
- package/src/components/features/remote-session/remote-session-ticket-modals.tsx +140 -0
- package/src/components/ui/autocomplete.tsx +18 -4
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
useAutoLimitTags,
|
|
4
|
+
useKeyboardCollisionPadding
|
|
5
|
+
} from "./chunk-YYYVS7CX.js";
|
|
2
6
|
import {
|
|
3
7
|
ChatInput,
|
|
4
8
|
Modal,
|
|
@@ -53,7 +57,9 @@ import {
|
|
|
53
57
|
MonitorOffIcon,
|
|
54
58
|
RecordingIcon,
|
|
55
59
|
Send03Icon,
|
|
56
|
-
Settings01Icon
|
|
60
|
+
Settings01Icon,
|
|
61
|
+
TrashIcon,
|
|
62
|
+
XmarkCircleIcon
|
|
57
63
|
} from "./chunk-NCPTID44.js";
|
|
58
64
|
import {
|
|
59
65
|
MonitorIcon
|
|
@@ -82,8 +88,63 @@ import {
|
|
|
82
88
|
cn
|
|
83
89
|
} from "./chunk-7RXWKTAP.js";
|
|
84
90
|
|
|
91
|
+
// src/components/ui/hidden-tags-popup.tsx
|
|
92
|
+
import { forwardRef } from "react";
|
|
93
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
94
|
+
var HiddenTagsPopup = forwardRef(function HiddenTagsPopupImpl({ items, onRemove, disabled, className, style }, ref) {
|
|
95
|
+
return /* @__PURE__ */ jsx(
|
|
96
|
+
"div",
|
|
97
|
+
{
|
|
98
|
+
ref,
|
|
99
|
+
style,
|
|
100
|
+
className: cn(
|
|
101
|
+
// Base positioning is neutral (left-anchored); consumers override via
|
|
102
|
+
// `style.left` (search-input, tag-search-input) or `className` (autocomplete).
|
|
103
|
+
"absolute left-0 top-full z-50 mt-1 min-w-[200px]",
|
|
104
|
+
"rounded-[6px] border border-ods-border bg-ods-card shadow-lg",
|
|
105
|
+
"duration-150 animate-in fade-in-0 zoom-in-95",
|
|
106
|
+
className
|
|
107
|
+
),
|
|
108
|
+
children: items.map((item) => /* @__PURE__ */ jsxs(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
className: cn(
|
|
112
|
+
"flex h-11 items-center justify-between gap-3 px-3 md:h-12",
|
|
113
|
+
"border-b border-ods-border last:border-b-0"
|
|
114
|
+
),
|
|
115
|
+
children: [
|
|
116
|
+
/* @__PURE__ */ jsx(
|
|
117
|
+
"span",
|
|
118
|
+
{
|
|
119
|
+
className: "min-w-0 flex-1 truncate uppercase text-ods-text-primary text-h5",
|
|
120
|
+
title: typeof item.label === "string" ? item.label : void 0,
|
|
121
|
+
children: item.label
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
!disabled && onRemove && /* @__PURE__ */ jsx(
|
|
125
|
+
"button",
|
|
126
|
+
{
|
|
127
|
+
type: "button",
|
|
128
|
+
onClick: (e) => {
|
|
129
|
+
e.stopPropagation();
|
|
130
|
+
onRemove(item.value);
|
|
131
|
+
},
|
|
132
|
+
className: "shrink-0 text-ods-text-secondary transition-colors hover:text-ods-text-primary",
|
|
133
|
+
"aria-label": `Remove ${String(item.label)}`,
|
|
134
|
+
children: /* @__PURE__ */ jsx(XmarkCircleIcon, { size: 20 })
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
String(item.value)
|
|
140
|
+
))
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
HiddenTagsPopup.displayName = "HiddenTagsPopup";
|
|
145
|
+
|
|
85
146
|
// src/components/ui/truncate-text.tsx
|
|
86
|
-
import { jsx } from "react/jsx-runtime";
|
|
147
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
87
148
|
var VARIANT_CLASS = {
|
|
88
149
|
h1: "text-h1",
|
|
89
150
|
h2: "text-h2",
|
|
@@ -118,7 +179,7 @@ function TruncateText({
|
|
|
118
179
|
const isMultiLine = lines > 1;
|
|
119
180
|
const { ref, isTruncated } = useIsTruncated(children, { multiline: isMultiLine });
|
|
120
181
|
const clampClass = isMultiLine ? LINE_CLAMP_CLASS[lines] : "truncate block";
|
|
121
|
-
return /* @__PURE__ */
|
|
182
|
+
return /* @__PURE__ */ jsx2(
|
|
122
183
|
FloatingTooltip,
|
|
123
184
|
{
|
|
124
185
|
content: tooltip ?? children,
|
|
@@ -127,7 +188,7 @@ function TruncateText({
|
|
|
127
188
|
className: "max-w-xs whitespace-pre-line [overflow-wrap:anywhere]",
|
|
128
189
|
as,
|
|
129
190
|
triggerClassName: cn("min-w-0 max-w-full", as === "span" && "inline-block align-bottom", triggerClassName),
|
|
130
|
-
children: /* @__PURE__ */
|
|
191
|
+
children: /* @__PURE__ */ jsx2(
|
|
131
192
|
"span",
|
|
132
193
|
{
|
|
133
194
|
ref,
|
|
@@ -145,19 +206,564 @@ function TruncateText({
|
|
|
145
206
|
);
|
|
146
207
|
}
|
|
147
208
|
|
|
209
|
+
// src/components/ui/autocomplete.tsx
|
|
210
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
211
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
212
|
+
import { Loader2 } from "lucide-react";
|
|
213
|
+
import {
|
|
214
|
+
forwardRef as forwardRef2,
|
|
215
|
+
useEffect,
|
|
216
|
+
useImperativeHandle,
|
|
217
|
+
useMemo,
|
|
218
|
+
useRef,
|
|
219
|
+
useState
|
|
220
|
+
} from "react";
|
|
221
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
222
|
+
var innerInputStyles = cn(
|
|
223
|
+
"min-w-[60px] flex-1 border-none bg-transparent outline-none",
|
|
224
|
+
"text-h4",
|
|
225
|
+
"text-ods-text-primary placeholder:text-ods-text-secondary",
|
|
226
|
+
// Disabled - match Input exactly (value greys out, placeholder dims further)
|
|
227
|
+
"disabled:cursor-not-allowed disabled:text-ods-text-disabled disabled:placeholder:text-ods-border"
|
|
228
|
+
);
|
|
229
|
+
function AutocompleteInner(props, ref) {
|
|
230
|
+
const {
|
|
231
|
+
options,
|
|
232
|
+
disabled = false,
|
|
233
|
+
startAdornment,
|
|
234
|
+
showClearAll = true,
|
|
235
|
+
className,
|
|
236
|
+
dropdownClassName,
|
|
237
|
+
freeSolo = false,
|
|
238
|
+
label,
|
|
239
|
+
labelVariant,
|
|
240
|
+
error,
|
|
241
|
+
filterOptions,
|
|
242
|
+
renderOption,
|
|
243
|
+
invalid = false,
|
|
244
|
+
noOptionsText = "No options",
|
|
245
|
+
inputValue: inputValueProp,
|
|
246
|
+
onInputChange,
|
|
247
|
+
loading = false,
|
|
248
|
+
loadingText = "Loading...",
|
|
249
|
+
creatable = false,
|
|
250
|
+
onCreateOption,
|
|
251
|
+
maxCreateLength,
|
|
252
|
+
onDeleteOption,
|
|
253
|
+
isDeletingOption = false,
|
|
254
|
+
disableClientFilter = false,
|
|
255
|
+
showChevron = true,
|
|
256
|
+
clearOnOpen = true
|
|
257
|
+
} = props;
|
|
258
|
+
const multiple = props.multiple ?? false;
|
|
259
|
+
const placeholder = props.placeholder ?? (multiple ? "Add More..." : "Select...");
|
|
260
|
+
const maxItems = multiple ? props.maxItems : void 0;
|
|
261
|
+
const renderTag = multiple ? props.renderTag : void 0;
|
|
262
|
+
const wrapTags = multiple && (props.wrapTags ?? false);
|
|
263
|
+
const limitTagsProp = multiple ? props.limitTags ?? "auto" : "auto";
|
|
264
|
+
const getLimitTagsText = multiple ? props.getLimitTagsText ?? ((more) => `+${more}`) : (more) => `+${more}`;
|
|
265
|
+
const valueArray = useMemo(
|
|
266
|
+
() => multiple ? props.value : props.value != null ? [props.value] : [],
|
|
267
|
+
[multiple, props.value]
|
|
268
|
+
);
|
|
269
|
+
const [internalInputValue, setInternalInputValue] = useState("");
|
|
270
|
+
const isInputControlled = inputValueProp !== void 0;
|
|
271
|
+
const inputValue = isInputControlled ? inputValueProp : internalInputValue;
|
|
272
|
+
const updateInputValue = (value, reason) => {
|
|
273
|
+
if (!isInputControlled) {
|
|
274
|
+
setInternalInputValue(value);
|
|
275
|
+
}
|
|
276
|
+
onInputChange?.(value, reason);
|
|
277
|
+
};
|
|
278
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
279
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
280
|
+
const keyboardPadding = useKeyboardCollisionPadding();
|
|
281
|
+
const containerRef = useRef(null);
|
|
282
|
+
const hiddenTagsPopupRef = useRef(null);
|
|
283
|
+
const isInvalid = invalid || !!error;
|
|
284
|
+
useImperativeHandle(ref, () => containerRef.current);
|
|
285
|
+
const selectedOptions = useMemo(() => {
|
|
286
|
+
return valueArray.map((v) => options.find((opt) => opt.value === v) ?? { label: String(v), value: v });
|
|
287
|
+
}, [valueArray, options]);
|
|
288
|
+
const selectedOption = !multiple && selectedOptions.length > 0 ? selectedOptions[0] : null;
|
|
289
|
+
const resolvedStartAdornment = startAdornment ?? selectedOption?.icon ?? null;
|
|
290
|
+
const inputPlaceholder = multiple ? valueArray.length === 0 ? placeholder : "Add More..." : placeholder;
|
|
291
|
+
const {
|
|
292
|
+
visibleCount: autoVisibleCount,
|
|
293
|
+
middleRef,
|
|
294
|
+
measureRef,
|
|
295
|
+
textMeasureRef,
|
|
296
|
+
badgeRef,
|
|
297
|
+
inputRef
|
|
298
|
+
} = useAutoLimitTags({
|
|
299
|
+
count: multiple ? selectedOptions.length : 0,
|
|
300
|
+
limitTags: multiple ? wrapTags ? selectedOptions.length : limitTagsProp : 0,
|
|
301
|
+
placeholder: inputPlaceholder
|
|
302
|
+
});
|
|
303
|
+
const visibleCount = multiple ? autoVisibleCount : 0;
|
|
304
|
+
const visibleTags = multiple ? selectedOptions.slice(0, visibleCount) : [];
|
|
305
|
+
const hiddenTags = multiple ? selectedOptions.slice(visibleCount) : [];
|
|
306
|
+
const hiddenTagsCount = multiple ? selectedOptions.length - visibleCount : 0;
|
|
307
|
+
const [showHiddenTags, setShowHiddenTags] = useState(false);
|
|
308
|
+
const hiddenTagsRef = useRef(null);
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
if (!showHiddenTags) return void 0;
|
|
311
|
+
const handleClick = (e) => {
|
|
312
|
+
const target = e.target;
|
|
313
|
+
const inButton = hiddenTagsRef.current?.contains(target);
|
|
314
|
+
const inPopup = hiddenTagsPopupRef.current?.contains(target);
|
|
315
|
+
if (!inButton && !inPopup) {
|
|
316
|
+
setShowHiddenTags(false);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
document.addEventListener("mousedown", handleClick);
|
|
320
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
321
|
+
}, [showHiddenTags]);
|
|
322
|
+
const openDropdown = () => {
|
|
323
|
+
if (!multiple && !clearOnOpen && selectedOption) {
|
|
324
|
+
updateInputValue(selectedOption.label, "reset");
|
|
325
|
+
}
|
|
326
|
+
setShowHiddenTags(false);
|
|
327
|
+
setIsOpen(true);
|
|
328
|
+
};
|
|
329
|
+
const inputDisplayValue = !multiple && !isOpen && selectedOption ? selectedOption.label : inputValue;
|
|
330
|
+
const filteredOptions = useMemo(() => {
|
|
331
|
+
if (disableClientFilter) {
|
|
332
|
+
return options;
|
|
333
|
+
}
|
|
334
|
+
if (filterOptions) {
|
|
335
|
+
return filterOptions(options, inputValue);
|
|
336
|
+
}
|
|
337
|
+
if (!inputValue.trim()) {
|
|
338
|
+
return options;
|
|
339
|
+
}
|
|
340
|
+
const lowerInput = inputValue.toLowerCase();
|
|
341
|
+
return options.filter((opt) => opt.label.toLowerCase().includes(lowerInput));
|
|
342
|
+
}, [options, inputValue, filterOptions, disableClientFilter]);
|
|
343
|
+
const showCreateOption = creatable && inputValue.trim().length > 0 && filteredOptions.length === 0;
|
|
344
|
+
const isCreateTooLong = maxCreateLength != null && inputValue.trim().length > maxCreateLength;
|
|
345
|
+
const handleCreate = () => {
|
|
346
|
+
const trimmed = inputValue.trim();
|
|
347
|
+
if (!trimmed || maxCreateLength != null && trimmed.length > maxCreateLength) return;
|
|
348
|
+
const newValue = trimmed;
|
|
349
|
+
if (multiple) {
|
|
350
|
+
if (maxItems && valueArray.length >= maxItems) return;
|
|
351
|
+
props.onChange([...valueArray, newValue]);
|
|
352
|
+
} else {
|
|
353
|
+
props.onChange(newValue);
|
|
354
|
+
}
|
|
355
|
+
updateInputValue("", "reset");
|
|
356
|
+
setIsOpen(false);
|
|
357
|
+
onCreateOption?.(trimmed);
|
|
358
|
+
};
|
|
359
|
+
const [highlightedFor, setHighlightedFor] = useState(filteredOptions.length);
|
|
360
|
+
if (highlightedFor !== filteredOptions.length) {
|
|
361
|
+
setHighlightedFor(filteredOptions.length);
|
|
362
|
+
setHighlightedIndex(-1);
|
|
363
|
+
}
|
|
364
|
+
const handleInputChange = (e) => {
|
|
365
|
+
updateInputValue(e.target.value, "input");
|
|
366
|
+
if (!isOpen) {
|
|
367
|
+
setIsOpen(true);
|
|
368
|
+
}
|
|
369
|
+
setHighlightedIndex(-1);
|
|
370
|
+
};
|
|
371
|
+
const handleSelect = (option) => {
|
|
372
|
+
if (multiple) {
|
|
373
|
+
const isSelected = valueArray.includes(option.value);
|
|
374
|
+
if (isSelected) {
|
|
375
|
+
props.onChange(valueArray.filter((v) => v !== option.value));
|
|
376
|
+
} else {
|
|
377
|
+
if (maxItems && valueArray.length >= maxItems) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
props.onChange([...valueArray, option.value]);
|
|
381
|
+
}
|
|
382
|
+
updateInputValue("", "reset");
|
|
383
|
+
inputRef.current?.focus();
|
|
384
|
+
} else {
|
|
385
|
+
props.onChange(option.value);
|
|
386
|
+
updateInputValue(clearOnOpen ? "" : option.label, "reset");
|
|
387
|
+
setIsOpen(false);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
const handleClearAll = (e) => {
|
|
391
|
+
e.stopPropagation();
|
|
392
|
+
e.preventDefault();
|
|
393
|
+
if (multiple) {
|
|
394
|
+
props.onChange([]);
|
|
395
|
+
} else {
|
|
396
|
+
props.onChange(null);
|
|
397
|
+
}
|
|
398
|
+
if (!isInputControlled) {
|
|
399
|
+
setInternalInputValue("");
|
|
400
|
+
}
|
|
401
|
+
onInputChange?.("", "clear");
|
|
402
|
+
setIsOpen(false);
|
|
403
|
+
};
|
|
404
|
+
const handleKeyDown = (e) => {
|
|
405
|
+
switch (e.key) {
|
|
406
|
+
case "ArrowDown":
|
|
407
|
+
e.preventDefault();
|
|
408
|
+
if (!isOpen) {
|
|
409
|
+
openDropdown();
|
|
410
|
+
}
|
|
411
|
+
setHighlightedIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : 0);
|
|
412
|
+
break;
|
|
413
|
+
case "ArrowUp":
|
|
414
|
+
e.preventDefault();
|
|
415
|
+
setHighlightedIndex((prev) => prev > 0 ? prev - 1 : filteredOptions.length - 1);
|
|
416
|
+
break;
|
|
417
|
+
case "Enter":
|
|
418
|
+
e.preventDefault();
|
|
419
|
+
if (showCreateOption) {
|
|
420
|
+
handleCreate();
|
|
421
|
+
} else if (highlightedIndex >= 0 && filteredOptions[highlightedIndex]) {
|
|
422
|
+
handleSelect(filteredOptions[highlightedIndex]);
|
|
423
|
+
} else if (freeSolo && inputValue.trim()) {
|
|
424
|
+
const newOption = {
|
|
425
|
+
label: inputValue.trim(),
|
|
426
|
+
value: inputValue.trim()
|
|
427
|
+
};
|
|
428
|
+
handleSelect(newOption);
|
|
429
|
+
}
|
|
430
|
+
break;
|
|
431
|
+
case "Escape": {
|
|
432
|
+
const resetValue = !multiple && !clearOnOpen && selectedOption ? selectedOption.label : "";
|
|
433
|
+
updateInputValue(resetValue, "reset");
|
|
434
|
+
setIsOpen(false);
|
|
435
|
+
setHighlightedIndex(-1);
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
case "Backspace":
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
const handleOpenChange = (open) => {
|
|
443
|
+
if (open) {
|
|
444
|
+
openDropdown();
|
|
445
|
+
} else {
|
|
446
|
+
const resetValue = !multiple && !clearOnOpen && selectedOption ? selectedOption.label : "";
|
|
447
|
+
updateInputValue(resetValue, "reset");
|
|
448
|
+
setIsOpen(false);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
const canAddMore = multiple ? !maxItems || valueArray.length < maxItems : true;
|
|
452
|
+
const hasValue = valueArray.length > 0;
|
|
453
|
+
const popover = /* @__PURE__ */ jsxs2(PopoverPrimitive.Root, { open: isOpen, onOpenChange: handleOpenChange, modal: false, children: [
|
|
454
|
+
/* @__PURE__ */ jsx3(PopoverPrimitive.Anchor, { asChild: true, children: /* @__PURE__ */ jsxs2(
|
|
455
|
+
"div",
|
|
456
|
+
{
|
|
457
|
+
"data-invalid": isInvalid || void 0,
|
|
458
|
+
className: cn(
|
|
459
|
+
// Layout — single line, no wrapping
|
|
460
|
+
"flex min-h-11 cursor-text items-center rounded-[6px] border md:min-h-12",
|
|
461
|
+
"focus-within:outline-none",
|
|
462
|
+
"transition-colors duration-200",
|
|
463
|
+
"border-ods-border bg-ods-card",
|
|
464
|
+
"group",
|
|
465
|
+
!disabled && "hover:border-ods-border-hover hover:bg-ods-bg-hover active:border-ods-border-active active:bg-ods-bg-active",
|
|
466
|
+
disabled && "!cursor-not-allowed bg-ods-bg",
|
|
467
|
+
// Adornments / chevron carry their own colour — grey them with the
|
|
468
|
+
// value so a disabled field reads as one flat colour. Scoped to the
|
|
469
|
+
// DIRECT span child (the start adornment) on purpose: as a descendant
|
|
470
|
+
// rule it also hit the selected `Tag` chips in the middle zone, whose
|
|
471
|
+
// label is a span, and they went invisible against their own fill in
|
|
472
|
+
// the light theme. Anything nested inside the adornment that sets its
|
|
473
|
+
// own colour keeps it; anything that doesn't inherits the grey.
|
|
474
|
+
"has-[:disabled]:[&>span]:text-ods-text-disabled has-[:disabled]:[&_svg]:text-ods-text-disabled",
|
|
475
|
+
isOpen && !isInvalid && "border-ods-accent hover:border-ods-accent",
|
|
476
|
+
isInvalid && "border-ods-error hover:border-ods-error"
|
|
477
|
+
),
|
|
478
|
+
onClick: () => {
|
|
479
|
+
if (!disabled) {
|
|
480
|
+
inputRef.current?.focus();
|
|
481
|
+
openDropdown();
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
children: [
|
|
485
|
+
resolvedStartAdornment && /* @__PURE__ */ jsx3(
|
|
486
|
+
"span",
|
|
487
|
+
{
|
|
488
|
+
className: cn(
|
|
489
|
+
// Images are sized alongside svgs: an entity adornment is
|
|
490
|
+
// usually a flag or a crest, and an unconstrained <img> lays
|
|
491
|
+
// out at 0x0 inside this flex row.
|
|
492
|
+
"flex-shrink-0 pl-3 text-ods-text-secondary transition-colors duration-200",
|
|
493
|
+
"[&_img]:size-4 [&_img]:object-contain md:[&_img]:size-6 [&_svg]:size-4 md:[&_svg]:size-6",
|
|
494
|
+
isOpen && !isInvalid && "text-ods-accent",
|
|
495
|
+
isInvalid && "text-ods-error"
|
|
496
|
+
),
|
|
497
|
+
children: resolvedStartAdornment
|
|
498
|
+
}
|
|
499
|
+
),
|
|
500
|
+
/* @__PURE__ */ jsxs2(
|
|
501
|
+
"div",
|
|
502
|
+
{
|
|
503
|
+
ref: middleRef,
|
|
504
|
+
className: cn(
|
|
505
|
+
"flex min-w-0 flex-1 items-center gap-2 px-2",
|
|
506
|
+
wrapTags ? "flex-wrap py-[var(--spacing-system-xsf)]" : "overflow-hidden"
|
|
507
|
+
),
|
|
508
|
+
children: [
|
|
509
|
+
multiple && visibleTags.map((option) => /* @__PURE__ */ jsx3(
|
|
510
|
+
Tag,
|
|
511
|
+
{
|
|
512
|
+
variant: "outline",
|
|
513
|
+
className: wrapTags ? "max-w-full" : void 0,
|
|
514
|
+
labelClassName: wrapTags ? "truncate" : "max-w-[90px] truncate",
|
|
515
|
+
label: renderTag ? renderTag(option) : option.label,
|
|
516
|
+
onClose: !disabled ? () => {
|
|
517
|
+
props.onChange(valueArray.filter((v) => v !== option.value));
|
|
518
|
+
} : void 0
|
|
519
|
+
},
|
|
520
|
+
String(option.value)
|
|
521
|
+
)),
|
|
522
|
+
multiple && hiddenTagsCount > 0 && /* @__PURE__ */ jsx3("div", { ref: hiddenTagsRef, className: "shrink-0", children: /* @__PURE__ */ jsx3(
|
|
523
|
+
"button",
|
|
524
|
+
{
|
|
525
|
+
ref: badgeRef,
|
|
526
|
+
type: "button",
|
|
527
|
+
onClick: (e) => {
|
|
528
|
+
e.stopPropagation();
|
|
529
|
+
setShowHiddenTags((prev) => {
|
|
530
|
+
if (!prev) setIsOpen(false);
|
|
531
|
+
return !prev;
|
|
532
|
+
});
|
|
533
|
+
},
|
|
534
|
+
className: cn(
|
|
535
|
+
"flex h-8 items-center px-2",
|
|
536
|
+
"rounded-[6px] border border-ods-border bg-ods-card",
|
|
537
|
+
"text-ods-text-secondary text-h5",
|
|
538
|
+
"cursor-pointer transition-colors hover:bg-ods-bg-hover"
|
|
539
|
+
),
|
|
540
|
+
children: getLimitTagsText(hiddenTagsCount)
|
|
541
|
+
}
|
|
542
|
+
) }),
|
|
543
|
+
canAddMore && /* @__PURE__ */ jsx3(
|
|
544
|
+
"input",
|
|
545
|
+
{
|
|
546
|
+
ref: inputRef,
|
|
547
|
+
type: "text",
|
|
548
|
+
value: inputDisplayValue,
|
|
549
|
+
onChange: handleInputChange,
|
|
550
|
+
onKeyDown: handleKeyDown,
|
|
551
|
+
onFocus: () => openDropdown(),
|
|
552
|
+
placeholder: inputPlaceholder,
|
|
553
|
+
disabled,
|
|
554
|
+
className: innerInputStyles
|
|
555
|
+
}
|
|
556
|
+
)
|
|
557
|
+
]
|
|
558
|
+
}
|
|
559
|
+
),
|
|
560
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-1 pr-3", children: [
|
|
561
|
+
showClearAll && (hasValue || inputValue.length > 0) && !disabled && isOpen && /* @__PURE__ */ jsx3(
|
|
562
|
+
"button",
|
|
563
|
+
{
|
|
564
|
+
type: "button",
|
|
565
|
+
onClick: handleClearAll,
|
|
566
|
+
className: "flex items-center justify-center transition-opacity hover:opacity-70",
|
|
567
|
+
"aria-label": "Clear all",
|
|
568
|
+
children: /* @__PURE__ */ jsx3(XmarkCircleIcon, { className: "size-4 text-ods-text-secondary md:size-6" })
|
|
569
|
+
}
|
|
570
|
+
),
|
|
571
|
+
loading ? /* @__PURE__ */ jsx3(
|
|
572
|
+
Loader2,
|
|
573
|
+
{
|
|
574
|
+
className: cn(
|
|
575
|
+
"size-4 animate-spin md:size-6",
|
|
576
|
+
isInvalid ? "text-ods-error" : isOpen ? "text-ods-accent" : "text-ods-text-secondary"
|
|
577
|
+
)
|
|
578
|
+
}
|
|
579
|
+
) : showChevron && /* @__PURE__ */ jsx3(
|
|
580
|
+
Chevron02DownIcon,
|
|
581
|
+
{
|
|
582
|
+
className: cn(
|
|
583
|
+
"size-4 transition-all duration-200 md:size-6",
|
|
584
|
+
"text-ods-text-secondary",
|
|
585
|
+
isOpen && "rotate-180",
|
|
586
|
+
isOpen && !isInvalid && "text-ods-accent",
|
|
587
|
+
isInvalid && "text-ods-error"
|
|
588
|
+
)
|
|
589
|
+
}
|
|
590
|
+
)
|
|
591
|
+
] })
|
|
592
|
+
]
|
|
593
|
+
}
|
|
594
|
+
) }),
|
|
595
|
+
/* @__PURE__ */ jsx3(
|
|
596
|
+
PopoverPrimitive.Content,
|
|
597
|
+
{
|
|
598
|
+
className: cn(
|
|
599
|
+
"z-50 mt-1 w-[var(--radix-popover-trigger-width)]",
|
|
600
|
+
"rounded-[4px] border border-ods-border bg-ods-card",
|
|
601
|
+
"flex max-h-[var(--radix-popper-available-height)] flex-col overflow-hidden",
|
|
602
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
603
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
604
|
+
dropdownClassName
|
|
605
|
+
),
|
|
606
|
+
sideOffset: 4,
|
|
607
|
+
align: "start",
|
|
608
|
+
collisionPadding: { bottom: keyboardPadding },
|
|
609
|
+
onOpenAutoFocus: (e) => {
|
|
610
|
+
e.preventDefault();
|
|
611
|
+
inputRef.current?.focus();
|
|
612
|
+
},
|
|
613
|
+
onInteractOutside: (e) => {
|
|
614
|
+
if (containerRef.current?.contains(e.target)) {
|
|
615
|
+
e.preventDefault();
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
children: /* @__PURE__ */ jsxs2(ScrollAreaPrimitive.Root, { className: "flex min-h-0 flex-col overflow-hidden", children: [
|
|
619
|
+
/* @__PURE__ */ jsx3(ScrollAreaPrimitive.Viewport, { className: "max-h-[240px] min-h-0 w-full [&>div]:!block", children: /* @__PURE__ */ jsx3("div", { role: "listbox", children: loading ? /* @__PURE__ */ jsx3("div", { className: "px-3 py-2 text-ods-text-secondary text-h6", children: loadingText }) : filteredOptions.length === 0 ? showCreateOption ? isCreateTooLong ? /* @__PURE__ */ jsxs2("div", { className: "flex h-11 min-w-0 items-center px-[var(--spacing-system-mf)] text-ods-error text-h5 md:h-12", children: [
|
|
620
|
+
"Maximum ",
|
|
621
|
+
maxCreateLength,
|
|
622
|
+
" characters"
|
|
623
|
+
] }) : /* @__PURE__ */ jsx3(
|
|
624
|
+
"div",
|
|
625
|
+
{
|
|
626
|
+
role: "option",
|
|
627
|
+
"aria-selected": false,
|
|
628
|
+
className: cn(
|
|
629
|
+
"flex h-11 min-w-0 cursor-pointer items-center px-[var(--spacing-system-mf)] transition-colors md:h-12",
|
|
630
|
+
"text-ods-accent text-h4",
|
|
631
|
+
"hover:bg-ods-bg-hover"
|
|
632
|
+
),
|
|
633
|
+
onClick: handleCreate,
|
|
634
|
+
children: /* @__PURE__ */ jsx3(TruncateText, { className: "text-current", children: `+ Create "${inputValue.trim()}"` })
|
|
635
|
+
}
|
|
636
|
+
) : /* @__PURE__ */ jsx3("div", { className: "px-3 py-2 text-ods-text-secondary text-h6", children: freeSolo && inputValue.trim() ? /* @__PURE__ */ jsxs2("span", { children: [
|
|
637
|
+
'Press Enter to add "',
|
|
638
|
+
inputValue,
|
|
639
|
+
'"'
|
|
640
|
+
] }) : noOptionsText }) : filteredOptions.map((option, index) => {
|
|
641
|
+
const isSelected = valueArray.includes(option.value);
|
|
642
|
+
const isHighlighted = index === highlightedIndex;
|
|
643
|
+
return /* @__PURE__ */ jsx3(
|
|
644
|
+
"div",
|
|
645
|
+
{
|
|
646
|
+
role: "option",
|
|
647
|
+
"aria-selected": isSelected,
|
|
648
|
+
className: cn(
|
|
649
|
+
// `min-h` rather than a fixed height: an option may carry
|
|
650
|
+
// a second line, and a clipped one is worse than a taller row.
|
|
651
|
+
"group/item flex min-h-11 cursor-pointer items-center border-b border-ods-border px-[var(--spacing-system-mf)] py-[var(--spacing-system-xsf)] transition-colors last:border-b-0 md:min-h-12",
|
|
652
|
+
"text-h4",
|
|
653
|
+
isHighlighted && "bg-ods-bg-surface",
|
|
654
|
+
isSelected ? "text-ods-accent" : "text-ods-text-primary",
|
|
655
|
+
!isHighlighted && "hover:bg-ods-bg-hover"
|
|
656
|
+
),
|
|
657
|
+
onClick: () => handleSelect(option),
|
|
658
|
+
onMouseEnter: () => setHighlightedIndex(index),
|
|
659
|
+
children: renderOption ? renderOption(option, isSelected) : /* @__PURE__ */ jsxs2("div", { className: "flex w-full min-w-0 items-center justify-between gap-[var(--spacing-system-xsf)]", children: [
|
|
660
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 items-center gap-[var(--spacing-system-xsf)]", children: [
|
|
661
|
+
option.icon && /* @__PURE__ */ jsx3("span", { className: "flex size-5 shrink-0 items-center justify-center overflow-hidden [&_img]:size-full [&_img]:object-contain [&_svg]:size-full", children: option.icon }),
|
|
662
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
663
|
+
/* @__PURE__ */ jsx3(TruncateText, { className: "text-current", children: option.label }),
|
|
664
|
+
typeof option.description === "string" ? /* @__PURE__ */ jsx3(TruncateText, { tone: "secondary", variant: "h6", children: option.description }) : option.description
|
|
665
|
+
] })
|
|
666
|
+
] }),
|
|
667
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-[var(--spacing-system-xsf)]", children: [
|
|
668
|
+
isSelected && /* @__PURE__ */ jsx3(CheckIcon, { className: "text-ods-accent", size: 20 }),
|
|
669
|
+
onDeleteOption && !isSelected && /* @__PURE__ */ jsx3(
|
|
670
|
+
"button",
|
|
671
|
+
{
|
|
672
|
+
type: "button",
|
|
673
|
+
"aria-label": `Delete ${option.label}`,
|
|
674
|
+
onClick: (e) => {
|
|
675
|
+
e.stopPropagation();
|
|
676
|
+
onDeleteOption(option.value);
|
|
677
|
+
},
|
|
678
|
+
disabled: isDeletingOption,
|
|
679
|
+
className: "opacity-0 transition-opacity focus-visible:opacity-100 disabled:pointer-events-none disabled:opacity-50 group-hover/item:opacity-100",
|
|
680
|
+
children: /* @__PURE__ */ jsx3(TrashIcon, { className: "size-4 text-ods-error" })
|
|
681
|
+
}
|
|
682
|
+
)
|
|
683
|
+
] })
|
|
684
|
+
] })
|
|
685
|
+
},
|
|
686
|
+
String(option.value)
|
|
687
|
+
);
|
|
688
|
+
}) }) }),
|
|
689
|
+
/* @__PURE__ */ jsx3(ScrollAreaPrimitive.Scrollbar, { className: "hidden", orientation: "vertical", children: /* @__PURE__ */ jsx3(ScrollAreaPrimitive.Thumb, {}) })
|
|
690
|
+
] })
|
|
691
|
+
}
|
|
692
|
+
)
|
|
693
|
+
] });
|
|
694
|
+
return /* @__PURE__ */ jsx3(
|
|
695
|
+
FieldWrapper,
|
|
696
|
+
{
|
|
697
|
+
label,
|
|
698
|
+
labelVariant,
|
|
699
|
+
error,
|
|
700
|
+
errorSlot: "error" in props,
|
|
701
|
+
className,
|
|
702
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "relative", ref: containerRef, children: [
|
|
703
|
+
popover,
|
|
704
|
+
multiple && showHiddenTags && hiddenTagsCount > 0 && /* @__PURE__ */ jsx3(
|
|
705
|
+
HiddenTagsPopup,
|
|
706
|
+
{
|
|
707
|
+
ref: hiddenTagsPopupRef,
|
|
708
|
+
items: hiddenTags,
|
|
709
|
+
disabled,
|
|
710
|
+
className: "left-auto right-0 max-w-full",
|
|
711
|
+
onRemove: (value) => {
|
|
712
|
+
const newValue = valueArray.filter((v) => v !== value);
|
|
713
|
+
props.onChange(newValue);
|
|
714
|
+
if (typeof limitTagsProp === "number" && newValue.length <= limitTagsProp) setShowHiddenTags(false);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
),
|
|
718
|
+
multiple && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
719
|
+
/* @__PURE__ */ jsx3(
|
|
720
|
+
"span",
|
|
721
|
+
{
|
|
722
|
+
ref: textMeasureRef,
|
|
723
|
+
"aria-hidden": "true",
|
|
724
|
+
className: "pointer-events-none invisible absolute left-0 top-0 -z-10 whitespace-nowrap text-h4",
|
|
725
|
+
children: inputPlaceholder
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
/* @__PURE__ */ jsx3(
|
|
729
|
+
"div",
|
|
730
|
+
{
|
|
731
|
+
ref: measureRef,
|
|
732
|
+
"aria-hidden": "true",
|
|
733
|
+
className: "pointer-events-none invisible absolute left-0 top-0 -z-10 flex gap-2",
|
|
734
|
+
children: selectedOptions.map((option) => /* @__PURE__ */ jsx3(
|
|
735
|
+
Tag,
|
|
736
|
+
{
|
|
737
|
+
variant: "outline",
|
|
738
|
+
labelClassName: "max-w-[90px] truncate",
|
|
739
|
+
label: renderTag ? renderTag(option) : option.label,
|
|
740
|
+
onClose: () => {
|
|
741
|
+
}
|
|
742
|
+
},
|
|
743
|
+
`m-${String(option.value)}`
|
|
744
|
+
))
|
|
745
|
+
}
|
|
746
|
+
)
|
|
747
|
+
] })
|
|
748
|
+
] })
|
|
749
|
+
}
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
var Autocomplete = forwardRef2(AutocompleteInner);
|
|
753
|
+
|
|
148
754
|
// src/components/ui/select.tsx
|
|
149
755
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
150
756
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
151
|
-
import { forwardRef } from "react";
|
|
152
|
-
import { jsx as
|
|
757
|
+
import { forwardRef as forwardRef3 } from "react";
|
|
758
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
153
759
|
var Select = SelectPrimitive.Root;
|
|
154
760
|
var SelectGroup = SelectPrimitive.Group;
|
|
155
761
|
var SelectValue = SelectPrimitive.Value;
|
|
156
|
-
var SelectTrigger =
|
|
762
|
+
var SelectTrigger = forwardRef3((allProps, ref) => {
|
|
157
763
|
const { className, children, invalid, label, labelVariant, error, ...props } = allProps;
|
|
158
764
|
const errorSlot = "error" in allProps;
|
|
159
765
|
const isInvalid = invalid || !!error;
|
|
160
|
-
const trigger = /* @__PURE__ */
|
|
766
|
+
const trigger = /* @__PURE__ */ jsxs3(
|
|
161
767
|
SelectPrimitive.Trigger,
|
|
162
768
|
{
|
|
163
769
|
ref,
|
|
@@ -191,7 +797,7 @@ var SelectTrigger = forwardRef((allProps, ref) => {
|
|
|
191
797
|
...props,
|
|
192
798
|
children: [
|
|
193
799
|
children,
|
|
194
|
-
/* @__PURE__ */
|
|
800
|
+
/* @__PURE__ */ jsx4(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx4(
|
|
195
801
|
Chevron02DownIcon,
|
|
196
802
|
{
|
|
197
803
|
className: cn(
|
|
@@ -204,30 +810,30 @@ var SelectTrigger = forwardRef((allProps, ref) => {
|
|
|
204
810
|
]
|
|
205
811
|
}
|
|
206
812
|
);
|
|
207
|
-
return /* @__PURE__ */
|
|
813
|
+
return /* @__PURE__ */ jsx4(FieldWrapper, { label, labelVariant, error, errorSlot, children: trigger });
|
|
208
814
|
});
|
|
209
815
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
210
|
-
var SelectScrollUpButton =
|
|
816
|
+
var SelectScrollUpButton = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
211
817
|
SelectPrimitive.ScrollUpButton,
|
|
212
818
|
{
|
|
213
819
|
ref,
|
|
214
820
|
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
215
821
|
...props,
|
|
216
|
-
children: /* @__PURE__ */
|
|
822
|
+
children: /* @__PURE__ */ jsx4(ChevronUp, { className: "h-4 w-4" })
|
|
217
823
|
}
|
|
218
824
|
));
|
|
219
825
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
220
|
-
var SelectScrollDownButton =
|
|
826
|
+
var SelectScrollDownButton = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
221
827
|
SelectPrimitive.ScrollDownButton,
|
|
222
828
|
{
|
|
223
829
|
ref,
|
|
224
830
|
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
225
831
|
...props,
|
|
226
|
-
children: /* @__PURE__ */
|
|
832
|
+
children: /* @__PURE__ */ jsx4(ChevronDown, { className: "h-4 w-4" })
|
|
227
833
|
}
|
|
228
834
|
));
|
|
229
835
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
230
|
-
var SelectContent =
|
|
836
|
+
var SelectContent = forwardRef3(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx4(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs3(
|
|
231
837
|
SelectPrimitive.Content,
|
|
232
838
|
{
|
|
233
839
|
ref,
|
|
@@ -244,16 +850,16 @@ var SelectContent = forwardRef(({ className, children, position = "popper", ...p
|
|
|
244
850
|
},
|
|
245
851
|
...props,
|
|
246
852
|
children: [
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
853
|
+
/* @__PURE__ */ jsx4(SelectScrollUpButton, {}),
|
|
854
|
+
/* @__PURE__ */ jsx4(SelectPrimitive.Viewport, { className: "w-full", children }),
|
|
855
|
+
/* @__PURE__ */ jsx4(SelectScrollDownButton, {})
|
|
250
856
|
]
|
|
251
857
|
}
|
|
252
858
|
) }));
|
|
253
859
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
254
|
-
var SelectLabel =
|
|
860
|
+
var SelectLabel = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(SelectPrimitive.Label, { ref, className: cn("py-1.5 pl-8 pr-2 font-semibold text-h6", className), ...props }));
|
|
255
861
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
256
|
-
var SelectItem =
|
|
862
|
+
var SelectItem = forwardRef3(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
|
|
257
863
|
SelectPrimitive.Item,
|
|
258
864
|
{
|
|
259
865
|
ref,
|
|
@@ -269,17 +875,17 @@ var SelectItem = forwardRef(({ className, children, ...props }, ref) => /* @__PU
|
|
|
269
875
|
),
|
|
270
876
|
...props,
|
|
271
877
|
children: [
|
|
272
|
-
/* @__PURE__ */
|
|
273
|
-
/* @__PURE__ */
|
|
878
|
+
/* @__PURE__ */ jsx4(SelectPrimitive.ItemText, { children }),
|
|
879
|
+
/* @__PURE__ */ jsx4(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx4(CheckIcon, { className: "text-ods-accent", size: 20 }) })
|
|
274
880
|
]
|
|
275
881
|
}
|
|
276
882
|
));
|
|
277
883
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
278
|
-
var SelectSeparator =
|
|
884
|
+
var SelectSeparator = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx4(SelectPrimitive.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-ods-border", className), ...props }));
|
|
279
885
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
280
886
|
|
|
281
887
|
// src/components/layout/back-button.tsx
|
|
282
|
-
import { Fragment, jsx as
|
|
888
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
283
889
|
var BACK_BUTTON_CLASS = cn(
|
|
284
890
|
"group inline-flex items-center justify-center self-start rounded-md",
|
|
285
891
|
"gap-[var(--spacing-system-xsf)] py-[var(--spacing-system-sf)]",
|
|
@@ -289,9 +895,9 @@ var BACK_BUTTON_CLASS = cn(
|
|
|
289
895
|
);
|
|
290
896
|
var BACK_BUTTON_SKELETON_CLASS = "h-12 w-40 rounded-md";
|
|
291
897
|
function BackButton({ label = "Back", className, type = "button", href, ...props }) {
|
|
292
|
-
const content = /* @__PURE__ */
|
|
293
|
-
/* @__PURE__ */
|
|
294
|
-
/* @__PURE__ */
|
|
898
|
+
const content = /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
899
|
+
/* @__PURE__ */ jsx5(Chevron02LeftIcon, { className: "size-6 shrink-0" }),
|
|
900
|
+
/* @__PURE__ */ jsx5("span", { className: "text-h4", children: label })
|
|
295
901
|
] });
|
|
296
902
|
if (href) {
|
|
297
903
|
const {
|
|
@@ -306,7 +912,7 @@ function BackButton({ label = "Back", className, type = "button", href, ...props
|
|
|
306
912
|
value: _value,
|
|
307
913
|
...shared
|
|
308
914
|
} = props;
|
|
309
|
-
return /* @__PURE__ */
|
|
915
|
+
return /* @__PURE__ */ jsx5(
|
|
310
916
|
next_link_default,
|
|
311
917
|
{
|
|
312
918
|
...shared,
|
|
@@ -316,12 +922,12 @@ function BackButton({ label = "Back", className, type = "button", href, ...props
|
|
|
316
922
|
}
|
|
317
923
|
);
|
|
318
924
|
}
|
|
319
|
-
return /* @__PURE__ */
|
|
925
|
+
return /* @__PURE__ */ jsx5("button", { type, className: cn(BACK_BUTTON_CLASS, className), ...props, children: content });
|
|
320
926
|
}
|
|
321
927
|
|
|
322
928
|
// src/components/ui/page-actions.tsx
|
|
323
929
|
import React from "react";
|
|
324
|
-
import { Fragment as
|
|
930
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
325
931
|
function actionKey(action, idx) {
|
|
326
932
|
return `${action.label ?? action.ariaLabel ?? "action"}-${idx}`;
|
|
327
933
|
}
|
|
@@ -356,14 +962,14 @@ function actionToMenuItems(action, idx) {
|
|
|
356
962
|
function renderActionButton(action, opts = {}) {
|
|
357
963
|
const button = renderRawActionButton(action, opts);
|
|
358
964
|
if (!action.tooltip) return button;
|
|
359
|
-
return /* @__PURE__ */
|
|
360
|
-
/* @__PURE__ */
|
|
361
|
-
/* @__PURE__ */
|
|
965
|
+
return /* @__PURE__ */ jsx6(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs5(Tooltip, { children: [
|
|
966
|
+
/* @__PURE__ */ jsx6(TooltipTrigger, { asChild: true, children: button }),
|
|
967
|
+
/* @__PURE__ */ jsx6(TooltipContent, { children: action.tooltip })
|
|
362
968
|
] }) });
|
|
363
969
|
}
|
|
364
970
|
function renderRawActionButton(action, opts = {}) {
|
|
365
971
|
if (action.iconAction) {
|
|
366
|
-
return /* @__PURE__ */
|
|
972
|
+
return /* @__PURE__ */ jsx6(
|
|
367
973
|
SplitButton,
|
|
368
974
|
{
|
|
369
975
|
variant: action.variant ?? void 0,
|
|
@@ -381,18 +987,18 @@ function renderRawActionButton(action, opts = {}) {
|
|
|
381
987
|
);
|
|
382
988
|
}
|
|
383
989
|
if (action.submenu && action.submenu.length > 0) {
|
|
384
|
-
return /* @__PURE__ */
|
|
990
|
+
return /* @__PURE__ */ jsx6(
|
|
385
991
|
ActionsMenuDropdown,
|
|
386
992
|
{
|
|
387
993
|
groups: [{ items: action.submenu }],
|
|
388
|
-
customTrigger: /* @__PURE__ */
|
|
994
|
+
customTrigger: /* @__PURE__ */ jsx6(
|
|
389
995
|
Button,
|
|
390
996
|
{
|
|
391
997
|
variant: "outline",
|
|
392
998
|
disabled: action.disabled,
|
|
393
999
|
loading: action.loading,
|
|
394
1000
|
leftIcon: action.icon,
|
|
395
|
-
splitIcon: /* @__PURE__ */
|
|
1001
|
+
splitIcon: /* @__PURE__ */ jsx6(Chevron02DownIcon, { className: "h-4 w-4" }),
|
|
396
1002
|
className: opts.fullWidth ? "flex-1" : void 0,
|
|
397
1003
|
children: action.label
|
|
398
1004
|
}
|
|
@@ -402,8 +1008,8 @@ function renderRawActionButton(action, opts = {}) {
|
|
|
402
1008
|
}
|
|
403
1009
|
const isIconOnly = opts.iconOnly || !action.label || action.iconOnlyOnDesktop;
|
|
404
1010
|
if (isIconOnly) {
|
|
405
|
-
const iconNode = action.iconOnlyOnDesktop ? /* @__PURE__ */
|
|
406
|
-
return /* @__PURE__ */
|
|
1011
|
+
const iconNode = action.iconOnlyOnDesktop ? /* @__PURE__ */ jsx6("span", { className: "inline-flex [&_svg]:!text-ods-text-primary", children: action.icon }) : action.icon;
|
|
1012
|
+
return /* @__PURE__ */ jsx6(
|
|
407
1013
|
Button,
|
|
408
1014
|
{
|
|
409
1015
|
variant: action.variant,
|
|
@@ -419,7 +1025,7 @@ function renderRawActionButton(action, opts = {}) {
|
|
|
419
1025
|
}
|
|
420
1026
|
);
|
|
421
1027
|
}
|
|
422
|
-
return /* @__PURE__ */
|
|
1028
|
+
return /* @__PURE__ */ jsx6(
|
|
423
1029
|
Button,
|
|
424
1030
|
{
|
|
425
1031
|
variant: action.variant,
|
|
@@ -446,9 +1052,9 @@ function ActionSkeletons({
|
|
|
446
1052
|
emptyFallback = "icon"
|
|
447
1053
|
}) {
|
|
448
1054
|
const items = actions.length > 0 ? actions : [null];
|
|
449
|
-
return /* @__PURE__ */
|
|
1055
|
+
return /* @__PURE__ */ jsx6(Fragment3, { children: items.map((action, idx) => {
|
|
450
1056
|
const isIconOnly = action ? !action.label || !!action.iconOnlyOnDesktop : emptyFallback === "icon";
|
|
451
|
-
return /* @__PURE__ */
|
|
1057
|
+
return /* @__PURE__ */ jsx6(
|
|
452
1058
|
Skeleton,
|
|
453
1059
|
{
|
|
454
1060
|
className: cn(
|
|
@@ -462,7 +1068,7 @@ function ActionSkeletons({
|
|
|
462
1068
|
}) });
|
|
463
1069
|
}
|
|
464
1070
|
function MobileTriggerSkeleton() {
|
|
465
|
-
return /* @__PURE__ */
|
|
1071
|
+
return /* @__PURE__ */ jsx6(Skeleton, { className: cn(SKELETON_HEIGHT, SKELETON_ICON_WIDTH, SKELETON_RADIUS) });
|
|
466
1072
|
}
|
|
467
1073
|
function PageActions({
|
|
468
1074
|
variant = "icon-buttons",
|
|
@@ -473,7 +1079,7 @@ function PageActions({
|
|
|
473
1079
|
loading
|
|
474
1080
|
}) {
|
|
475
1081
|
if (variant === "icon-buttons") {
|
|
476
|
-
return /* @__PURE__ */
|
|
1082
|
+
return /* @__PURE__ */ jsx6(
|
|
477
1083
|
IconButtonsVariant,
|
|
478
1084
|
{
|
|
479
1085
|
actions,
|
|
@@ -485,7 +1091,7 @@ function PageActions({
|
|
|
485
1091
|
);
|
|
486
1092
|
}
|
|
487
1093
|
if (variant === "menu-primary") {
|
|
488
|
-
return /* @__PURE__ */
|
|
1094
|
+
return /* @__PURE__ */ jsx6(
|
|
489
1095
|
MenuPrimaryVariant,
|
|
490
1096
|
{
|
|
491
1097
|
actions,
|
|
@@ -496,7 +1102,7 @@ function PageActions({
|
|
|
496
1102
|
}
|
|
497
1103
|
);
|
|
498
1104
|
}
|
|
499
|
-
return /* @__PURE__ */
|
|
1105
|
+
return /* @__PURE__ */ jsx6(PrimaryButtonsVariant, { actions, className, loading });
|
|
500
1106
|
}
|
|
501
1107
|
function IconButtonsVariant({
|
|
502
1108
|
actions,
|
|
@@ -512,15 +1118,15 @@ function IconButtonsVariant({
|
|
|
512
1118
|
const useSingleActionMobile = isSingleAction && !hasMenuActions;
|
|
513
1119
|
const mobileMenuGroups = [{ items: actions.flatMap(actionToMenuItems) }, ...menuActions ?? []];
|
|
514
1120
|
const hasMobileMenuItems = mobileMenuGroups.some((g) => g.items.length > 0);
|
|
515
|
-
return /* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
1121
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1122
|
+
/* @__PURE__ */ jsxs5("div", { className: cn("hidden items-center content-md:flex", ACTIONS_GAP, className), children: [
|
|
517
1123
|
selector,
|
|
518
|
-
loading ? /* @__PURE__ */
|
|
519
|
-
desktopActions.map((action, idx) => /* @__PURE__ */
|
|
520
|
-
hasMenuActions && /* @__PURE__ */
|
|
1124
|
+
loading ? /* @__PURE__ */ jsx6(ActionSkeletons, { actions: desktopActions }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1125
|
+
desktopActions.map((action, idx) => /* @__PURE__ */ jsx6(React.Fragment, { children: renderActionButton(action) }, actionKey(action, idx))),
|
|
1126
|
+
hasMenuActions && /* @__PURE__ */ jsx6(ActionsMenuDropdown, { groups: menuActions })
|
|
521
1127
|
] })
|
|
522
1128
|
] }),
|
|
523
|
-
/* @__PURE__ */
|
|
1129
|
+
/* @__PURE__ */ jsx6("div", { className: cn("flex content-md:hidden", className), children: loading ? /* @__PURE__ */ jsx6(MobileTriggerSkeleton, {}) : useSingleActionMobile && singleAction ? renderActionButton(singleAction, { iconOnly: true }) : hasMobileMenuItems ? /* @__PURE__ */ jsx6(ActionsMenuDropdown, { groups: mobileMenuGroups }) : null })
|
|
524
1130
|
] });
|
|
525
1131
|
}
|
|
526
1132
|
function PrimaryButtonsVariant({
|
|
@@ -534,14 +1140,14 @@ function PrimaryButtonsVariant({
|
|
|
534
1140
|
return 0;
|
|
535
1141
|
});
|
|
536
1142
|
const desktopActions = sortedActions.filter((a) => !a.showOnlyMobile);
|
|
537
|
-
return /* @__PURE__ */
|
|
538
|
-
/* @__PURE__ */
|
|
1143
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1144
|
+
/* @__PURE__ */ jsx6("div", { className: cn("hidden items-center md:content-md:flex", ACTIONS_GAP, className), children: loading ? (
|
|
539
1145
|
// No overflow trigger in this variant — an unknown action set settles
|
|
540
1146
|
// into a labelled button, not a square one.
|
|
541
|
-
/* @__PURE__ */
|
|
542
|
-
) : desktopActions.map((action, idx) => /* @__PURE__ */
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
1147
|
+
/* @__PURE__ */ jsx6(ActionSkeletons, { actions: desktopActions, emptyFallback: "label" })
|
|
1148
|
+
) : desktopActions.map((action, idx) => /* @__PURE__ */ jsx6(React.Fragment, { children: renderActionButton(action) }, `desktop-${actionKey(action, idx)}`)) }),
|
|
1149
|
+
/* @__PURE__ */ jsx6("div", { className: cn("hidden items-center md:content-max-md:flex", ACTIONS_GAP, className), children: loading ? /* @__PURE__ */ jsx6(MobileTriggerSkeleton, {}) : /* @__PURE__ */ jsx6(CompactPrimaryActions, { actions: desktopActions }) }),
|
|
1150
|
+
/* @__PURE__ */ jsx6(MobileBottomActions, { actions: sortedActions, loading })
|
|
545
1151
|
] });
|
|
546
1152
|
}
|
|
547
1153
|
function MenuPrimaryVariant({
|
|
@@ -555,19 +1161,19 @@ function MenuPrimaryVariant({
|
|
|
555
1161
|
const hasMenuActions = menuActions.some((g) => g.items.length > 0);
|
|
556
1162
|
const mobileMenuGroups = [{ items: actions.flatMap(actionToMenuItems) }, ...menuActions];
|
|
557
1163
|
const hasMobileMenuItems = mobileMenuGroups.some((g) => g.items.length > 0);
|
|
558
|
-
return /* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
1164
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1165
|
+
/* @__PURE__ */ jsxs5("div", { className: cn("hidden items-center content-md:flex", ACTIONS_GAP, className), children: [
|
|
560
1166
|
selector,
|
|
561
|
-
loading ? /* @__PURE__ */
|
|
562
|
-
hasMenuActions && /* @__PURE__ */
|
|
563
|
-
desktopActions.map((action, idx) => /* @__PURE__ */
|
|
1167
|
+
loading ? /* @__PURE__ */ jsx6(ActionSkeletons, { actions: desktopActions }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1168
|
+
hasMenuActions && /* @__PURE__ */ jsx6(ActionsMenuDropdown, { groups: menuActions }),
|
|
1169
|
+
desktopActions.map((action, idx) => /* @__PURE__ */ jsx6(React.Fragment, { children: renderActionButton({ ...action, variant: action.variant || "accent" }) }, `desktop-${actionKey(action, idx)}`))
|
|
564
1170
|
] })
|
|
565
1171
|
] }),
|
|
566
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ jsx6("div", { className: cn("flex content-md:hidden", className), children: loading ? /* @__PURE__ */ jsx6(MobileTriggerSkeleton, {}) : hasMobileMenuItems || selector ? (
|
|
567
1173
|
// The selector rides into the menu as its header row: on mobile the
|
|
568
1174
|
// title row has no room for it, and hiding it entirely (what
|
|
569
1175
|
// `icon-buttons` does) would leave no way to switch views at all.
|
|
570
|
-
/* @__PURE__ */
|
|
1176
|
+
/* @__PURE__ */ jsx6(ActionsMenuDropdown, { groups: mobileMenuGroups, header: selector })
|
|
571
1177
|
) : null })
|
|
572
1178
|
] });
|
|
573
1179
|
}
|
|
@@ -575,13 +1181,13 @@ function CompactPrimaryActions({ actions }) {
|
|
|
575
1181
|
const foldable = actions.filter((action) => action.variant !== "accent" && !!action.label);
|
|
576
1182
|
const fold = foldable.length > 1;
|
|
577
1183
|
const inline = fold ? actions.filter((action) => !foldable.includes(action)) : actions;
|
|
578
|
-
return /* @__PURE__ */
|
|
579
|
-
fold && /* @__PURE__ */
|
|
580
|
-
inline.map((action, idx) => /* @__PURE__ */
|
|
1184
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1185
|
+
fold && /* @__PURE__ */ jsx6(ActionsMenuDropdown, { groups: [{ items: foldable.flatMap(actionToMenuItems) }] }),
|
|
1186
|
+
inline.map((action, idx) => /* @__PURE__ */ jsx6(React.Fragment, { children: renderActionButton(action) }, `compact-${actionKey(action, idx)}`))
|
|
581
1187
|
] });
|
|
582
1188
|
}
|
|
583
1189
|
function MobileBottomActions({ actions, loading }) {
|
|
584
|
-
return /* @__PURE__ */
|
|
1190
|
+
return /* @__PURE__ */ jsx6(
|
|
585
1191
|
"div",
|
|
586
1192
|
{
|
|
587
1193
|
className: cn(
|
|
@@ -593,7 +1199,7 @@ function MobileBottomActions({ actions, loading }) {
|
|
|
593
1199
|
"flex items-start p-[var(--spacing-system-lf)]",
|
|
594
1200
|
ACTIONS_GAP
|
|
595
1201
|
),
|
|
596
|
-
children: loading ? /* @__PURE__ */
|
|
1202
|
+
children: loading ? /* @__PURE__ */ jsx6(ActionSkeletons, { actions, fullWidth: true, emptyFallback: "label" }) : actions.map((action, idx) => /* @__PURE__ */ jsx6(React.Fragment, { children: renderActionButton(action, { fullWidth: !!action.label }) }, `mobile-${actionKey(action, idx)}`))
|
|
597
1203
|
}
|
|
598
1204
|
);
|
|
599
1205
|
}
|
|
@@ -603,7 +1209,7 @@ function usePageActionsBottomPadding(variant) {
|
|
|
603
1209
|
|
|
604
1210
|
// src/components/ui/entity-image.tsx
|
|
605
1211
|
import React2 from "react";
|
|
606
|
-
import { jsx as
|
|
1212
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
607
1213
|
var ENTITY_IMAGE_SIZE = "size-[52px] content-md:size-[60px]";
|
|
608
1214
|
function EntityImage({ src, alt, fallbackText, sizeClassName, className }) {
|
|
609
1215
|
const resolvedSrc = useAuthedImageSrc(src);
|
|
@@ -612,7 +1218,7 @@ function EntityImage({ src, alt, fallbackText, sizeClassName, className }) {
|
|
|
612
1218
|
const showFallback = imageFailed || !resolvedSrc;
|
|
613
1219
|
const initials = personInitials(fallbackText ?? alt);
|
|
614
1220
|
if (showFallback) {
|
|
615
|
-
return /* @__PURE__ */
|
|
1221
|
+
return /* @__PURE__ */ jsx7(
|
|
616
1222
|
"div",
|
|
617
1223
|
{
|
|
618
1224
|
"aria-label": alt,
|
|
@@ -625,7 +1231,7 @@ function EntityImage({ src, alt, fallbackText, sizeClassName, className }) {
|
|
|
625
1231
|
}
|
|
626
1232
|
);
|
|
627
1233
|
}
|
|
628
|
-
return /* @__PURE__ */
|
|
1234
|
+
return /* @__PURE__ */ jsx7(
|
|
629
1235
|
next_image_default,
|
|
630
1236
|
{
|
|
631
1237
|
src: resolvedSrc,
|
|
@@ -644,10 +1250,10 @@ function EntityImage({ src, alt, fallbackText, sizeClassName, className }) {
|
|
|
644
1250
|
}
|
|
645
1251
|
|
|
646
1252
|
// src/components/layout/title-block.tsx
|
|
647
|
-
import { jsx as
|
|
1253
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
648
1254
|
var TITLE_BLOCK_MIN_HEIGHT = "min-h-11 content-md:min-h-12";
|
|
649
1255
|
function TitleTextSkeleton({ widthClass, heightClass }) {
|
|
650
|
-
return /* @__PURE__ */
|
|
1256
|
+
return /* @__PURE__ */ jsx8(
|
|
651
1257
|
"span",
|
|
652
1258
|
{
|
|
653
1259
|
"aria-hidden": true,
|
|
@@ -687,8 +1293,8 @@ function TitleBlock({
|
|
|
687
1293
|
const { ref: subtitleRef, isTruncated: subtitleTruncated } = useIsTruncated(
|
|
688
1294
|
loading ? null : subtitle
|
|
689
1295
|
);
|
|
690
|
-
const titleNode = loading ? /* @__PURE__ */
|
|
691
|
-
return /* @__PURE__ */
|
|
1296
|
+
const titleNode = loading ? /* @__PURE__ */ jsx8(TitleTextSkeleton, { widthClass: skeletonSize.width, heightClass: skeletonSize.height }) : title;
|
|
1297
|
+
return /* @__PURE__ */ jsxs6(
|
|
692
1298
|
"div",
|
|
693
1299
|
{
|
|
694
1300
|
className: cn(
|
|
@@ -707,7 +1313,7 @@ function TitleBlock({
|
|
|
707
1313
|
className
|
|
708
1314
|
),
|
|
709
1315
|
children: [
|
|
710
|
-
/* @__PURE__ */
|
|
1316
|
+
/* @__PURE__ */ jsxs6(
|
|
711
1317
|
"div",
|
|
712
1318
|
{
|
|
713
1319
|
className: cn(
|
|
@@ -715,19 +1321,19 @@ function TitleBlock({
|
|
|
715
1321
|
TITLE_BLOCK_MIN_HEIGHT
|
|
716
1322
|
),
|
|
717
1323
|
children: [
|
|
718
|
-
backButton && /* @__PURE__ */
|
|
719
|
-
image || hasSubtitleRow || loading ? /* @__PURE__ */
|
|
720
|
-
image && /* @__PURE__ */
|
|
721
|
-
/* @__PURE__ */
|
|
722
|
-
(loading || title) && (titleAdornment ? /* @__PURE__ */
|
|
723
|
-
/* @__PURE__ */
|
|
1324
|
+
backButton && /* @__PURE__ */ jsx8(BackButton, { onClick: backButton.onClick, label: backButton.label, className: "hidden content-md:inline-flex" }),
|
|
1325
|
+
image || hasSubtitleRow || loading ? /* @__PURE__ */ jsxs6("div", { className: "flex w-full min-w-0 items-center gap-[var(--spacing-system-m)]", children: [
|
|
1326
|
+
image && /* @__PURE__ */ jsx8(EntityImage, { src: image.src, alt: image.alt, fallbackText: image.alt || title }),
|
|
1327
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [
|
|
1328
|
+
(loading || title) && (titleAdornment ? /* @__PURE__ */ jsxs6("div", { className: "flex w-full min-w-0 items-center gap-[var(--spacing-system-m)]", children: [
|
|
1329
|
+
/* @__PURE__ */ jsx8(
|
|
724
1330
|
FloatingTooltip,
|
|
725
1331
|
{
|
|
726
1332
|
content: title,
|
|
727
1333
|
side: "bottom",
|
|
728
1334
|
disabled: !titleTruncated,
|
|
729
1335
|
triggerClassName: "min-w-0",
|
|
730
|
-
children: /* @__PURE__ */
|
|
1336
|
+
children: /* @__PURE__ */ jsx8(
|
|
731
1337
|
"h1",
|
|
732
1338
|
{
|
|
733
1339
|
ref: titleRef,
|
|
@@ -737,36 +1343,36 @@ function TitleBlock({
|
|
|
737
1343
|
)
|
|
738
1344
|
}
|
|
739
1345
|
),
|
|
740
|
-
/* @__PURE__ */
|
|
741
|
-
] }) : /* @__PURE__ */
|
|
1346
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0", children: titleAdornment })
|
|
1347
|
+
] }) : /* @__PURE__ */ jsx8(FloatingTooltip, { content: title, side: "bottom", disabled: !titleTruncated, children: /* @__PURE__ */ jsx8("h1", { ref: titleRef, className: cn(titleClass, "text-ods-text-primary", titleOverflowClass), children: titleNode }) })),
|
|
742
1348
|
hasSubtitleRow && /* The NBSP is a pure spacer, reached only in `'always'` mode: an
|
|
743
1349
|
empty `p` collapses to zero height (its only content would be
|
|
744
1350
|
collapsible whitespace), which is exactly the shift that mode
|
|
745
1351
|
exists to prevent. Hidden from AT — it carries no meaning. */
|
|
746
|
-
/* @__PURE__ */
|
|
1352
|
+
/* @__PURE__ */ jsx8(FloatingTooltip, { content: subtitle, side: "bottom", disabled: !subtitleTruncated, children: /* @__PURE__ */ jsx8(
|
|
747
1353
|
"p",
|
|
748
1354
|
{
|
|
749
1355
|
ref: subtitleRef,
|
|
750
1356
|
className: "truncate text-ods-text-secondary text-h6",
|
|
751
1357
|
"aria-hidden": !loading && !subtitle ? true : void 0,
|
|
752
|
-
children: loading ? /* @__PURE__ */
|
|
1358
|
+
children: loading ? /* @__PURE__ */ jsx8(TitleTextSkeleton, { widthClass: "w-28 content-md:w-36", heightClass: "h-2.5 content-md:h-3" }) : subtitle || "\xA0"
|
|
753
1359
|
}
|
|
754
1360
|
) })
|
|
755
1361
|
] })
|
|
756
|
-
] }) : title && (titleAdornment ? /* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
758
|
-
/* @__PURE__ */
|
|
1362
|
+
] }) : title && (titleAdornment ? /* @__PURE__ */ jsxs6("div", { className: "flex w-full min-w-0 items-center gap-[var(--spacing-system-m)]", children: [
|
|
1363
|
+
/* @__PURE__ */ jsx8(FloatingTooltip, { content: title, side: "bottom", disabled: !titleTruncated, triggerClassName: "min-w-0", children: /* @__PURE__ */ jsx8("h1", { ref: titleRef, className: cn(titleClass, "min-w-0 text-ods-text-primary", titleOverflowClass), children: title }) }),
|
|
1364
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0", children: titleAdornment })
|
|
759
1365
|
] }) : (
|
|
760
1366
|
/* This branch never had the single-line clamp, so text already
|
|
761
1367
|
wraps; `titleWrap` only adds break-words for pathological
|
|
762
1368
|
unbroken tokens. No class change when the prop is unset —
|
|
763
1369
|
the frozen baseline stays byte-identical. */
|
|
764
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsx8("h1", { className: cn(titleClass, "text-ods-text-primary", titleWrap && "break-words"), children: title })
|
|
765
1371
|
))
|
|
766
1372
|
]
|
|
767
1373
|
}
|
|
768
1374
|
),
|
|
769
|
-
(hasActions || hasMenuActions || selector || loadingActions) && /* @__PURE__ */
|
|
1375
|
+
(hasActions || hasMenuActions || selector || loadingActions) && /* @__PURE__ */ jsx8("div", { className: "flex shrink-0 items-center gap-2", children: /* @__PURE__ */ jsx8(
|
|
770
1376
|
PageActions,
|
|
771
1377
|
{
|
|
772
1378
|
variant: actionsVariant,
|
|
@@ -782,7 +1388,7 @@ function TitleBlock({
|
|
|
782
1388
|
}
|
|
783
1389
|
|
|
784
1390
|
// src/components/layout/page-layout.tsx
|
|
785
|
-
import { jsx as
|
|
1391
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
786
1392
|
function PageLayout({
|
|
787
1393
|
children,
|
|
788
1394
|
title,
|
|
@@ -807,8 +1413,8 @@ function PageLayout({
|
|
|
807
1413
|
const hasActions = actions && actions.length > 0;
|
|
808
1414
|
const needsBottomPadding = hasActions && actionsVariant === "primary-buttons";
|
|
809
1415
|
const hasHeader = showHeader && (title || subtitle || image || backButton || hasActions || selector || loading);
|
|
810
|
-
return /* @__PURE__ */
|
|
811
|
-
hasHeader && /* @__PURE__ */
|
|
1416
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("flex w-full flex-col", className), children: [
|
|
1417
|
+
hasHeader && /* @__PURE__ */ jsx9(
|
|
812
1418
|
TitleBlock,
|
|
813
1419
|
{
|
|
814
1420
|
title,
|
|
@@ -828,7 +1434,7 @@ function PageLayout({
|
|
|
828
1434
|
titleWrap
|
|
829
1435
|
}
|
|
830
1436
|
),
|
|
831
|
-
/* @__PURE__ */
|
|
1437
|
+
/* @__PURE__ */ jsx9(
|
|
832
1438
|
"div",
|
|
833
1439
|
{
|
|
834
1440
|
className: cn(
|
|
@@ -843,8 +1449,8 @@ function PageLayout({
|
|
|
843
1449
|
}
|
|
844
1450
|
|
|
845
1451
|
// src/components/features/remote-session/remote-session-viewers.tsx
|
|
846
|
-
import { useState } from "react";
|
|
847
|
-
import { jsx as
|
|
1452
|
+
import { useState as useState2 } from "react";
|
|
1453
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
848
1454
|
function viewerLabel(viewer) {
|
|
849
1455
|
if (viewer.isHost) return `${viewer.name} (host)`;
|
|
850
1456
|
if (viewer.isYou) return `${viewer.name} (you)`;
|
|
@@ -854,14 +1460,14 @@ function hostFirst(viewers) {
|
|
|
854
1460
|
return [...viewers.filter((viewer) => viewer.isHost), ...viewers.filter((viewer) => !viewer.isHost)];
|
|
855
1461
|
}
|
|
856
1462
|
function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
857
|
-
const [open, setOpen] =
|
|
1463
|
+
const [open, setOpen] = useState2(false);
|
|
858
1464
|
if (viewers.length === 0) return null;
|
|
859
1465
|
const ordered = hostFirst(viewers);
|
|
860
1466
|
const faces = ordered.slice(0, max);
|
|
861
1467
|
const overflow = ordered.length - faces.length;
|
|
862
1468
|
const Chevron = open ? Chevron02UpIcon : Chevron02DownIcon;
|
|
863
|
-
return /* @__PURE__ */
|
|
864
|
-
/* @__PURE__ */
|
|
1469
|
+
return /* @__PURE__ */ jsxs8(DropdownMenu, { open, onOpenChange: setOpen, children: [
|
|
1470
|
+
/* @__PURE__ */ jsxs8(
|
|
865
1471
|
DropdownMenuTrigger,
|
|
866
1472
|
{
|
|
867
1473
|
"aria-label": `In this session: ${ordered.map(viewerLabel).join(", ")}`,
|
|
@@ -871,8 +1477,8 @@ function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
|
871
1477
|
className
|
|
872
1478
|
),
|
|
873
1479
|
children: [
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
faces.map((viewer, index) => /* @__PURE__ */
|
|
1480
|
+
/* @__PURE__ */ jsxs8("span", { className: "flex items-center", children: [
|
|
1481
|
+
faces.map((viewer, index) => /* @__PURE__ */ jsx10(
|
|
876
1482
|
SquareAvatar,
|
|
877
1483
|
{
|
|
878
1484
|
variant: "round",
|
|
@@ -889,16 +1495,16 @@ function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
|
889
1495
|
},
|
|
890
1496
|
viewer.id
|
|
891
1497
|
)),
|
|
892
|
-
overflow > 0 && /* @__PURE__ */
|
|
1498
|
+
overflow > 0 && /* @__PURE__ */ jsxs8("span", { className: "relative -ml-2 flex size-8 shrink-0 items-center justify-center rounded-full bg-ods-bg text-ods-text-secondary ring-1 ring-ods-border text-h6", children: [
|
|
893
1499
|
"+",
|
|
894
1500
|
overflow
|
|
895
1501
|
] })
|
|
896
1502
|
] }),
|
|
897
|
-
/* @__PURE__ */
|
|
1503
|
+
/* @__PURE__ */ jsx10("span", { className: "flex size-8 items-center justify-center rounded-md text-ods-text-primary", children: /* @__PURE__ */ jsx10(Chevron, { size: 16, color: "currentColor" }) })
|
|
898
1504
|
]
|
|
899
1505
|
}
|
|
900
1506
|
),
|
|
901
|
-
/* @__PURE__ */
|
|
1507
|
+
/* @__PURE__ */ jsx10(DropdownMenuContent, { align: "end", className: "w-[280px] p-0", children: ordered.map((viewer) => /* @__PURE__ */ jsxs8(
|
|
902
1508
|
DropdownMenuItem,
|
|
903
1509
|
{
|
|
904
1510
|
className: cn(
|
|
@@ -906,7 +1512,7 @@ function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
|
906
1512
|
"py-[var(--spacing-system-s)] pl-[var(--spacing-system-mf)] pr-[var(--spacing-system-xs)] text-h4"
|
|
907
1513
|
),
|
|
908
1514
|
children: [
|
|
909
|
-
/* @__PURE__ */
|
|
1515
|
+
/* @__PURE__ */ jsx10(
|
|
910
1516
|
SquareAvatar,
|
|
911
1517
|
{
|
|
912
1518
|
variant: "round",
|
|
@@ -917,7 +1523,7 @@ function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
|
917
1523
|
className: "shrink-0"
|
|
918
1524
|
}
|
|
919
1525
|
),
|
|
920
|
-
/* @__PURE__ */
|
|
1526
|
+
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate", children: viewerLabel(viewer) })
|
|
921
1527
|
]
|
|
922
1528
|
},
|
|
923
1529
|
viewer.id
|
|
@@ -926,8 +1532,8 @@ function RemoteSessionViewers({ viewers, max = 4, className }) {
|
|
|
926
1532
|
}
|
|
927
1533
|
|
|
928
1534
|
// src/components/features/remote-session/remote-session-parts.tsx
|
|
929
|
-
import { useEffect, useState as
|
|
930
|
-
import { jsx as
|
|
1535
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1536
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
931
1537
|
var DESKTOP_SCALE = {
|
|
932
1538
|
"--spacing-system-xs": "0.5rem",
|
|
933
1539
|
"--spacing-system-s": "0.75rem",
|
|
@@ -948,11 +1554,11 @@ var DESKTOP_SCALE = {
|
|
|
948
1554
|
"--font-line-space-h6-caption": "1.25rem"
|
|
949
1555
|
};
|
|
950
1556
|
function RemoteSessionScope({ children, className }) {
|
|
951
|
-
return /* @__PURE__ */
|
|
1557
|
+
return /* @__PURE__ */ jsx11("div", { "data-app-type": "openframe", style: DESKTOP_SCALE, className, children });
|
|
952
1558
|
}
|
|
953
1559
|
function RemoteSessionOrgLogo({ name, logoUrl, sizePx, className }) {
|
|
954
1560
|
if (logoUrl) {
|
|
955
|
-
return /* @__PURE__ */
|
|
1561
|
+
return /* @__PURE__ */ jsx11(
|
|
956
1562
|
SquareAvatar,
|
|
957
1563
|
{
|
|
958
1564
|
variant: "square",
|
|
@@ -965,7 +1571,7 @@ function RemoteSessionOrgLogo({ name, logoUrl, sizePx, className }) {
|
|
|
965
1571
|
}
|
|
966
1572
|
);
|
|
967
1573
|
}
|
|
968
|
-
return /* @__PURE__ */
|
|
1574
|
+
return /* @__PURE__ */ jsx11(
|
|
969
1575
|
"div",
|
|
970
1576
|
{
|
|
971
1577
|
role: "img",
|
|
@@ -975,12 +1581,12 @@ function RemoteSessionOrgLogo({ name, logoUrl, sizePx, className }) {
|
|
|
975
1581
|
"flex shrink-0 items-center justify-center rounded-md border border-ods-border bg-ods-card",
|
|
976
1582
|
className
|
|
977
1583
|
),
|
|
978
|
-
children: /* @__PURE__ */
|
|
1584
|
+
children: /* @__PURE__ */ jsx11(OpenFrameLogo, { className: "size-1/2" })
|
|
979
1585
|
}
|
|
980
1586
|
);
|
|
981
1587
|
}
|
|
982
1588
|
function RemoteSessionRecordingTag({ className }) {
|
|
983
|
-
return /* @__PURE__ */
|
|
1589
|
+
return /* @__PURE__ */ jsxs9(
|
|
984
1590
|
"div",
|
|
985
1591
|
{
|
|
986
1592
|
className: cn(
|
|
@@ -988,8 +1594,8 @@ function RemoteSessionRecordingTag({ className }) {
|
|
|
988
1594
|
className
|
|
989
1595
|
),
|
|
990
1596
|
children: [
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
1597
|
+
/* @__PURE__ */ jsx11(RecordingIcon, { size: 16, color: "currentColor", className: "text-ods-success" }),
|
|
1598
|
+
/* @__PURE__ */ jsx11("span", { className: "text-ods-success text-h5", children: "Session Recording" })
|
|
993
1599
|
]
|
|
994
1600
|
}
|
|
995
1601
|
);
|
|
@@ -1000,15 +1606,15 @@ function RemoteSessionStatusRow({
|
|
|
1000
1606
|
}) {
|
|
1001
1607
|
const hasViewers = !!viewers && viewers.length > 0;
|
|
1002
1608
|
if (!showRecordingTag && !hasViewers) return null;
|
|
1003
|
-
if (!hasViewers) return /* @__PURE__ */
|
|
1004
|
-
return /* @__PURE__ */
|
|
1005
|
-
showRecordingTag && /* @__PURE__ */
|
|
1006
|
-
/* @__PURE__ */
|
|
1609
|
+
if (!hasViewers) return /* @__PURE__ */ jsx11(RemoteSessionRecordingTag, {});
|
|
1610
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex w-full items-center gap-[var(--spacing-system-m)]", children: [
|
|
1611
|
+
showRecordingTag && /* @__PURE__ */ jsx11(RemoteSessionRecordingTag, { className: "flex-1 justify-center self-auto" }),
|
|
1612
|
+
/* @__PURE__ */ jsx11(RemoteSessionViewers, { viewers, className: "ml-auto" })
|
|
1007
1613
|
] });
|
|
1008
1614
|
}
|
|
1009
1615
|
var REMOTE_SESSION_DRAG_HANDLE_CLASS = "cursor-grab active:cursor-grabbing";
|
|
1010
1616
|
function RemoteSessionDragger({ dragHandlers }) {
|
|
1011
|
-
return /* @__PURE__ */
|
|
1617
|
+
return /* @__PURE__ */ jsx11(
|
|
1012
1618
|
"span",
|
|
1013
1619
|
{
|
|
1014
1620
|
"aria-hidden": true,
|
|
@@ -1017,7 +1623,7 @@ function RemoteSessionDragger({ dragHandlers }) {
|
|
|
1017
1623
|
dragHandlers && REMOTE_SESSION_DRAG_HANDLE_CLASS
|
|
1018
1624
|
),
|
|
1019
1625
|
...dragHandlers,
|
|
1020
|
-
children: /* @__PURE__ */
|
|
1626
|
+
children: /* @__PURE__ */ jsx11(DraggerIcon, { size: 24, color: "currentColor" })
|
|
1021
1627
|
}
|
|
1022
1628
|
);
|
|
1023
1629
|
}
|
|
@@ -1029,8 +1635,8 @@ function formatRemoteSessionElapsed(elapsedMs) {
|
|
|
1029
1635
|
return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}` : `${minutes}:${seconds}`;
|
|
1030
1636
|
}
|
|
1031
1637
|
function useRemoteSessionTimer(startedAt) {
|
|
1032
|
-
const [nowMs, setNowMs] =
|
|
1033
|
-
|
|
1638
|
+
const [nowMs, setNowMs] = useState3(() => Date.now());
|
|
1639
|
+
useEffect2(() => {
|
|
1034
1640
|
const timer = setInterval(() => setNowMs(Date.now()), 1e3);
|
|
1035
1641
|
return () => clearInterval(timer);
|
|
1036
1642
|
}, []);
|
|
@@ -1038,7 +1644,7 @@ function useRemoteSessionTimer(startedAt) {
|
|
|
1038
1644
|
}
|
|
1039
1645
|
|
|
1040
1646
|
// src/components/features/remote-session/remote-access-request-card.tsx
|
|
1041
|
-
import { jsx as
|
|
1647
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1042
1648
|
function displaySiteUrl(url) {
|
|
1043
1649
|
return url.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
1044
1650
|
}
|
|
@@ -1053,30 +1659,30 @@ function RemoteAccessRequestCard({
|
|
|
1053
1659
|
const { organizationName } = party;
|
|
1054
1660
|
const siteUrl = party.organizationSiteUrl ?? void 0;
|
|
1055
1661
|
const openableSite = siteUrl?.startsWith("https://") ? siteUrl : void 0;
|
|
1056
|
-
return /* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1060
|
-
/* @__PURE__ */
|
|
1061
|
-
/* @__PURE__ */
|
|
1062
|
-
siteUrl && /* @__PURE__ */
|
|
1662
|
+
return /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-[var(--spacing-system-l)] rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-xl)]", children: [
|
|
1663
|
+
/* @__PURE__ */ jsx12("h1", { className: "w-full text-ods-text-primary text-h2", children: "Your IT support team is requesting remote access" }),
|
|
1664
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full items-center gap-[var(--spacing-system-m)] rounded-md border border-ods-border bg-ods-bg p-[var(--spacing-system-m)]", children: [
|
|
1665
|
+
/* @__PURE__ */ jsx12(RemoteSessionOrgLogo, { name: organizationName, logoUrl: party.organizationLogoUrl, sizePx: 64 }),
|
|
1666
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
1667
|
+
/* @__PURE__ */ jsx12("p", { className: "w-full truncate text-ods-text-primary text-h3", children: organizationName }),
|
|
1668
|
+
siteUrl && /* @__PURE__ */ jsx12("p", { className: "w-full truncate text-ods-text-secondary text-h4", children: displaySiteUrl(siteUrl) })
|
|
1063
1669
|
] }),
|
|
1064
|
-
openableSite && onOpenSite && /* @__PURE__ */
|
|
1670
|
+
openableSite && onOpenSite && /* @__PURE__ */ jsx12(Button, { variant: "outline", size: "icon", "aria-label": "Open website", onClick: () => onOpenSite(openableSite), children: /* @__PURE__ */ jsx12(ExternalLinkIcon, { size: 24, color: "currentColor" }) })
|
|
1065
1671
|
] }),
|
|
1066
|
-
/* @__PURE__ */
|
|
1672
|
+
/* @__PURE__ */ jsxs10("p", { className: "w-full text-ods-text-primary text-h4", children: [
|
|
1067
1673
|
"A technician from ",
|
|
1068
|
-
/* @__PURE__ */
|
|
1674
|
+
/* @__PURE__ */ jsx12("span", { className: "text-ods-accent", children: organizationName }),
|
|
1069
1675
|
" will be able to view your screen and control your mouse and keyboard during this session."
|
|
1070
1676
|
] }),
|
|
1071
|
-
/* @__PURE__ */
|
|
1072
|
-
showRecordingNotice && /* @__PURE__ */
|
|
1073
|
-
/* @__PURE__ */
|
|
1074
|
-
/* @__PURE__ */
|
|
1677
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-[var(--spacing-system-xs)]", children: [
|
|
1678
|
+
showRecordingNotice && /* @__PURE__ */ jsxs10("div", { className: "flex w-full items-center gap-[var(--spacing-system-xs)] rounded-md border border-ods-border bg-ods-bg p-[var(--spacing-system-s)]", children: [
|
|
1679
|
+
/* @__PURE__ */ jsx12(InfoCircleIcon, { size: 24, color: "currentColor", className: "shrink-0 text-ods-accent" }),
|
|
1680
|
+
/* @__PURE__ */ jsx12("p", { className: "min-w-0 flex-1 text-ods-text-primary text-h6", children: "This session will be recorded and available upon request." })
|
|
1075
1681
|
] }),
|
|
1076
|
-
error ? /* @__PURE__ */
|
|
1682
|
+
error ? /* @__PURE__ */ jsx12("p", { className: "w-full text-ods-text-primary text-h6", children: error }) : /* @__PURE__ */ jsx12("p", { className: "w-full text-ods-text-secondary text-h6", children: "You can end the session at any time." })
|
|
1077
1683
|
] }),
|
|
1078
|
-
/* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1684
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full items-stretch gap-[var(--spacing-system-l)]", children: [
|
|
1685
|
+
/* @__PURE__ */ jsx12(
|
|
1080
1686
|
Button,
|
|
1081
1687
|
{
|
|
1082
1688
|
variant: "outline",
|
|
@@ -1087,7 +1693,7 @@ function RemoteAccessRequestCard({
|
|
|
1087
1693
|
children: "Decline"
|
|
1088
1694
|
}
|
|
1089
1695
|
),
|
|
1090
|
-
/* @__PURE__ */
|
|
1696
|
+
/* @__PURE__ */ jsx12(
|
|
1091
1697
|
Button,
|
|
1092
1698
|
{
|
|
1093
1699
|
variant: "accent",
|
|
@@ -1103,11 +1709,11 @@ function RemoteAccessRequestCard({
|
|
|
1103
1709
|
}
|
|
1104
1710
|
|
|
1105
1711
|
// src/components/features/remote-session/remote-session-block.tsx
|
|
1106
|
-
import { forwardRef as
|
|
1107
|
-
import { jsx as
|
|
1108
|
-
var RemoteSessionBlockFrame =
|
|
1712
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
1713
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1714
|
+
var RemoteSessionBlockFrame = forwardRef4(
|
|
1109
1715
|
({ children, expanded = false, onHide, className }, ref) => {
|
|
1110
|
-
return /* @__PURE__ */
|
|
1716
|
+
return /* @__PURE__ */ jsxs11(
|
|
1111
1717
|
"div",
|
|
1112
1718
|
{
|
|
1113
1719
|
ref,
|
|
@@ -1118,16 +1724,16 @@ var RemoteSessionBlockFrame = forwardRef2(
|
|
|
1118
1724
|
),
|
|
1119
1725
|
children: [
|
|
1120
1726
|
children,
|
|
1121
|
-
/* @__PURE__ */
|
|
1727
|
+
/* @__PURE__ */ jsxs11(
|
|
1122
1728
|
"button",
|
|
1123
1729
|
{
|
|
1124
1730
|
type: "button",
|
|
1125
1731
|
className: "flex h-12 w-full shrink-0 items-center gap-[var(--spacing-system-xs)] border-t border-ods-border bg-ods-card px-[var(--spacing-system-m)]",
|
|
1126
1732
|
onClick: onHide,
|
|
1127
1733
|
children: [
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1734
|
+
/* @__PURE__ */ jsx13(Chevrons03RightIcon, { size: 24 }),
|
|
1735
|
+
/* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate text-left text-ods-text-secondary text-h4", children: "Hide this Block" }),
|
|
1736
|
+
/* @__PURE__ */ jsx13(OpenFrameLogo, { className: "size-6 shrink-0" })
|
|
1131
1737
|
]
|
|
1132
1738
|
}
|
|
1133
1739
|
)
|
|
@@ -1138,12 +1744,12 @@ var RemoteSessionBlockFrame = forwardRef2(
|
|
|
1138
1744
|
);
|
|
1139
1745
|
RemoteSessionBlockFrame.displayName = "RemoteSessionBlockFrame";
|
|
1140
1746
|
function RemoteSessionEndButton({ onEndSession }) {
|
|
1141
|
-
return /* @__PURE__ */
|
|
1747
|
+
return /* @__PURE__ */ jsx13(
|
|
1142
1748
|
Button,
|
|
1143
1749
|
{
|
|
1144
1750
|
variant: "outline",
|
|
1145
1751
|
fullWidth: true,
|
|
1146
|
-
leftIcon: /* @__PURE__ */
|
|
1752
|
+
leftIcon: /* @__PURE__ */ jsx13(MonitorOffIcon, { size: 24, color: "currentColor", className: "text-ods-error" }),
|
|
1147
1753
|
onClick: onEndSession,
|
|
1148
1754
|
children: "End Session"
|
|
1149
1755
|
}
|
|
@@ -1159,9 +1765,9 @@ function RemoteSessionSummary({
|
|
|
1159
1765
|
dragHandlers
|
|
1160
1766
|
}) {
|
|
1161
1767
|
const technician = party.technicianName;
|
|
1162
|
-
return /* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1768
|
+
return /* @__PURE__ */ jsxs11("div", { className: "relative flex flex-col gap-[var(--spacing-system-m)] p-[var(--spacing-system-m)]", children: [
|
|
1769
|
+
/* @__PURE__ */ jsx13(RemoteSessionDragger, { dragHandlers }),
|
|
1770
|
+
/* @__PURE__ */ jsxs11(
|
|
1165
1771
|
"div",
|
|
1166
1772
|
{
|
|
1167
1773
|
className: cn(
|
|
@@ -1170,7 +1776,7 @@ function RemoteSessionSummary({
|
|
|
1170
1776
|
),
|
|
1171
1777
|
...dragHandlers,
|
|
1172
1778
|
children: [
|
|
1173
|
-
technician ? /* @__PURE__ */
|
|
1779
|
+
technician ? /* @__PURE__ */ jsx13(
|
|
1174
1780
|
SquareAvatar,
|
|
1175
1781
|
{
|
|
1176
1782
|
variant: "round",
|
|
@@ -1178,42 +1784,42 @@ function RemoteSessionSummary({
|
|
|
1178
1784
|
src: party.technicianAvatarUrl ?? void 0,
|
|
1179
1785
|
fallback: technician
|
|
1180
1786
|
}
|
|
1181
|
-
) : /* @__PURE__ */
|
|
1182
|
-
/* @__PURE__ */
|
|
1183
|
-
/* @__PURE__ */
|
|
1787
|
+
) : /* @__PURE__ */ jsx13(RemoteSessionOrgLogo, { name: party.organizationName, logoUrl: party.organizationLogoUrl, sizePx: 48 }),
|
|
1788
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
1789
|
+
/* @__PURE__ */ jsxs11("p", { className: "w-full truncate text-ods-text-primary text-h4", children: [
|
|
1184
1790
|
technician ? `${technician} connected` : "IT support team is connected",
|
|
1185
1791
|
" ",
|
|
1186
|
-
/* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsxs11("span", { className: "text-ods-text-secondary", children: [
|
|
1187
1793
|
"(",
|
|
1188
1794
|
elapsed,
|
|
1189
1795
|
")"
|
|
1190
1796
|
] })
|
|
1191
1797
|
] }),
|
|
1192
|
-
/* @__PURE__ */
|
|
1798
|
+
/* @__PURE__ */ jsx13("p", { className: "w-full truncate text-ods-text-secondary text-h4", children: party.organizationName })
|
|
1193
1799
|
] })
|
|
1194
1800
|
]
|
|
1195
1801
|
}
|
|
1196
1802
|
),
|
|
1197
|
-
/* @__PURE__ */
|
|
1198
|
-
/* @__PURE__ */
|
|
1199
|
-
/* @__PURE__ */
|
|
1803
|
+
/* @__PURE__ */ jsx13(RemoteSessionStatusRow, { showRecordingTag, viewers }),
|
|
1804
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex w-full items-stretch gap-[var(--spacing-system-m)]", children: [
|
|
1805
|
+
/* @__PURE__ */ jsx13(
|
|
1200
1806
|
Button,
|
|
1201
1807
|
{
|
|
1202
1808
|
variant: "outline",
|
|
1203
1809
|
fullWidth: true,
|
|
1204
|
-
leftIcon: /* @__PURE__ */
|
|
1810
|
+
leftIcon: /* @__PURE__ */ jsx13(ChatsIcon, { size: 24, color: "currentColor" }),
|
|
1205
1811
|
onClick: onOpenChat,
|
|
1206
1812
|
children: "Open Chat"
|
|
1207
1813
|
}
|
|
1208
1814
|
),
|
|
1209
|
-
/* @__PURE__ */
|
|
1815
|
+
/* @__PURE__ */ jsx13(RemoteSessionEndButton, { onEndSession })
|
|
1210
1816
|
] })
|
|
1211
1817
|
] });
|
|
1212
1818
|
}
|
|
1213
|
-
var RemoteSessionMinimizedChip =
|
|
1819
|
+
var RemoteSessionMinimizedChip = forwardRef4(
|
|
1214
1820
|
({ party, onExpand, dragHandlers }, ref) => {
|
|
1215
1821
|
const technician = party.technicianName;
|
|
1216
|
-
return /* @__PURE__ */
|
|
1822
|
+
return /* @__PURE__ */ jsxs11(
|
|
1217
1823
|
"button",
|
|
1218
1824
|
{
|
|
1219
1825
|
ref,
|
|
@@ -1226,7 +1832,7 @@ var RemoteSessionMinimizedChip = forwardRef2(
|
|
|
1226
1832
|
onClick: onExpand,
|
|
1227
1833
|
...dragHandlers,
|
|
1228
1834
|
children: [
|
|
1229
|
-
technician ? /* @__PURE__ */
|
|
1835
|
+
technician ? /* @__PURE__ */ jsx13(
|
|
1230
1836
|
SquareAvatar,
|
|
1231
1837
|
{
|
|
1232
1838
|
sizePx: 48,
|
|
@@ -1234,7 +1840,7 @@ var RemoteSessionMinimizedChip = forwardRef2(
|
|
|
1234
1840
|
fallback: technician,
|
|
1235
1841
|
className: "rounded-none"
|
|
1236
1842
|
}
|
|
1237
|
-
) : /* @__PURE__ */
|
|
1843
|
+
) : /* @__PURE__ */ jsx13(
|
|
1238
1844
|
RemoteSessionOrgLogo,
|
|
1239
1845
|
{
|
|
1240
1846
|
name: party.organizationName,
|
|
@@ -1243,7 +1849,7 @@ var RemoteSessionMinimizedChip = forwardRef2(
|
|
|
1243
1849
|
className: "rounded-none border-0"
|
|
1244
1850
|
}
|
|
1245
1851
|
),
|
|
1246
|
-
/* @__PURE__ */
|
|
1852
|
+
/* @__PURE__ */ jsx13("span", { className: "flex h-9 w-12 items-center justify-center border-t border-ods-border bg-ods-card", children: /* @__PURE__ */ jsx13(Chevrons03LeftIcon, { size: 24 }) })
|
|
1247
1853
|
]
|
|
1248
1854
|
}
|
|
1249
1855
|
);
|
|
@@ -1252,8 +1858,8 @@ var RemoteSessionMinimizedChip = forwardRef2(
|
|
|
1252
1858
|
RemoteSessionMinimizedChip.displayName = "RemoteSessionMinimizedChip";
|
|
1253
1859
|
|
|
1254
1860
|
// src/components/features/remote-session/remote-session-chat-panel.tsx
|
|
1255
|
-
import { useEffect as
|
|
1256
|
-
import { jsx as
|
|
1861
|
+
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
1862
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1257
1863
|
function formatTime2(at) {
|
|
1258
1864
|
return at.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
|
|
1259
1865
|
}
|
|
@@ -1272,8 +1878,8 @@ function RemoteSessionChatPanel({
|
|
|
1272
1878
|
onEndSession,
|
|
1273
1879
|
dragHandlers
|
|
1274
1880
|
}) {
|
|
1275
|
-
const listRef =
|
|
1276
|
-
|
|
1881
|
+
const listRef = useRef2(null);
|
|
1882
|
+
useEffect3(() => {
|
|
1277
1883
|
const list = listRef.current;
|
|
1278
1884
|
if (list) list.scrollTop = list.scrollHeight;
|
|
1279
1885
|
}, [messages]);
|
|
@@ -1283,10 +1889,10 @@ function RemoteSessionChatPanel({
|
|
|
1283
1889
|
onSend(text);
|
|
1284
1890
|
onDraftChange("");
|
|
1285
1891
|
};
|
|
1286
|
-
return /* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1289
|
-
/* @__PURE__ */
|
|
1892
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
1893
|
+
/* @__PURE__ */ jsxs12("div", { className: "relative flex flex-col gap-[var(--spacing-system-m)] p-[var(--spacing-system-m)]", children: [
|
|
1894
|
+
/* @__PURE__ */ jsx14(RemoteSessionDragger, { dragHandlers }),
|
|
1895
|
+
/* @__PURE__ */ jsxs12(
|
|
1290
1896
|
"div",
|
|
1291
1897
|
{
|
|
1292
1898
|
className: cn(
|
|
@@ -1295,45 +1901,45 @@ function RemoteSessionChatPanel({
|
|
|
1295
1901
|
),
|
|
1296
1902
|
...dragHandlers,
|
|
1297
1903
|
children: [
|
|
1298
|
-
/* @__PURE__ */
|
|
1904
|
+
/* @__PURE__ */ jsxs12("p", { className: "w-full truncate text-ods-text-primary text-h4", children: [
|
|
1299
1905
|
"Your IT support team is connected ",
|
|
1300
|
-
/* @__PURE__ */
|
|
1906
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-ods-text-secondary", children: [
|
|
1301
1907
|
"(",
|
|
1302
1908
|
elapsed,
|
|
1303
1909
|
")"
|
|
1304
1910
|
] })
|
|
1305
1911
|
] }),
|
|
1306
|
-
/* @__PURE__ */
|
|
1912
|
+
/* @__PURE__ */ jsx14("p", { className: "w-full truncate text-ods-text-secondary text-h4", children: "You can end this session at any time" })
|
|
1307
1913
|
]
|
|
1308
1914
|
}
|
|
1309
1915
|
),
|
|
1310
|
-
/* @__PURE__ */
|
|
1311
|
-
/* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1916
|
+
/* @__PURE__ */ jsx14(RemoteSessionStatusRow, { showRecordingTag, viewers }),
|
|
1917
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-stretch gap-[var(--spacing-system-m)]", children: [
|
|
1918
|
+
/* @__PURE__ */ jsx14(
|
|
1313
1919
|
Button,
|
|
1314
1920
|
{
|
|
1315
1921
|
variant: "outline",
|
|
1316
1922
|
fullWidth: true,
|
|
1317
|
-
leftIcon: /* @__PURE__ */
|
|
1923
|
+
leftIcon: /* @__PURE__ */ jsx14(MessageOffIcon, { size: 24, color: "currentColor" }),
|
|
1318
1924
|
onClick: onCloseChat,
|
|
1319
1925
|
children: "Close Chat"
|
|
1320
1926
|
}
|
|
1321
1927
|
),
|
|
1322
|
-
/* @__PURE__ */
|
|
1928
|
+
/* @__PURE__ */ jsx14(RemoteSessionEndButton, { onEndSession })
|
|
1323
1929
|
] })
|
|
1324
1930
|
] }),
|
|
1325
|
-
/* @__PURE__ */
|
|
1931
|
+
/* @__PURE__ */ jsx14(
|
|
1326
1932
|
"div",
|
|
1327
1933
|
{
|
|
1328
1934
|
ref: listRef,
|
|
1329
1935
|
className: "flex min-h-0 flex-1 flex-col overflow-y-auto bg-ods-card p-[var(--spacing-system-m)]",
|
|
1330
|
-
children: /* @__PURE__ */
|
|
1331
|
-
(message) => message.author === "system" ? /* @__PURE__ */
|
|
1936
|
+
children: /* @__PURE__ */ jsx14("div", { className: "mt-auto flex flex-col gap-[var(--spacing-system-s)]", children: messages.map(
|
|
1937
|
+
(message) => message.author === "system" ? /* @__PURE__ */ jsx14("p", { className: "w-full text-center text-ods-text-secondary text-h6", children: message.text }, message.id) : /* @__PURE__ */ jsx14(RemoteSessionChatMessageRow, { message, party }, message.id)
|
|
1332
1938
|
) })
|
|
1333
1939
|
}
|
|
1334
1940
|
),
|
|
1335
|
-
error && /* @__PURE__ */
|
|
1336
|
-
/* @__PURE__ */
|
|
1941
|
+
error && /* @__PURE__ */ jsx14("p", { className: "bg-ods-card px-[var(--spacing-system-m)] text-ods-error text-h6", children: error }),
|
|
1942
|
+
/* @__PURE__ */ jsxs12(
|
|
1337
1943
|
"form",
|
|
1338
1944
|
{
|
|
1339
1945
|
className: "flex items-center gap-[var(--spacing-system-xs)] bg-ods-card px-[var(--spacing-system-m)] pb-[var(--spacing-system-m)]",
|
|
@@ -1342,7 +1948,7 @@ function RemoteSessionChatPanel({
|
|
|
1342
1948
|
handleSend();
|
|
1343
1949
|
},
|
|
1344
1950
|
children: [
|
|
1345
|
-
/* @__PURE__ */
|
|
1951
|
+
/* @__PURE__ */ jsx14(
|
|
1346
1952
|
"input",
|
|
1347
1953
|
{
|
|
1348
1954
|
value: draft,
|
|
@@ -1353,14 +1959,14 @@ function RemoteSessionChatPanel({
|
|
|
1353
1959
|
className: "h-12 min-w-0 flex-1 rounded-md border border-ods-border bg-ods-bg px-[var(--spacing-system-s)] text-ods-text-primary outline-none text-h6 placeholder:text-ods-text-secondary"
|
|
1354
1960
|
}
|
|
1355
1961
|
),
|
|
1356
|
-
/* @__PURE__ */
|
|
1962
|
+
/* @__PURE__ */ jsx14(
|
|
1357
1963
|
"button",
|
|
1358
1964
|
{
|
|
1359
1965
|
type: "submit",
|
|
1360
1966
|
"aria-label": "Send message",
|
|
1361
1967
|
disabled: !ready,
|
|
1362
1968
|
className: "flex size-12 shrink-0 items-center justify-center",
|
|
1363
|
-
children: /* @__PURE__ */
|
|
1969
|
+
children: /* @__PURE__ */ jsx14(Send03Icon, { size: 24, color: "currentColor", className: "text-ods-text-primary" })
|
|
1364
1970
|
}
|
|
1365
1971
|
)
|
|
1366
1972
|
]
|
|
@@ -1374,9 +1980,9 @@ function RemoteSessionChatMessageRow({
|
|
|
1374
1980
|
}) {
|
|
1375
1981
|
const isTechnician = message.author === "technician";
|
|
1376
1982
|
const technician = message.name ?? party.technicianName ?? "Technician";
|
|
1377
|
-
return /* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1379
|
-
isTechnician && /* @__PURE__ */
|
|
1983
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex w-full flex-col", children: [
|
|
1984
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center gap-[var(--spacing-system-xs)]", children: [
|
|
1985
|
+
isTechnician && /* @__PURE__ */ jsx14(
|
|
1380
1986
|
SquareAvatar,
|
|
1381
1987
|
{
|
|
1382
1988
|
variant: "round",
|
|
@@ -1385,7 +1991,7 @@ function RemoteSessionChatMessageRow({
|
|
|
1385
1991
|
fallback: technician
|
|
1386
1992
|
}
|
|
1387
1993
|
),
|
|
1388
|
-
/* @__PURE__ */
|
|
1994
|
+
/* @__PURE__ */ jsx14(
|
|
1389
1995
|
"span",
|
|
1390
1996
|
{
|
|
1391
1997
|
className: cn(
|
|
@@ -1395,14 +2001,14 @@ function RemoteSessionChatMessageRow({
|
|
|
1395
2001
|
children: isTechnician ? technician : "User"
|
|
1396
2002
|
}
|
|
1397
2003
|
),
|
|
1398
|
-
/* @__PURE__ */
|
|
2004
|
+
/* @__PURE__ */ jsx14("span", { className: "shrink-0 text-ods-text-secondary text-h6", children: formatTime2(message.at) })
|
|
1399
2005
|
] }),
|
|
1400
|
-
/* @__PURE__ */
|
|
2006
|
+
/* @__PURE__ */ jsx14("p", { className: "w-full break-words text-ods-text-primary text-h6", children: message.text })
|
|
1401
2007
|
] });
|
|
1402
2008
|
}
|
|
1403
2009
|
|
|
1404
2010
|
// src/components/features/remote-session/remote-desktop-chat-message-row.tsx
|
|
1405
|
-
import { jsx as
|
|
2011
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1406
2012
|
function RemoteDesktopChatMessageRow({
|
|
1407
2013
|
authorName,
|
|
1408
2014
|
isTechnician,
|
|
@@ -1410,10 +2016,10 @@ function RemoteDesktopChatMessageRow({
|
|
|
1410
2016
|
sentAt,
|
|
1411
2017
|
body
|
|
1412
2018
|
}) {
|
|
1413
|
-
return /* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
isTechnician && /* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
2019
|
+
return /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-1 gap-[var(--spacing-system-xxs)]", children: [
|
|
2020
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-[var(--spacing-system-xxs)]", children: [
|
|
2021
|
+
isTechnician && /* @__PURE__ */ jsx15(SquareAvatar, { variant: "round", sizePx: 24, src: avatarUrl, alt: authorName, className: "shrink-0" }),
|
|
2022
|
+
/* @__PURE__ */ jsx15(
|
|
1417
2023
|
"span",
|
|
1418
2024
|
{
|
|
1419
2025
|
className: cn(
|
|
@@ -1423,15 +2029,15 @@ function RemoteDesktopChatMessageRow({
|
|
|
1423
2029
|
children: authorName
|
|
1424
2030
|
}
|
|
1425
2031
|
),
|
|
1426
|
-
/* @__PURE__ */
|
|
2032
|
+
/* @__PURE__ */ jsx15("span", { suppressHydrationWarning: true, className: "shrink-0 text-ods-text-secondary text-h6", children: formatTime(sentAt) })
|
|
1427
2033
|
] }),
|
|
1428
|
-
/* @__PURE__ */
|
|
2034
|
+
/* @__PURE__ */ jsx15("p", { className: "whitespace-pre-wrap text-ods-text-primary text-h4", children: body })
|
|
1429
2035
|
] });
|
|
1430
2036
|
}
|
|
1431
2037
|
|
|
1432
2038
|
// src/components/features/remote-session/remote-desktop-chat-panel.tsx
|
|
1433
|
-
import { useEffect as
|
|
1434
|
-
import { jsx as
|
|
2039
|
+
import { useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
2040
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1435
2041
|
var REMOTE_DESKTOP_CHAT_END_USER_NAME = "User";
|
|
1436
2042
|
function RemoteDesktopChatPanel({
|
|
1437
2043
|
messages,
|
|
@@ -1441,13 +2047,13 @@ function RemoteDesktopChatPanel({
|
|
|
1441
2047
|
onSend,
|
|
1442
2048
|
variant
|
|
1443
2049
|
}) {
|
|
1444
|
-
const scrollRef =
|
|
2050
|
+
const scrollRef = useRef3(null);
|
|
1445
2051
|
const rows = messages.filter((message) => message.author !== "system");
|
|
1446
|
-
|
|
2052
|
+
useEffect4(() => {
|
|
1447
2053
|
const el = scrollRef.current;
|
|
1448
2054
|
if (el) el.scrollTop = el.scrollHeight;
|
|
1449
2055
|
}, [rows.length]);
|
|
1450
|
-
return /* @__PURE__ */
|
|
2056
|
+
return /* @__PURE__ */ jsxs14(
|
|
1451
2057
|
"aside",
|
|
1452
2058
|
{
|
|
1453
2059
|
"aria-label": "Session chat",
|
|
@@ -1456,7 +2062,7 @@ function RemoteDesktopChatPanel({
|
|
|
1456
2062
|
variant === "side" ? "h-full w-[400px] flex-shrink-0" : "absolute bottom-[var(--spacing-system-mf)] right-[var(--spacing-system-mf)] top-[calc(var(--spacing-system-xlf)+var(--spacing-system-mf))] z-10 w-[360px] shadow-lg"
|
|
1457
2063
|
),
|
|
1458
2064
|
children: [
|
|
1459
|
-
/* @__PURE__ */
|
|
2065
|
+
/* @__PURE__ */ jsx16("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx16("div", { className: "flex min-h-full flex-col justify-end gap-[var(--spacing-system-xsf)]", children: rows.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "text-center text-ods-text-muted text-h6", children: loading ? "Loading the chat..." : "No messages yet - say hello to the user." }) : rows.map((message) => /* @__PURE__ */ jsx16(
|
|
1460
2066
|
RemoteDesktopChatMessageRow,
|
|
1461
2067
|
{
|
|
1462
2068
|
authorName: message.name || (message.author === "technician" ? technician.name : REMOTE_DESKTOP_CHAT_END_USER_NAME),
|
|
@@ -1467,7 +2073,7 @@ function RemoteDesktopChatPanel({
|
|
|
1467
2073
|
},
|
|
1468
2074
|
message.id
|
|
1469
2075
|
)) }) }),
|
|
1470
|
-
/* @__PURE__ */
|
|
2076
|
+
/* @__PURE__ */ jsx16(
|
|
1471
2077
|
ChatInput,
|
|
1472
2078
|
{
|
|
1473
2079
|
placeholder: "Enter your Message...",
|
|
@@ -1484,7 +2090,7 @@ function RemoteDesktopChatPanel({
|
|
|
1484
2090
|
}
|
|
1485
2091
|
|
|
1486
2092
|
// src/components/features/remote-session/remote-desktop-fullscreen-toolbar.tsx
|
|
1487
|
-
import { Fragment as
|
|
2093
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1488
2094
|
function RemoteDesktopFullscreenToolbar({
|
|
1489
2095
|
deviceName,
|
|
1490
2096
|
displayMenuGroups,
|
|
@@ -1495,79 +2101,79 @@ function RemoteDesktopFullscreenToolbar({
|
|
|
1495
2101
|
chatOpen = false,
|
|
1496
2102
|
onToggleChat
|
|
1497
2103
|
}) {
|
|
1498
|
-
return /* @__PURE__ */
|
|
1499
|
-
/* @__PURE__ */
|
|
1500
|
-
/* @__PURE__ */
|
|
2104
|
+
return /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
2105
|
+
/* @__PURE__ */ jsx17(OpenFrameLogo, { className: "absolute left-[var(--spacing-system-mf)] top-[var(--spacing-system-mf)] z-10 h-6 w-6 opacity-50" }),
|
|
2106
|
+
/* @__PURE__ */ jsxs15(
|
|
1501
2107
|
"div",
|
|
1502
2108
|
{
|
|
1503
2109
|
className: "absolute left-1/2 top-0 z-10 w-[calc(100%-7rem)] -translate-x-1/2 flex items-center gap-[var(--spacing-system-xs)] rounded-b-[6px] border-x border-b border-ods-border bg-ods-overlay py-[var(--spacing-system-xsf)] pl-[var(--spacing-system-mf)] pr-[var(--spacing-system-xsf)]",
|
|
1504
2110
|
children: [
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1507
|
-
displayMenuGroups.length > 0 && /* @__PURE__ */
|
|
2111
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 flex-1 items-center gap-[var(--spacing-system-xsf)]", children: [
|
|
2112
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate text-ods-text-primary text-h6", children: deviceName }),
|
|
2113
|
+
displayMenuGroups.length > 0 && /* @__PURE__ */ jsx17(
|
|
1508
2114
|
ActionsMenuDropdown,
|
|
1509
2115
|
{
|
|
1510
2116
|
groups: displayMenuGroups,
|
|
1511
|
-
customTrigger: /* @__PURE__ */
|
|
2117
|
+
customTrigger: /* @__PURE__ */ jsxs15(
|
|
1512
2118
|
"button",
|
|
1513
2119
|
{
|
|
1514
2120
|
type: "button",
|
|
1515
2121
|
"aria-label": "Switch display",
|
|
1516
2122
|
className: "flex h-8 flex-shrink-0 items-center gap-[var(--spacing-system-xs)] rounded-[6px] border border-ods-border bg-ods-card p-[var(--spacing-system-xsf)] text-ods-text-primary hover:border-ods-border-hover",
|
|
1517
2123
|
children: [
|
|
1518
|
-
/* @__PURE__ */
|
|
1519
|
-
/* @__PURE__ */
|
|
1520
|
-
/* @__PURE__ */
|
|
2124
|
+
/* @__PURE__ */ jsx17(MonitorIcon, { className: "h-4 w-4" }),
|
|
2125
|
+
/* @__PURE__ */ jsx17("span", { className: "whitespace-nowrap text-h5", children: currentDisplayLabel }),
|
|
2126
|
+
/* @__PURE__ */ jsx17(Chevron02DownIcon, { className: "h-4 w-4" })
|
|
1521
2127
|
]
|
|
1522
2128
|
}
|
|
1523
2129
|
)
|
|
1524
2130
|
}
|
|
1525
2131
|
)
|
|
1526
2132
|
] }),
|
|
1527
|
-
/* @__PURE__ */
|
|
1528
|
-
onToggleChat && /* @__PURE__ */
|
|
2133
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-shrink-0 items-center gap-[var(--spacing-system-xs)]", children: [
|
|
2134
|
+
onToggleChat && /* @__PURE__ */ jsx17(
|
|
1529
2135
|
Button,
|
|
1530
2136
|
{
|
|
1531
2137
|
variant: "outline",
|
|
1532
2138
|
size: "small",
|
|
1533
2139
|
onClick: onToggleChat,
|
|
1534
|
-
leftIcon: chatOpen ? /* @__PURE__ */
|
|
1535
|
-
children: /* @__PURE__ */
|
|
2140
|
+
leftIcon: chatOpen ? /* @__PURE__ */ jsx17(ChatOffIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx17(ChatTextIcon, { className: "h-4 w-4" }),
|
|
2141
|
+
children: /* @__PURE__ */ jsx17("span", { className: "text-h5", children: chatOpen ? "Close Chat" : "Open Chat" })
|
|
1536
2142
|
}
|
|
1537
2143
|
),
|
|
1538
|
-
/* @__PURE__ */
|
|
2144
|
+
/* @__PURE__ */ jsx17(
|
|
1539
2145
|
ActionsMenuDropdown,
|
|
1540
2146
|
{
|
|
1541
2147
|
groups: actionsMenuGroups,
|
|
1542
|
-
customTrigger: /* @__PURE__ */
|
|
2148
|
+
customTrigger: /* @__PURE__ */ jsx17(
|
|
1543
2149
|
Button,
|
|
1544
2150
|
{
|
|
1545
2151
|
variant: "outline",
|
|
1546
2152
|
size: "icon-sm",
|
|
1547
2153
|
"aria-label": "Actions",
|
|
1548
|
-
leftIcon: /* @__PURE__ */
|
|
2154
|
+
leftIcon: /* @__PURE__ */ jsx17(Ellipsis01Icon, { className: "h-4 w-4" })
|
|
1549
2155
|
}
|
|
1550
2156
|
)
|
|
1551
2157
|
}
|
|
1552
2158
|
),
|
|
1553
|
-
/* @__PURE__ */
|
|
2159
|
+
/* @__PURE__ */ jsx17(
|
|
1554
2160
|
Button,
|
|
1555
2161
|
{
|
|
1556
2162
|
variant: "outline",
|
|
1557
2163
|
size: "icon-sm",
|
|
1558
2164
|
"aria-label": "Exit fullscreen",
|
|
1559
2165
|
onClick: onExitFullscreen,
|
|
1560
|
-
leftIcon: /* @__PURE__ */
|
|
2166
|
+
leftIcon: /* @__PURE__ */ jsx17(Collapse02Icon, { className: "h-4 w-4" })
|
|
1561
2167
|
}
|
|
1562
2168
|
),
|
|
1563
|
-
/* @__PURE__ */
|
|
2169
|
+
/* @__PURE__ */ jsx17(
|
|
1564
2170
|
Button,
|
|
1565
2171
|
{
|
|
1566
2172
|
variant: "outline",
|
|
1567
2173
|
size: "icon-sm",
|
|
1568
2174
|
"aria-label": "Settings",
|
|
1569
2175
|
onClick: onOpenSettings,
|
|
1570
|
-
leftIcon: /* @__PURE__ */
|
|
2176
|
+
leftIcon: /* @__PURE__ */ jsx17(Settings01Icon, { className: "h-4 w-4" })
|
|
1571
2177
|
}
|
|
1572
2178
|
)
|
|
1573
2179
|
] })
|
|
@@ -1578,7 +2184,7 @@ function RemoteDesktopFullscreenToolbar({
|
|
|
1578
2184
|
}
|
|
1579
2185
|
|
|
1580
2186
|
// src/components/features/remote-session/remote-desktop-view.tsx
|
|
1581
|
-
import { jsx as
|
|
2187
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1582
2188
|
var PAGE_CLASS = "h-full overflow-hidden px-[var(--spacing-system-l)] pb-[var(--spacing-system-l)]";
|
|
1583
2189
|
var CONTROLS_BAR_CLASS = "flex flex-shrink-0 items-center justify-between gap-[var(--spacing-system-mf)] rounded-md border border-ods-border bg-ods-card px-[var(--spacing-system-mf)] py-[var(--spacing-system-xs)]";
|
|
1584
2190
|
function RemoteDesktopView({
|
|
@@ -1598,12 +2204,12 @@ function RemoteDesktopView({
|
|
|
1598
2204
|
chat,
|
|
1599
2205
|
children
|
|
1600
2206
|
}) {
|
|
1601
|
-
const controlsBar = /* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1605
|
-
/* @__PURE__ */
|
|
1606
|
-
/* @__PURE__ */
|
|
2207
|
+
const controlsBar = /* @__PURE__ */ jsxs16("div", { className: CONTROLS_BAR_CLASS, children: [
|
|
2208
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 items-center gap-[var(--spacing-system-mf)]", children: [
|
|
2209
|
+
/* @__PURE__ */ jsx18("div", { className: "flex-shrink-0 rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-xsf)]", children: /* @__PURE__ */ jsx18(MonitorIcon, { className: "h-4 w-4 text-ods-text-primary" }) }),
|
|
2210
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-col", children: [
|
|
2211
|
+
/* @__PURE__ */ jsx18(TruncateText, { children: deviceName }),
|
|
2212
|
+
/* @__PURE__ */ jsx18(
|
|
1607
2213
|
TruncateText,
|
|
1608
2214
|
{
|
|
1609
2215
|
variant: "h6",
|
|
@@ -1613,55 +2219,55 @@ function RemoteDesktopView({
|
|
|
1613
2219
|
)
|
|
1614
2220
|
] })
|
|
1615
2221
|
] }),
|
|
1616
|
-
/* @__PURE__ */
|
|
1617
|
-
displayMenuGroups.length > 0 && /* @__PURE__ */
|
|
2222
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-shrink-0 items-center gap-[var(--spacing-system-xs)]", children: [
|
|
2223
|
+
displayMenuGroups.length > 0 && /* @__PURE__ */ jsx18(
|
|
1618
2224
|
ActionsMenuDropdown,
|
|
1619
2225
|
{
|
|
1620
2226
|
groups: displayMenuGroups,
|
|
1621
|
-
customTrigger: /* @__PURE__ */
|
|
2227
|
+
customTrigger: /* @__PURE__ */ jsx18(Button, { variant: "outline", leftIcon: /* @__PURE__ */ jsx18(MonitorIcon, { className: "h-4 w-4 md:h-6 md:w-6" }), children: /* @__PURE__ */ jsx18("span", { className: "sr-only content-md:not-sr-only", children: currentDisplayLabel }) })
|
|
1622
2228
|
}
|
|
1623
2229
|
),
|
|
1624
|
-
onToggleChat && /* @__PURE__ */
|
|
2230
|
+
onToggleChat && /* @__PURE__ */ jsx18(
|
|
1625
2231
|
Button,
|
|
1626
2232
|
{
|
|
1627
2233
|
variant: "outline",
|
|
1628
2234
|
onClick: onToggleChat,
|
|
1629
|
-
leftIcon: chatOpen ? /* @__PURE__ */
|
|
1630
|
-
children: /* @__PURE__ */
|
|
2235
|
+
leftIcon: chatOpen ? /* @__PURE__ */ jsx18(ChatOffIcon, { className: "h-4 w-4 md:h-6 md:w-6" }) : /* @__PURE__ */ jsx18(ChatTextIcon, { className: "h-4 w-4 md:h-6 md:w-6" }),
|
|
2236
|
+
children: /* @__PURE__ */ jsx18("span", { className: "sr-only content-md:not-sr-only", children: chatOpen ? "Close Chat" : "Open Chat" })
|
|
1631
2237
|
}
|
|
1632
2238
|
),
|
|
1633
|
-
/* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsx18(ActionsMenuDropdown, { groups: actionsMenuGroups, triggerAriaLabel: "Actions" }),
|
|
2240
|
+
/* @__PURE__ */ jsx18(
|
|
1635
2241
|
Button,
|
|
1636
2242
|
{
|
|
1637
2243
|
variant: "outline",
|
|
1638
2244
|
size: "icon",
|
|
1639
2245
|
"aria-label": "Settings",
|
|
1640
2246
|
onClick: onOpenSettings,
|
|
1641
|
-
leftIcon: /* @__PURE__ */
|
|
2247
|
+
leftIcon: /* @__PURE__ */ jsx18(Settings01Icon, {})
|
|
1642
2248
|
}
|
|
1643
2249
|
),
|
|
1644
|
-
/* @__PURE__ */
|
|
2250
|
+
/* @__PURE__ */ jsx18(
|
|
1645
2251
|
Button,
|
|
1646
2252
|
{
|
|
1647
2253
|
variant: "outline",
|
|
1648
2254
|
size: "icon",
|
|
1649
2255
|
"aria-label": fullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
1650
2256
|
onClick: fullscreen ? onExitFullscreen : onEnterFullscreen,
|
|
1651
|
-
leftIcon: fullscreen ? /* @__PURE__ */
|
|
2257
|
+
leftIcon: fullscreen ? /* @__PURE__ */ jsx18(Collapse02Icon, {}) : /* @__PURE__ */ jsx18(Expand02Icon, {})
|
|
1652
2258
|
}
|
|
1653
2259
|
)
|
|
1654
2260
|
] })
|
|
1655
2261
|
] });
|
|
1656
|
-
return /* @__PURE__ */
|
|
2262
|
+
return /* @__PURE__ */ jsxs16(
|
|
1657
2263
|
PageLayout,
|
|
1658
2264
|
{
|
|
1659
2265
|
className: PAGE_CLASS,
|
|
1660
2266
|
backButton: onBack ? { label: "Back", onClick: onBack } : void 0,
|
|
1661
2267
|
showHeader: !fullscreen,
|
|
1662
2268
|
children: [
|
|
1663
|
-
/* @__PURE__ */
|
|
1664
|
-
fullscreen ? /* @__PURE__ */
|
|
2269
|
+
/* @__PURE__ */ jsxs16("div", { className: fullscreen ? "fixed inset-0 z-50 flex flex-col bg-black" : "contents", children: [
|
|
2270
|
+
fullscreen ? /* @__PURE__ */ jsx18(
|
|
1665
2271
|
RemoteDesktopFullscreenToolbar,
|
|
1666
2272
|
{
|
|
1667
2273
|
deviceName,
|
|
@@ -1674,8 +2280,8 @@ function RemoteDesktopView({
|
|
|
1674
2280
|
onToggleChat
|
|
1675
2281
|
}
|
|
1676
2282
|
) : controlsBar,
|
|
1677
|
-
/* @__PURE__ */
|
|
1678
|
-
/* @__PURE__ */
|
|
2283
|
+
/* @__PURE__ */ jsxs16("div", { className: `relative flex min-h-0 min-w-0 flex-1 ${fullscreen ? "" : "gap-[var(--spacing-system-mf)]"}`, children: [
|
|
2284
|
+
/* @__PURE__ */ jsx18("div", { className: `relative min-h-0 min-w-0 flex-1 overflow-hidden bg-black ${fullscreen ? "" : "rounded-lg"}`, children: screen }),
|
|
1679
2285
|
chat
|
|
1680
2286
|
] })
|
|
1681
2287
|
] }),
|
|
@@ -1685,27 +2291,27 @@ function RemoteDesktopView({
|
|
|
1685
2291
|
);
|
|
1686
2292
|
}
|
|
1687
2293
|
function RemoteDesktopViewSkeleton({ onBack }) {
|
|
1688
|
-
return /* @__PURE__ */
|
|
1689
|
-
/* @__PURE__ */
|
|
1690
|
-
/* @__PURE__ */
|
|
1691
|
-
/* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1693
|
-
/* @__PURE__ */
|
|
1694
|
-
/* @__PURE__ */
|
|
2294
|
+
return /* @__PURE__ */ jsxs16(PageLayout, { className: PAGE_CLASS, backButton: onBack ? { label: "Back", onClick: onBack } : void 0, children: [
|
|
2295
|
+
/* @__PURE__ */ jsxs16("div", { className: CONTROLS_BAR_CLASS, children: [
|
|
2296
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 items-center gap-[var(--spacing-system-mf)]", children: [
|
|
2297
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-9 w-9 flex-shrink-0 rounded-md" }),
|
|
2298
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-col gap-[var(--spacing-system-xxs)]", children: [
|
|
2299
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-5 w-48" }),
|
|
2300
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-4 w-36" })
|
|
1695
2301
|
] })
|
|
1696
2302
|
] }),
|
|
1697
|
-
/* @__PURE__ */
|
|
1698
|
-
/* @__PURE__ */
|
|
1699
|
-
/* @__PURE__ */
|
|
1700
|
-
/* @__PURE__ */
|
|
2303
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-shrink-0 items-center gap-[var(--spacing-system-xs)]", children: [
|
|
2304
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-11 w-11 rounded-lg md:h-12 md:w-12" }),
|
|
2305
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-11 w-11 rounded-lg md:h-12 md:w-12" }),
|
|
2306
|
+
/* @__PURE__ */ jsx18(Skeleton, { className: "h-11 w-11 rounded-lg md:h-12 md:w-12" })
|
|
1701
2307
|
] })
|
|
1702
2308
|
] }),
|
|
1703
|
-
/* @__PURE__ */
|
|
2309
|
+
/* @__PURE__ */ jsx18("div", { className: "min-h-0 min-w-0 flex-1 rounded-lg bg-black" })
|
|
1704
2310
|
] });
|
|
1705
2311
|
}
|
|
1706
2312
|
|
|
1707
2313
|
// src/components/features/remote-session/remote-session-dialog.tsx
|
|
1708
|
-
import { jsx as
|
|
2314
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1709
2315
|
var NOTICE_COPY = {
|
|
1710
2316
|
"session-ended": { title: "Remote session ended", suffix: "has disconnected from your device." },
|
|
1711
2317
|
"connection-lost": { title: "Connection lost", suffix: "lost the connection to your device." }
|
|
@@ -1718,57 +2324,57 @@ function RemoteSessionDialog({
|
|
|
1718
2324
|
onClose
|
|
1719
2325
|
}) {
|
|
1720
2326
|
if (variant === "end-confirm") {
|
|
1721
|
-
return /* @__PURE__ */
|
|
1722
|
-
/* @__PURE__ */
|
|
1723
|
-
/* @__PURE__ */
|
|
1724
|
-
/* @__PURE__ */
|
|
2327
|
+
return /* @__PURE__ */ jsxs17(DialogCard, { children: [
|
|
2328
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-[var(--spacing-system-xs)]", children: [
|
|
2329
|
+
/* @__PURE__ */ jsx19("h1", { className: "w-full text-ods-text-primary text-h2", children: "End remote session?" }),
|
|
2330
|
+
/* @__PURE__ */ jsx19("p", { className: "w-full text-ods-text-primary text-h4", children: "The technician will lose access to your device immediately." })
|
|
1725
2331
|
] }),
|
|
1726
|
-
/* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
1728
|
-
/* @__PURE__ */
|
|
2332
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full items-stretch gap-[var(--spacing-system-l)]", children: [
|
|
2333
|
+
/* @__PURE__ */ jsx19(Button, { variant: "outline", fullWidth: true, disabled: ending, onClick: onClose, children: "Cancel" }),
|
|
2334
|
+
/* @__PURE__ */ jsx19(Button, { variant: "destructive", fullWidth: true, loading: ending, onClick: onEndSession, children: "End Session" })
|
|
1729
2335
|
] })
|
|
1730
2336
|
] });
|
|
1731
2337
|
}
|
|
1732
2338
|
const copy = NOTICE_COPY[variant];
|
|
1733
|
-
return /* @__PURE__ */
|
|
1734
|
-
/* @__PURE__ */
|
|
1735
|
-
/* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
2339
|
+
return /* @__PURE__ */ jsxs17(DialogCard, { children: [
|
|
2340
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-[var(--spacing-system-xs)]", children: [
|
|
2341
|
+
/* @__PURE__ */ jsx19("h1", { className: "w-full text-ods-text-primary text-h2", children: copy.title }),
|
|
2342
|
+
/* @__PURE__ */ jsxs17("p", { className: "w-full text-ods-text-primary text-h4", children: [
|
|
2343
|
+
/* @__PURE__ */ jsx19("span", { className: "text-ods-accent", children: organizationName }),
|
|
1738
2344
|
" ",
|
|
1739
2345
|
copy.suffix
|
|
1740
2346
|
] })
|
|
1741
2347
|
] }),
|
|
1742
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ jsx19("div", { className: "flex w-full justify-end", children: /* @__PURE__ */ jsx19(Button, { variant: "outline", className: "w-1/2", onClick: onClose, children: "Close" }) })
|
|
1743
2349
|
] });
|
|
1744
2350
|
}
|
|
1745
2351
|
function DialogCard({ children }) {
|
|
1746
|
-
return /* @__PURE__ */
|
|
2352
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex w-full flex-col gap-[var(--spacing-system-l)] rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-xl)]", children });
|
|
1747
2353
|
}
|
|
1748
2354
|
|
|
1749
2355
|
// src/components/features/remote-session/remote-session-overlay.tsx
|
|
1750
|
-
import { jsx as
|
|
2356
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1751
2357
|
function RemoteSessionBorder({ className }) {
|
|
1752
|
-
return /* @__PURE__ */
|
|
2358
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("pointer-events-none size-full border-4 border-ods-warning", className) });
|
|
1753
2359
|
}
|
|
1754
2360
|
function RemoteSessionPill({ onEndSession }) {
|
|
1755
|
-
return /* @__PURE__ */
|
|
2361
|
+
return /* @__PURE__ */ jsxs18(
|
|
1756
2362
|
"button",
|
|
1757
2363
|
{
|
|
1758
2364
|
type: "button",
|
|
1759
2365
|
className: "flex items-center gap-[var(--spacing-system-xsf)] rounded-b-md bg-ods-warning px-[var(--spacing-system-m)] py-[var(--spacing-system-xs)] text-ods-text-on-accent",
|
|
1760
2366
|
onClick: onEndSession,
|
|
1761
2367
|
children: [
|
|
1762
|
-
/* @__PURE__ */
|
|
1763
|
-
/* @__PURE__ */
|
|
2368
|
+
/* @__PURE__ */ jsx20(MonitorOffIcon, { size: 24, color: "currentColor" }),
|
|
2369
|
+
/* @__PURE__ */ jsx20("span", { className: "whitespace-nowrap text-h3", children: "End Session" })
|
|
1764
2370
|
]
|
|
1765
2371
|
}
|
|
1766
2372
|
);
|
|
1767
2373
|
}
|
|
1768
2374
|
|
|
1769
2375
|
// src/components/features/remote-session/remote-session-keep-modals.tsx
|
|
1770
|
-
import { useState as
|
|
1771
|
-
import { jsx as
|
|
2376
|
+
import { useState as useState4 } from "react";
|
|
2377
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1772
2378
|
var REMOTE_SESSION_KEEP_REASON_LABELS = {
|
|
1773
2379
|
CLIENT_DISPUTE: "Client dispute",
|
|
1774
2380
|
INTERNAL_REVIEW: "Internal review",
|
|
@@ -1778,11 +2384,11 @@ var REMOTE_SESSION_KEEP_REASON_LABELS = {
|
|
|
1778
2384
|
var KEEP_REASONS = Object.keys(REMOTE_SESSION_KEEP_REASON_LABELS);
|
|
1779
2385
|
var DESCRIPTION_MAX_LENGTH = 500;
|
|
1780
2386
|
function KeepNotice({ icon, title, children }) {
|
|
1781
|
-
return /* @__PURE__ */
|
|
1782
|
-
/* @__PURE__ */
|
|
1783
|
-
/* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
2387
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex w-full items-start gap-[var(--spacing-system-m)] rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-m)]", children: [
|
|
2388
|
+
/* @__PURE__ */ jsx21("span", { className: "flex shrink-0 text-ods-text-secondary", children: icon }),
|
|
2389
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
2390
|
+
/* @__PURE__ */ jsx21("p", { className: "text-ods-text-primary text-h3", children: title }),
|
|
2391
|
+
/* @__PURE__ */ jsx21("p", { className: "text-ods-text-secondary text-h4", children })
|
|
1786
2392
|
] })
|
|
1787
2393
|
] });
|
|
1788
2394
|
}
|
|
@@ -1793,9 +2399,9 @@ function KeepRecordingModal({
|
|
|
1793
2399
|
isPending = false,
|
|
1794
2400
|
onConfirm
|
|
1795
2401
|
}) {
|
|
1796
|
-
const [reason, setReason] =
|
|
1797
|
-
const [description, setDescription] =
|
|
1798
|
-
const [seededOpen, setSeededOpen] =
|
|
2402
|
+
const [reason, setReason] = useState4("");
|
|
2403
|
+
const [description, setDescription] = useState4("");
|
|
2404
|
+
const [seededOpen, setSeededOpen] = useState4(isOpen);
|
|
1799
2405
|
if (seededOpen !== isOpen) {
|
|
1800
2406
|
setSeededOpen(isOpen);
|
|
1801
2407
|
if (isOpen) {
|
|
@@ -1809,13 +2415,13 @@ function KeepRecordingModal({
|
|
|
1809
2415
|
if (!canKeep || isPending) return;
|
|
1810
2416
|
onConfirm({ reason, description: reason === "OTHER" ? trimmed : null });
|
|
1811
2417
|
};
|
|
1812
|
-
return /* @__PURE__ */
|
|
2418
|
+
return /* @__PURE__ */ jsxs19(Modal, { isOpen, onClose: isPending ? () => {
|
|
1813
2419
|
} : onClose, className: "text-left md:max-w-[600px]", children: [
|
|
1814
|
-
/* @__PURE__ */
|
|
1815
|
-
/* @__PURE__ */
|
|
2420
|
+
/* @__PURE__ */ jsx21(ModalHeader, { children: /* @__PURE__ */ jsx21(ModalTitle, { children: "Keep this recording" }) }),
|
|
2421
|
+
/* @__PURE__ */ jsxs19(
|
|
1816
2422
|
KeepNotice,
|
|
1817
2423
|
{
|
|
1818
|
-
icon: /* @__PURE__ */
|
|
2424
|
+
icon: /* @__PURE__ */ jsx21(InfoCircleIcon, { size: 24, color: "currentColor" }),
|
|
1819
2425
|
title: "This recording won't be deleted automatically",
|
|
1820
2426
|
children: [
|
|
1821
2427
|
"It stays until you stop keeping it. Kept recordings use ",
|
|
@@ -1824,20 +2430,20 @@ function KeepRecordingModal({
|
|
|
1824
2430
|
]
|
|
1825
2431
|
}
|
|
1826
2432
|
),
|
|
1827
|
-
/* @__PURE__ */
|
|
1828
|
-
/* @__PURE__ */
|
|
2433
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex w-full flex-col gap-[var(--spacing-system-xs)]", children: [
|
|
2434
|
+
/* @__PURE__ */ jsxs19(
|
|
1829
2435
|
Select,
|
|
1830
2436
|
{
|
|
1831
2437
|
value: reason,
|
|
1832
2438
|
onValueChange: (value) => setReason(value),
|
|
1833
2439
|
disabled: isPending,
|
|
1834
2440
|
children: [
|
|
1835
|
-
/* @__PURE__ */
|
|
1836
|
-
/* @__PURE__ */
|
|
2441
|
+
/* @__PURE__ */ jsx21(SelectTrigger, { label: "Reason", labelVariant: "large", children: /* @__PURE__ */ jsx21(SelectValue, { placeholder: "Select Reason" }) }),
|
|
2442
|
+
/* @__PURE__ */ jsx21(SelectContent, { children: KEEP_REASONS.map((value) => /* @__PURE__ */ jsx21(SelectItem, { value, children: REMOTE_SESSION_KEEP_REASON_LABELS[value] }, value)) })
|
|
1837
2443
|
]
|
|
1838
2444
|
}
|
|
1839
2445
|
),
|
|
1840
|
-
reason === "OTHER" && /* @__PURE__ */
|
|
2446
|
+
reason === "OTHER" && /* @__PURE__ */ jsx21(
|
|
1841
2447
|
Input,
|
|
1842
2448
|
{
|
|
1843
2449
|
"aria-label": "Reason description",
|
|
@@ -1849,10 +2455,10 @@ function KeepRecordingModal({
|
|
|
1849
2455
|
}
|
|
1850
2456
|
)
|
|
1851
2457
|
] }),
|
|
1852
|
-
/* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
2458
|
+
/* @__PURE__ */ jsxs19(ModalFooter, { children: [
|
|
2459
|
+
/* @__PURE__ */ jsx21(Button, { type: "button", variant: "outline", onClick: onClose, disabled: isPending, className: "flex-1 md:hidden", children: "Cancel" }),
|
|
2460
|
+
/* @__PURE__ */ jsx21("div", { className: "hidden flex-1 md:block" }),
|
|
2461
|
+
/* @__PURE__ */ jsx21(
|
|
1856
2462
|
Button,
|
|
1857
2463
|
{
|
|
1858
2464
|
type: "button",
|
|
@@ -1873,17 +2479,17 @@ function ReleaseKeepingModal({
|
|
|
1873
2479
|
keptBy,
|
|
1874
2480
|
keptOn,
|
|
1875
2481
|
reason,
|
|
1876
|
-
|
|
2482
|
+
tickets = [],
|
|
1877
2483
|
expiresOn,
|
|
1878
2484
|
dueOn,
|
|
1879
2485
|
isPending = false,
|
|
1880
2486
|
onConfirm
|
|
1881
2487
|
}) {
|
|
1882
|
-
return /* @__PURE__ */
|
|
2488
|
+
return /* @__PURE__ */ jsxs19(Modal, { isOpen, onClose: isPending ? () => {
|
|
1883
2489
|
} : onClose, className: "text-left md:max-w-[600px]", children: [
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */
|
|
1886
|
-
/* @__PURE__ */
|
|
2490
|
+
/* @__PURE__ */ jsx21(ModalHeader, { children: /* @__PURE__ */ jsx21(ModalTitle, { children: "Release Keeping" }) }),
|
|
2491
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex w-full flex-col gap-[var(--spacing-system-xsf)] text-ods-text-primary text-h4", children: [
|
|
2492
|
+
/* @__PURE__ */ jsxs19("p", { children: [
|
|
1887
2493
|
"Kept by ",
|
|
1888
2494
|
keptBy,
|
|
1889
2495
|
" on ",
|
|
@@ -1892,22 +2498,108 @@ function ReleaseKeepingModal({
|
|
|
1892
2498
|
reason,
|
|
1893
2499
|
"."
|
|
1894
2500
|
] }),
|
|
1895
|
-
|
|
2501
|
+
tickets.length > 0 && /* @__PURE__ */ jsxs19("p", { children: [
|
|
1896
2502
|
"Ticket: ",
|
|
1897
|
-
|
|
2503
|
+
tickets.join(", ")
|
|
1898
2504
|
] })
|
|
1899
2505
|
] }),
|
|
1900
|
-
/* @__PURE__ */
|
|
1901
|
-
/* @__PURE__ */
|
|
1902
|
-
/* @__PURE__ */
|
|
1903
|
-
/* @__PURE__ */
|
|
1904
|
-
/* @__PURE__ */
|
|
2506
|
+
/* @__PURE__ */ jsx21(KeepNotice, { icon: /* @__PURE__ */ jsx21(HourglassIcon, { size: 24, color: "currentColor" }), title: `It will expire on ${expiresOn}`, children: dueOn ? `It was due to expire on ${dueOn}. Releasing gives it 3 days' grace, and it shows amber until then. Whoever placed the Keep is reminded the day before it goes. Nothing is deleted now.` : "Nothing is deleted now." }),
|
|
2507
|
+
/* @__PURE__ */ jsxs19(ModalFooter, { children: [
|
|
2508
|
+
/* @__PURE__ */ jsx21(Button, { type: "button", variant: "outline", onClick: onClose, disabled: isPending, className: "flex-1 md:hidden", children: "Cancel" }),
|
|
2509
|
+
/* @__PURE__ */ jsx21("div", { className: "hidden flex-1 md:block" }),
|
|
2510
|
+
/* @__PURE__ */ jsx21(Button, { type: "button", variant: "accent", onClick: onConfirm, loading: isPending, className: "flex-1", children: "Release Keeping" })
|
|
2511
|
+
] })
|
|
2512
|
+
] });
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
// src/components/features/remote-session/remote-session-ticket-modals.tsx
|
|
2516
|
+
import { useState as useState5 } from "react";
|
|
2517
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2518
|
+
function AssignTicketModal({
|
|
2519
|
+
isOpen,
|
|
2520
|
+
onClose,
|
|
2521
|
+
options,
|
|
2522
|
+
onSearch,
|
|
2523
|
+
loading = false,
|
|
2524
|
+
isPending = false,
|
|
2525
|
+
onConfirm
|
|
2526
|
+
}) {
|
|
2527
|
+
const [ticketIds, setTicketIds] = useState5([]);
|
|
2528
|
+
const [titles, setTitles] = useState5({});
|
|
2529
|
+
const [seededOpen, setSeededOpen] = useState5(isOpen);
|
|
2530
|
+
if (seededOpen !== isOpen) {
|
|
2531
|
+
setSeededOpen(isOpen);
|
|
2532
|
+
if (isOpen) {
|
|
2533
|
+
setTicketIds([]);
|
|
2534
|
+
setTitles({});
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
const handleChange = (ids) => {
|
|
2538
|
+
setTicketIds(ids);
|
|
2539
|
+
setTitles((prev) => {
|
|
2540
|
+
const next = {};
|
|
2541
|
+
for (const id of ids) next[id] = options.find((option) => option.value === id)?.label ?? prev[id] ?? id;
|
|
2542
|
+
return next;
|
|
2543
|
+
});
|
|
2544
|
+
};
|
|
2545
|
+
const handleAssign = () => {
|
|
2546
|
+
if (ticketIds.length === 0 || isPending) return;
|
|
2547
|
+
onConfirm(ticketIds);
|
|
2548
|
+
};
|
|
2549
|
+
return /* @__PURE__ */ jsxs20(Modal, { isOpen, onClose: isPending ? () => {
|
|
2550
|
+
} : onClose, className: "text-left md:max-w-[600px]", children: [
|
|
2551
|
+
/* @__PURE__ */ jsx22(ModalHeader, { children: /* @__PURE__ */ jsx22(ModalTitle, { children: "Assign Ticket" }) }),
|
|
2552
|
+
/* @__PURE__ */ jsx22(
|
|
2553
|
+
Autocomplete,
|
|
2554
|
+
{
|
|
2555
|
+
multiple: true,
|
|
2556
|
+
wrapTags: true,
|
|
2557
|
+
label: "Tickets",
|
|
2558
|
+
labelVariant: "large",
|
|
2559
|
+
options,
|
|
2560
|
+
value: ticketIds,
|
|
2561
|
+
onChange: handleChange,
|
|
2562
|
+
renderTag: (option) => titles[option.value] ?? option.label,
|
|
2563
|
+
onInputChange: onSearch ? (value, reason) => reason === "input" && onSearch(value) : void 0,
|
|
2564
|
+
disableClientFilter: Boolean(onSearch),
|
|
2565
|
+
loading,
|
|
2566
|
+
noOptionsText: "No tickets found",
|
|
2567
|
+
disabled: isPending
|
|
2568
|
+
}
|
|
2569
|
+
),
|
|
2570
|
+
/* @__PURE__ */ jsxs20(ModalFooter, { children: [
|
|
2571
|
+
/* @__PURE__ */ jsx22(Button, { type: "button", variant: "outline", onClick: onClose, disabled: isPending, className: "flex-1 md:hidden", children: "Cancel" }),
|
|
2572
|
+
/* @__PURE__ */ jsx22("div", { className: "hidden flex-1 md:block" }),
|
|
2573
|
+
/* @__PURE__ */ jsx22(
|
|
2574
|
+
Button,
|
|
2575
|
+
{
|
|
2576
|
+
type: "button",
|
|
2577
|
+
variant: "accent",
|
|
2578
|
+
onClick: handleAssign,
|
|
2579
|
+
loading: isPending,
|
|
2580
|
+
disabled: ticketIds.length === 0,
|
|
2581
|
+
className: "flex-1",
|
|
2582
|
+
children: "Assign"
|
|
2583
|
+
}
|
|
2584
|
+
)
|
|
2585
|
+
] })
|
|
2586
|
+
] });
|
|
2587
|
+
}
|
|
2588
|
+
function UnassignTicketModal({ isOpen, onClose, isPending = false, onConfirm }) {
|
|
2589
|
+
return /* @__PURE__ */ jsxs20(Modal, { isOpen, onClose: isPending ? () => {
|
|
2590
|
+
} : onClose, className: "text-left md:max-w-[600px]", children: [
|
|
2591
|
+
/* @__PURE__ */ jsx22(ModalHeader, { children: /* @__PURE__ */ jsx22(ModalTitle, { children: "Unassign Ticket" }) }),
|
|
2592
|
+
/* @__PURE__ */ jsx22("p", { className: "w-full text-ods-text-primary text-h4", children: "This Ticket will no longer be linked to this remote session. The ticket itself stays as it is, and you can assign it again anytime." }),
|
|
2593
|
+
/* @__PURE__ */ jsxs20(ModalFooter, { children: [
|
|
2594
|
+
/* @__PURE__ */ jsx22(Button, { type: "button", variant: "outline", onClick: onClose, disabled: isPending, className: "flex-1 md:hidden", children: "Cancel" }),
|
|
2595
|
+
/* @__PURE__ */ jsx22("div", { className: "hidden flex-1 md:block" }),
|
|
2596
|
+
/* @__PURE__ */ jsx22(Button, { type: "button", variant: "destructive", onClick: onConfirm, loading: isPending, className: "flex-1", children: "Unassign" })
|
|
1905
2597
|
] })
|
|
1906
2598
|
] });
|
|
1907
2599
|
}
|
|
1908
2600
|
|
|
1909
2601
|
// src/components/features/remote-session/remote-session-events.tsx
|
|
1910
|
-
import { jsx as
|
|
2602
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1911
2603
|
function formatRemoteSessionOffset(offsetMs) {
|
|
1912
2604
|
const total = Math.max(0, Math.floor(offsetMs / 1e3));
|
|
1913
2605
|
const hours = Math.floor(total / 3600);
|
|
@@ -1916,9 +2608,9 @@ function formatRemoteSessionOffset(offsetMs) {
|
|
|
1916
2608
|
return hours > 0 ? `${hours}:${minutes}:${seconds}` : `${minutes}:${seconds}`;
|
|
1917
2609
|
}
|
|
1918
2610
|
function RemoteSessionEventList({ events, activeEventId, onSelect, className }) {
|
|
1919
|
-
return /* @__PURE__ */
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
2611
|
+
return /* @__PURE__ */ jsxs21("section", { className: cn("flex w-full flex-col gap-[var(--spacing-system-xxs)]", className), children: [
|
|
2612
|
+
/* @__PURE__ */ jsx23("h2", { className: "text-ods-text-secondary text-h5", children: "Session Events" }),
|
|
2613
|
+
/* @__PURE__ */ jsx23("ol", { className: "flex w-full flex-col gap-[var(--spacing-system-xxs)] rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-m)]", children: events.map((event) => /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsxs21(
|
|
1922
2614
|
"button",
|
|
1923
2615
|
{
|
|
1924
2616
|
type: "button",
|
|
@@ -1930,10 +2622,10 @@ function RemoteSessionEventList({ events, activeEventId, onSelect, className })
|
|
|
1930
2622
|
event.id === activeEventId && "bg-ods-border hover:bg-ods-border"
|
|
1931
2623
|
),
|
|
1932
2624
|
children: [
|
|
1933
|
-
/* @__PURE__ */
|
|
1934
|
-
/* @__PURE__ */
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
event.detail && /* @__PURE__ */
|
|
2625
|
+
/* @__PURE__ */ jsx23("span", { className: "w-[84px] shrink-0 text-ods-text-secondary text-h4", children: formatRemoteSessionOffset(event.offsetMs) }),
|
|
2626
|
+
/* @__PURE__ */ jsxs21("span", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
2627
|
+
/* @__PURE__ */ jsx23("span", { className: "text-ods-text-primary text-h4", children: event.title }),
|
|
2628
|
+
event.detail && /* @__PURE__ */ jsx23("span", { className: "text-ods-text-secondary text-h6", children: event.detail })
|
|
1937
2629
|
] })
|
|
1938
2630
|
]
|
|
1939
2631
|
}
|
|
@@ -1947,10 +2639,10 @@ function RemoteSessionTimelineMarkers({
|
|
|
1947
2639
|
className
|
|
1948
2640
|
}) {
|
|
1949
2641
|
if (durationMs <= 0) return null;
|
|
1950
|
-
return /* @__PURE__ */
|
|
2642
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("relative h-4 w-full", className), children: events.map((event) => {
|
|
1951
2643
|
const share = Math.min(1, Math.max(0, event.offsetMs / durationMs));
|
|
1952
2644
|
const label = `${event.title} at ${formatRemoteSessionOffset(event.offsetMs)}`;
|
|
1953
|
-
return /* @__PURE__ */
|
|
2645
|
+
return /* @__PURE__ */ jsx23(
|
|
1954
2646
|
"button",
|
|
1955
2647
|
{
|
|
1956
2648
|
type: "button",
|
|
@@ -1966,9 +2658,9 @@ function RemoteSessionTimelineMarkers({
|
|
|
1966
2658
|
}
|
|
1967
2659
|
|
|
1968
2660
|
// src/components/features/remote-session/remote-session-status.tsx
|
|
1969
|
-
import { jsx as
|
|
2661
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1970
2662
|
function LiveDot() {
|
|
1971
|
-
return /* @__PURE__ */
|
|
2663
|
+
return /* @__PURE__ */ jsx24("span", { "aria-hidden": true, className: "size-2 animate-live-pulse rounded-full bg-current motion-reduce:animate-none" });
|
|
1972
2664
|
}
|
|
1973
2665
|
var STATUS_TAG = {
|
|
1974
2666
|
live: { label: "Live", variant: "critical" },
|
|
@@ -1977,12 +2669,12 @@ var STATUS_TAG = {
|
|
|
1977
2669
|
};
|
|
1978
2670
|
function RemoteSessionStatusTag({ status, className }) {
|
|
1979
2671
|
const { label, variant } = STATUS_TAG[status];
|
|
1980
|
-
return /* @__PURE__ */
|
|
2672
|
+
return /* @__PURE__ */ jsx24(
|
|
1981
2673
|
Tag,
|
|
1982
2674
|
{
|
|
1983
2675
|
label,
|
|
1984
2676
|
variant,
|
|
1985
|
-
icon: status === "live" ? /* @__PURE__ */
|
|
2677
|
+
icon: status === "live" ? /* @__PURE__ */ jsx24(LiveDot, {}) : void 0,
|
|
1986
2678
|
className: cn("pointer-events-none shrink-0", className)
|
|
1987
2679
|
}
|
|
1988
2680
|
);
|
|
@@ -1990,18 +2682,18 @@ function RemoteSessionStatusTag({ status, className }) {
|
|
|
1990
2682
|
function RemoteSessionExpiry(props) {
|
|
1991
2683
|
const { className } = props;
|
|
1992
2684
|
if (props.state === "none") {
|
|
1993
|
-
return /* @__PURE__ */
|
|
2685
|
+
return /* @__PURE__ */ jsx24("p", { className: cn("text-ods-text-primary text-h4", className), children: "-" });
|
|
1994
2686
|
}
|
|
1995
2687
|
if (props.state === "expired") {
|
|
1996
|
-
return /* @__PURE__ */
|
|
2688
|
+
return /* @__PURE__ */ jsx24("p", { className: cn("text-ods-text-secondary text-h4", className), children: "Expired" });
|
|
1997
2689
|
}
|
|
1998
2690
|
if (props.state === "kept") {
|
|
1999
|
-
return /* @__PURE__ */
|
|
2000
|
-
/* @__PURE__ */
|
|
2001
|
-
/* @__PURE__ */
|
|
2691
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("flex min-w-0 flex-col", className), children: [
|
|
2692
|
+
/* @__PURE__ */ jsxs22("p", { className: "flex items-center gap-[var(--spacing-system-xxs)] text-ods-text-primary text-h4", children: [
|
|
2693
|
+
/* @__PURE__ */ jsx24(LockIcon, { size: 24, color: "currentColor", className: "shrink-0" }),
|
|
2002
2694
|
"Kept"
|
|
2003
2695
|
] }),
|
|
2004
|
-
/* @__PURE__ */
|
|
2696
|
+
/* @__PURE__ */ jsxs22("p", { className: "truncate text-ods-text-secondary text-h6", children: [
|
|
2005
2697
|
"Kept by ",
|
|
2006
2698
|
props.keptBy,
|
|
2007
2699
|
" \xB7 ",
|
|
@@ -2009,14 +2701,14 @@ function RemoteSessionExpiry(props) {
|
|
|
2009
2701
|
] })
|
|
2010
2702
|
] });
|
|
2011
2703
|
}
|
|
2012
|
-
return /* @__PURE__ */
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
props.remaining && /* @__PURE__ */
|
|
2704
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("flex min-w-0 flex-col", className), children: [
|
|
2705
|
+
/* @__PURE__ */ jsx24("p", { className: "text-ods-text-primary text-h4", children: props.date }),
|
|
2706
|
+
props.remaining && /* @__PURE__ */ jsx24("p", { className: "truncate text-ods-text-secondary text-h6", children: props.remaining })
|
|
2015
2707
|
] });
|
|
2016
2708
|
}
|
|
2017
2709
|
function RemoteSessionStorageAlert({ scope, capacity, className }) {
|
|
2018
2710
|
const message = scope === "session" ? "This session isn't being recorded. Recording storage is full. New sessions aren't recorded until space is freed." : `Recording storage full. New sessions aren't recorded.${capacity ? ` All ${capacity} of recording storage is used.` : ""}`;
|
|
2019
|
-
return /* @__PURE__ */
|
|
2711
|
+
return /* @__PURE__ */ jsxs22(
|
|
2020
2712
|
"div",
|
|
2021
2713
|
{
|
|
2022
2714
|
role: "alert",
|
|
@@ -2025,15 +2717,17 @@ function RemoteSessionStorageAlert({ scope, capacity, className }) {
|
|
|
2025
2717
|
className
|
|
2026
2718
|
),
|
|
2027
2719
|
children: [
|
|
2028
|
-
/* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2720
|
+
/* @__PURE__ */ jsx24(AlertTriangleIcon, { size: 24, color: "currentColor", className: "shrink-0" }),
|
|
2721
|
+
/* @__PURE__ */ jsx24("p", { className: "min-w-0 flex-1 text-h3", children: message })
|
|
2030
2722
|
]
|
|
2031
2723
|
}
|
|
2032
2724
|
);
|
|
2033
2725
|
}
|
|
2034
2726
|
|
|
2035
2727
|
export {
|
|
2728
|
+
HiddenTagsPopup,
|
|
2036
2729
|
TruncateText,
|
|
2730
|
+
Autocomplete,
|
|
2037
2731
|
Select,
|
|
2038
2732
|
SelectGroup,
|
|
2039
2733
|
SelectValue,
|
|
@@ -2078,6 +2772,8 @@ export {
|
|
|
2078
2772
|
REMOTE_SESSION_KEEP_REASON_LABELS,
|
|
2079
2773
|
KeepRecordingModal,
|
|
2080
2774
|
ReleaseKeepingModal,
|
|
2775
|
+
AssignTicketModal,
|
|
2776
|
+
UnassignTicketModal,
|
|
2081
2777
|
formatRemoteSessionOffset,
|
|
2082
2778
|
RemoteSessionEventList,
|
|
2083
2779
|
RemoteSessionTimelineMarkers,
|