@skyvexsoftware/stratos-sdk 0.16.3 → 0.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,13 @@ type UseTrackingSessionReturn = {
27
27
  reconnecting: boolean;
28
28
  /** Reason tracking is suspended; null when not suspended. */
29
29
  suspendReason: string | null;
30
+ /**
31
+ * Why auto-start has not started a flight yet, as a sentence fragment
32
+ * ("the aircraft is 260 nm from CYUL, the nearest booked departure"); null
33
+ * when auto-start is off, not polling, a flight is active, or the shell
34
+ * predates core 2.32.17.
35
+ */
36
+ autoStartWaitReason: string | null;
30
37
  currentFlight: CurrentFlight | null;
31
38
  pendingRecovery: RecoverableFlight | null;
32
39
  elapsedTime: number;
@@ -75,6 +75,7 @@ export function useTrackingSession() {
75
75
  const simDisconnected = stateData?.simDisconnected ?? false;
76
76
  const reconnecting = stateData?.reconnecting ?? false;
77
77
  const suspendReason = stateData?.suspendReason ?? null;
78
+ const autoStartWaitReason = stateData?.autoStartWaitReason ?? null;
78
79
  const startFlight = useCallback(async (plan, options) => {
79
80
  const result = await api("/start", "POST", { flightPlan: plan, options });
80
81
  return result.data;
@@ -158,6 +159,7 @@ export function useTrackingSession() {
158
159
  simDisconnected,
159
160
  reconnecting,
160
161
  suspendReason,
162
+ autoStartWaitReason,
161
163
  currentFlight: flight,
162
164
  pendingRecovery,
163
165
  elapsedTime,
@@ -134,6 +134,13 @@ export type FlightManagerPayload = {
134
134
  reconnecting: boolean;
135
135
  /** Why tracking is suspended (continuity gate asserted a discontinuity), or null. Present whenever `simDisconnected` is true. */
136
136
  suspendReason?: string | null;
137
+ /**
138
+ * Why auto-start has not started a flight yet, as a sentence fragment
139
+ * ("the aircraft is 260 nm from CYUL, the nearest booked departure"), or
140
+ * null when auto-start is off, not polling, or a flight is active. Absent
141
+ * on shells before core 2.32.17.
142
+ */
143
+ autoStartWaitReason?: string | null;
137
144
  timestamp: number;
138
145
  };
139
146
  /** Result returned from startFlight */
@@ -4,6 +4,12 @@ import * as React from "react";
4
4
  export type ComboboxOption = {
5
5
  value: string;
6
6
  label: string;
7
+ /**
8
+ * Optional heading to list this option under. Groups render in the order
9
+ * they are first seen; options without a group render first, ungrouped.
10
+ * Omit on every option for a flat list.
11
+ */
12
+ group?: string;
7
13
  };
8
14
  /** Props for the searchable single-select `Combobox` component. */
9
15
  export type ComboboxProps = {
@@ -19,8 +19,25 @@ export function Combobox({ options, value, onValueChange, placeholder = "Select
19
19
  setOpen(next);
20
20
  onOpenChange?.(next);
21
21
  };
22
- return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, disabled: disabled, className: cn("border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", triggerClassName), children: [_jsx("span", { className: cn("truncate", !selected && "text-muted-foreground"), children: selected ? selected.label : placeholder }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { align: align, className: cn("w-[var(--radix-popover-trigger-width)] p-0", contentClassName), children: _jsxs(Command, { className: "text-popover-foreground flex w-full flex-col overflow-hidden", children: [_jsxs("div", { className: "border-border flex items-center border-b px-2.5", children: [_jsx(Search, { className: "text-muted-foreground mr-2 h-4 w-4 shrink-0" }), _jsx(Command.Input, { placeholder: searchPlaceholder, "aria-label": inputAriaLabel, className: "placeholder:text-muted-foreground h-9 w-full bg-transparent py-2 text-sm outline-none" })] }), _jsx(Command.List, { className: "max-h-60 overflow-y-auto p-1", children: loading ? (_jsx("div", { className: "text-muted-foreground py-3 text-center text-sm", children: loadingText })) : (_jsxs(_Fragment, { children: [_jsx(Command.Empty, { className: "text-muted-foreground py-3 text-center text-sm", children: emptyText }), options.map((option) => (_jsxs(Command.Item, { value: `${option.label} ${option.value}`, onSelect: () => {
23
- onValueChange?.(option.value);
24
- handleOpenChange(false);
25
- }, className: "aria-selected:bg-accent aria-selected:text-accent-foreground flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm outline-none", children: [_jsx(Check, { className: cn("mr-2 h-4 w-4 shrink-0", value === option.value ? "opacity-100" : "opacity-0") }), _jsx("span", { className: "truncate", children: option.label })] }, option.value)))] })) })] }) })] }));
22
+ // Ungrouped options stay flat at the top; grouped ones render under a
23
+ // heading per group, in first-seen order.
24
+ const ungrouped = options.filter((option) => !option.group);
25
+ const groups = React.useMemo(() => {
26
+ const byGroup = new Map();
27
+ for (const option of options) {
28
+ if (!option.group)
29
+ continue;
30
+ const bucket = byGroup.get(option.group);
31
+ if (bucket)
32
+ bucket.push(option);
33
+ else
34
+ byGroup.set(option.group, [option]);
35
+ }
36
+ return Array.from(byGroup.entries());
37
+ }, [options]);
38
+ const renderItem = (option) => (_jsxs(Command.Item, { value: `${option.label} ${option.value}`, onSelect: () => {
39
+ onValueChange?.(option.value);
40
+ handleOpenChange(false);
41
+ }, className: "aria-selected:bg-accent aria-selected:text-accent-foreground flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm outline-none", children: [_jsx(Check, { className: cn("mr-2 h-4 w-4 shrink-0", value === option.value ? "opacity-100" : "opacity-0") }), _jsx("span", { className: "truncate", children: option.label })] }, option.value));
42
+ return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, disabled: disabled, className: cn("border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", triggerClassName), children: [_jsx("span", { className: cn("truncate", !selected && "text-muted-foreground"), children: selected ? selected.label : placeholder }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { align: align, className: cn("w-[var(--radix-popover-trigger-width)] p-0", contentClassName), children: _jsxs(Command, { className: "text-popover-foreground flex w-full flex-col overflow-hidden", children: [_jsxs("div", { className: "border-border flex items-center border-b px-2.5", children: [_jsx(Search, { className: "text-muted-foreground mr-2 h-4 w-4 shrink-0" }), _jsx(Command.Input, { placeholder: searchPlaceholder, "aria-label": inputAriaLabel, className: "placeholder:text-muted-foreground h-9 w-full bg-transparent py-2 text-sm outline-none" })] }), _jsx(Command.List, { className: "max-h-60 overflow-y-auto p-1", children: loading ? (_jsx("div", { className: "text-muted-foreground py-3 text-center text-sm", children: loadingText })) : (_jsxs(_Fragment, { children: [_jsx(Command.Empty, { className: "text-muted-foreground py-3 text-center text-sm", children: emptyText }), ungrouped.map(renderItem), groups.map(([heading, items]) => (_jsx(Command.Group, { heading: heading, className: "[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium", children: items.map(renderItem) }, heading)))] })) })] }) })] }));
26
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyvexsoftware/stratos-sdk",
3
- "version": "0.16.3",
3
+ "version": "0.16.5",
4
4
  "description": "Plugin SDK for Stratos — types, hooks, and UI components",
5
5
  "author": {
6
6
  "name": "Skyvex Software Pty Ltd",