@petrarca/sonnet-shell 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -6
- package/dist/index.d.ts +96 -2
- package/dist/index.js +393 -195
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
useEffect as useEffect3,
|
|
5
5
|
useCallback as useCallback2,
|
|
6
6
|
useRef as useRef2,
|
|
7
|
-
useMemo as
|
|
7
|
+
useMemo as useMemo5
|
|
8
8
|
} from "react";
|
|
9
|
+
import { useResizablePanel as useResizablePanel2 } from "@petrarca/sonnet-core/hooks";
|
|
9
10
|
import { Outlet, useLocation as useLocation2, useNavigate as useNavigate2 } from "react-router-dom";
|
|
10
11
|
import { TooltipProvider } from "@petrarca/sonnet-ui";
|
|
11
12
|
import { ScrollArea as ScrollArea2 } from "@petrarca/sonnet-ui";
|
|
@@ -74,6 +75,9 @@ function ShellFooter({ children }) {
|
|
|
74
75
|
return /* @__PURE__ */ jsx3("footer", { className: "h-8 shrink-0 border-t border-border flex items-center justify-between px-3 bg-background text-[11px] text-muted-foreground z-20", children });
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
// src/ShellRail.tsx
|
|
79
|
+
import { useMemo as useMemo3 } from "react";
|
|
80
|
+
|
|
77
81
|
// src/IconRail.tsx
|
|
78
82
|
import { cn } from "@petrarca/sonnet-core";
|
|
79
83
|
import { Button as Button2, Separator } from "@petrarca/sonnet-ui";
|
|
@@ -98,7 +102,9 @@ function RailIcon({
|
|
|
98
102
|
icon: Icon,
|
|
99
103
|
label,
|
|
100
104
|
active = false,
|
|
101
|
-
onClick
|
|
105
|
+
onClick,
|
|
106
|
+
disabled = false,
|
|
107
|
+
tooltip
|
|
102
108
|
}) {
|
|
103
109
|
return /* @__PURE__ */ jsxs2(Tooltip, { delayDuration: 0, children: [
|
|
104
110
|
/* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
|
|
@@ -106,10 +112,11 @@ function RailIcon({
|
|
|
106
112
|
{
|
|
107
113
|
variant: "ghost",
|
|
108
114
|
size: "compact",
|
|
109
|
-
|
|
115
|
+
"aria-disabled": disabled || void 0,
|
|
116
|
+
onClick: disabled ? void 0 : onClick,
|
|
110
117
|
className: cn(
|
|
111
118
|
"h-10 w-10 rounded-lg transition-colors",
|
|
112
|
-
active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground hover:bg-muted-foreground/10"
|
|
119
|
+
disabled ? "text-muted-foreground/40 cursor-default hover:bg-transparent" : active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground hover:bg-muted-foreground/10"
|
|
113
120
|
),
|
|
114
121
|
children: [
|
|
115
122
|
/* @__PURE__ */ jsx4(Icon, { className: "h-5 w-5" }),
|
|
@@ -117,7 +124,7 @@ function RailIcon({
|
|
|
117
124
|
]
|
|
118
125
|
}
|
|
119
126
|
) }),
|
|
120
|
-
/* @__PURE__ */ jsx4(TooltipContent, { side: "right", sideOffset: 8, children: label })
|
|
127
|
+
/* @__PURE__ */ jsx4(TooltipContent, { side: "right", sideOffset: 8, children: tooltip ?? label })
|
|
121
128
|
] });
|
|
122
129
|
}
|
|
123
130
|
function RailSeparator() {
|
|
@@ -645,10 +652,82 @@ function useShellNavigation() {
|
|
|
645
652
|
return ctx;
|
|
646
653
|
}
|
|
647
654
|
|
|
655
|
+
// src/shellConfig.ts
|
|
656
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
657
|
+
var ShellConfigContext = createContext3(null);
|
|
658
|
+
function useShellConfig() {
|
|
659
|
+
const config = useContext3(ShellConfigContext);
|
|
660
|
+
if (!config) {
|
|
661
|
+
throw new Error("useShellConfig must be used within a ShellConfigProvider");
|
|
662
|
+
}
|
|
663
|
+
return config;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// src/capabilities.ts
|
|
667
|
+
import { warnLog as warnLog3 } from "@petrarca/sonnet-core";
|
|
668
|
+
var DEFAULT_CAPABILITY_POLICY = {
|
|
669
|
+
"missing-state": { rail: "disabled", command: "disabled", route: "redirect" },
|
|
670
|
+
"not-authorized": { rail: "hidden", command: "hidden", route: "redirect" },
|
|
671
|
+
"not-authorized-soft": {
|
|
672
|
+
rail: "disabled",
|
|
673
|
+
command: "disabled",
|
|
674
|
+
route: "redirect"
|
|
675
|
+
},
|
|
676
|
+
"feature-off": { rail: "hidden", command: "disabled", route: "redirect" },
|
|
677
|
+
error: { rail: "hidden", command: "hidden", route: "redirect" }
|
|
678
|
+
};
|
|
679
|
+
var EFFECT_RANK = {
|
|
680
|
+
hidden: 3,
|
|
681
|
+
redirect: 2,
|
|
682
|
+
disabled: 1,
|
|
683
|
+
visible: 0
|
|
684
|
+
};
|
|
685
|
+
function resolveCapabilityPolicy(override) {
|
|
686
|
+
if (!override) return DEFAULT_CAPABILITY_POLICY;
|
|
687
|
+
const merged = {};
|
|
688
|
+
for (const kind of Object.keys(DEFAULT_CAPABILITY_POLICY)) {
|
|
689
|
+
merged[kind] = {
|
|
690
|
+
...DEFAULT_CAPABILITY_POLICY[kind],
|
|
691
|
+
...override[kind] ?? {}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
return merged;
|
|
695
|
+
}
|
|
696
|
+
function foldUnmet(effect, resultReason, acc) {
|
|
697
|
+
const rank = EFFECT_RANK[effect];
|
|
698
|
+
const worstRank = EFFECT_RANK[acc.effect];
|
|
699
|
+
if (rank > worstRank) {
|
|
700
|
+
return { effect, reason: resultReason };
|
|
701
|
+
}
|
|
702
|
+
if (rank === worstRank && !acc.reason && resultReason) {
|
|
703
|
+
return { effect: acc.effect, reason: resultReason };
|
|
704
|
+
}
|
|
705
|
+
return acc;
|
|
706
|
+
}
|
|
707
|
+
function evaluateModule(module, surface, resolve, policy) {
|
|
708
|
+
const capabilities = module.requires;
|
|
709
|
+
if (!capabilities || capabilities.length === 0) return { effect: "visible" };
|
|
710
|
+
if (!resolve) return { effect: "visible" };
|
|
711
|
+
let acc = { effect: "visible" };
|
|
712
|
+
for (const capability of capabilities) {
|
|
713
|
+
const result = resolve(capability);
|
|
714
|
+
if (result.met) continue;
|
|
715
|
+
const kind = result.kind ?? "error";
|
|
716
|
+
if (kind === "error") {
|
|
717
|
+
warnLog3(
|
|
718
|
+
`[capabilities] unmet capability "${capability}" resolved to kind "error" (fail-closed)`
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
acc = foldUnmet(policy[kind][surface], result.reason, acc);
|
|
722
|
+
}
|
|
723
|
+
return acc;
|
|
724
|
+
}
|
|
725
|
+
|
|
648
726
|
// src/ShellRail.tsx
|
|
649
727
|
import { Fragment, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
650
728
|
function ShellRail() {
|
|
651
729
|
const { mainModules, bottomModules } = useShellModules();
|
|
730
|
+
const { resolveCapability, capabilityPolicy } = useShellConfig();
|
|
652
731
|
const {
|
|
653
732
|
activeService,
|
|
654
733
|
sidePaneModuleId,
|
|
@@ -657,29 +736,37 @@ function ShellRail() {
|
|
|
657
736
|
onServiceSelect
|
|
658
737
|
} = useShellNavigation();
|
|
659
738
|
const isActive = (id) => activeService?.id === id || sidePaneModuleId === id;
|
|
739
|
+
const policy = useMemo3(
|
|
740
|
+
() => resolveCapabilityPolicy(capabilityPolicy),
|
|
741
|
+
[capabilityPolicy]
|
|
742
|
+
);
|
|
743
|
+
const renderModule = (service) => {
|
|
744
|
+
const { effect, reason } = evaluateModule(
|
|
745
|
+
service,
|
|
746
|
+
"rail",
|
|
747
|
+
resolveCapability,
|
|
748
|
+
policy
|
|
749
|
+
);
|
|
750
|
+
if (effect === "hidden" || effect === "redirect") return null;
|
|
751
|
+
const disabled = effect === "disabled";
|
|
752
|
+
return /* @__PURE__ */ jsx8(
|
|
753
|
+
RailIcon,
|
|
754
|
+
{
|
|
755
|
+
icon: service.icon,
|
|
756
|
+
label: service.label,
|
|
757
|
+
active: isActive(service.id),
|
|
758
|
+
onClick: () => onServiceSelect(service.id),
|
|
759
|
+
disabled,
|
|
760
|
+
tooltip: disabled && reason ? `${service.label} \u2014 ${reason}` : void 0
|
|
761
|
+
},
|
|
762
|
+
service.id
|
|
763
|
+
);
|
|
764
|
+
};
|
|
660
765
|
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
661
766
|
/* @__PURE__ */ jsxs6(IconRail, { children: [
|
|
662
|
-
/* @__PURE__ */ jsx8("div", { className: "flex-1 flex flex-col items-center gap-1 overflow-y-auto", children: mainModules.map(
|
|
663
|
-
RailIcon,
|
|
664
|
-
{
|
|
665
|
-
icon: service.icon,
|
|
666
|
-
label: service.label,
|
|
667
|
-
active: isActive(service.id),
|
|
668
|
-
onClick: () => onServiceSelect(service.id)
|
|
669
|
-
},
|
|
670
|
-
service.id
|
|
671
|
-
)) }),
|
|
767
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 flex flex-col items-center gap-1 overflow-y-auto", children: mainModules.map(renderModule) }),
|
|
672
768
|
/* @__PURE__ */ jsx8(RailSeparator, {}),
|
|
673
|
-
/* @__PURE__ */ jsx8("div", { className: "flex flex-col items-center gap-1", children: bottomModules.map(
|
|
674
|
-
RailIcon,
|
|
675
|
-
{
|
|
676
|
-
icon: service.icon,
|
|
677
|
-
label: service.label,
|
|
678
|
-
active: isActive(service.id),
|
|
679
|
-
onClick: () => onServiceSelect(service.id)
|
|
680
|
-
},
|
|
681
|
-
service.id
|
|
682
|
-
)) })
|
|
769
|
+
/* @__PURE__ */ jsx8("div", { className: "flex flex-col items-center gap-1", children: bottomModules.map(renderModule) })
|
|
683
770
|
] }),
|
|
684
771
|
activeService && activeService.navigation.length > 0 && /* @__PURE__ */ jsx8(
|
|
685
772
|
SubNavPanel,
|
|
@@ -694,23 +781,25 @@ function ShellRail() {
|
|
|
694
781
|
|
|
695
782
|
// src/SidePane.tsx
|
|
696
783
|
import { X } from "lucide-react";
|
|
697
|
-
import { cn as
|
|
784
|
+
import { cn as cn5 } from "@petrarca/sonnet-core";
|
|
698
785
|
import { useResizablePanel } from "@petrarca/sonnet-core/hooks";
|
|
699
786
|
|
|
700
787
|
// src/sidePaneState.ts
|
|
701
|
-
import { createContext as
|
|
702
|
-
var SidePaneContext =
|
|
788
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
789
|
+
var SidePaneContext = createContext4(null);
|
|
703
790
|
function useSidePaneState() {
|
|
704
|
-
const ctx =
|
|
791
|
+
const ctx = useContext4(SidePaneContext);
|
|
705
792
|
if (!ctx) {
|
|
706
793
|
throw new Error("useSidePaneState must be used within an AppShell");
|
|
707
794
|
}
|
|
708
795
|
return ctx;
|
|
709
796
|
}
|
|
710
797
|
|
|
711
|
-
// src/
|
|
712
|
-
import {
|
|
798
|
+
// src/DragHandle.tsx
|
|
799
|
+
import { cn as cn4 } from "@petrarca/sonnet-core";
|
|
800
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
713
801
|
function DragHandle({
|
|
802
|
+
edge,
|
|
714
803
|
separatorProps,
|
|
715
804
|
onPointerDown,
|
|
716
805
|
onDoubleClick
|
|
@@ -722,19 +811,28 @@ function DragHandle({
|
|
|
722
811
|
onPointerDown,
|
|
723
812
|
onDoubleClick,
|
|
724
813
|
className: cn4(
|
|
725
|
-
|
|
726
|
-
"
|
|
814
|
+
// 8px invisible hit area; visual feedback only via the before pseudo-element.
|
|
815
|
+
"absolute top-0 h-full w-2 cursor-col-resize",
|
|
816
|
+
edge === "right" ? "right-0" : "left-0",
|
|
817
|
+
// Centered line: invisible at rest, 2px on hover, 4px while dragging.
|
|
818
|
+
"before:absolute before:inset-y-0 before:left-1/2 before:-translate-x-1/2",
|
|
819
|
+
"before:w-0 before:transition-all before:duration-150",
|
|
820
|
+
"hover:before:w-0.5 hover:before:bg-primary/60",
|
|
821
|
+
"active:before:w-1 active:before:bg-primary/80"
|
|
727
822
|
)
|
|
728
823
|
}
|
|
729
824
|
);
|
|
730
825
|
}
|
|
826
|
+
|
|
827
|
+
// src/SidePane.tsx
|
|
828
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
731
829
|
var DEFAULT_WIDTH = 320;
|
|
732
830
|
var DEFAULT_MIN = 240;
|
|
733
831
|
var DEFAULT_MAX = 800;
|
|
734
832
|
function SidePane() {
|
|
735
833
|
const { pane, close } = useSidePaneState();
|
|
736
834
|
if (!pane) return null;
|
|
737
|
-
return /* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx10(SidePaneOpen, { pane, onClose: close });
|
|
738
836
|
}
|
|
739
837
|
function SidePaneOpen({
|
|
740
838
|
pane,
|
|
@@ -750,29 +848,30 @@ function SidePaneOpen({
|
|
|
750
848
|
return /* @__PURE__ */ jsxs7(
|
|
751
849
|
"div",
|
|
752
850
|
{
|
|
753
|
-
className:
|
|
851
|
+
className: cn5(
|
|
754
852
|
"relative flex flex-col border-r bg-background",
|
|
755
853
|
isFullWidth ? "flex-1" : "shrink-0"
|
|
756
854
|
),
|
|
757
855
|
style: isFullWidth ? void 0 : { width: panelWidth },
|
|
758
856
|
children: [
|
|
759
|
-
/* @__PURE__ */
|
|
857
|
+
/* @__PURE__ */ jsx10("div", { className: "flex h-10 shrink-0 items-center justify-end border-b px-2", children: /* @__PURE__ */ jsx10(
|
|
760
858
|
"button",
|
|
761
859
|
{
|
|
762
860
|
onClick: onClose,
|
|
763
|
-
className:
|
|
861
|
+
className: cn5(
|
|
764
862
|
"flex h-6 w-6 items-center justify-center rounded text-muted-foreground",
|
|
765
863
|
"hover:bg-accent hover:text-foreground transition-colors",
|
|
766
864
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
767
865
|
),
|
|
768
866
|
"aria-label": "Close side pane",
|
|
769
|
-
children: /* @__PURE__ */
|
|
867
|
+
children: /* @__PURE__ */ jsx10(X, { className: "h-3.5 w-3.5" })
|
|
770
868
|
}
|
|
771
869
|
) }),
|
|
772
|
-
/* @__PURE__ */
|
|
773
|
-
!isFullWidth && /* @__PURE__ */
|
|
870
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-1 overflow-auto", children: pane.content }),
|
|
871
|
+
!isFullWidth && /* @__PURE__ */ jsx10(
|
|
774
872
|
DragHandle,
|
|
775
873
|
{
|
|
874
|
+
edge: "right",
|
|
776
875
|
separatorProps,
|
|
777
876
|
onPointerDown: handlePointerDown,
|
|
778
877
|
onDoubleClick: handleDoubleClick
|
|
@@ -784,7 +883,7 @@ function SidePaneOpen({
|
|
|
784
883
|
}
|
|
785
884
|
|
|
786
885
|
// src/CommandMenu.tsx
|
|
787
|
-
import { useEffect as useEffect2, useCallback } from "react";
|
|
886
|
+
import { useEffect as useEffect2, useCallback, useMemo as useMemo4 } from "react";
|
|
788
887
|
import { useNavigate } from "react-router-dom";
|
|
789
888
|
import {
|
|
790
889
|
CommandDialog,
|
|
@@ -795,10 +894,11 @@ import {
|
|
|
795
894
|
CommandList,
|
|
796
895
|
CommandSeparator
|
|
797
896
|
} from "@petrarca/sonnet-ui";
|
|
798
|
-
import { Fragment as Fragment2, jsx as
|
|
897
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
799
898
|
function CommandMenu({ open, onOpenChange }) {
|
|
800
899
|
const navigate = useNavigate();
|
|
801
900
|
const { mainModules, bottomModules } = useShellModules();
|
|
901
|
+
const { resolveCapability, capabilityPolicy } = useShellConfig();
|
|
802
902
|
useEffect2(() => {
|
|
803
903
|
const handleKeyDown = (e) => {
|
|
804
904
|
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
@@ -809,6 +909,11 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
809
909
|
document.addEventListener("keydown", handleKeyDown);
|
|
810
910
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
811
911
|
}, [open, onOpenChange]);
|
|
912
|
+
const policy = useMemo4(
|
|
913
|
+
() => resolveCapabilityPolicy(capabilityPolicy),
|
|
914
|
+
[capabilityPolicy]
|
|
915
|
+
);
|
|
916
|
+
const moduleEffect = (service) => evaluateModule(service, "command", resolveCapability, policy);
|
|
812
917
|
const handleSelect = useCallback(
|
|
813
918
|
(path) => {
|
|
814
919
|
navigate(path);
|
|
@@ -818,17 +923,21 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
818
923
|
);
|
|
819
924
|
const renderNavGroup = (service) => {
|
|
820
925
|
if (service.navigation.length === 0) return null;
|
|
926
|
+
const { effect, reason } = moduleEffect(service);
|
|
927
|
+
if (effect === "hidden" || effect === "redirect") return null;
|
|
928
|
+
const disabled = effect === "disabled";
|
|
821
929
|
const Icon = service.icon;
|
|
822
|
-
return /* @__PURE__ */
|
|
930
|
+
return /* @__PURE__ */ jsx11(CommandGroup, { heading: service.label, children: service.navigation.flatMap(
|
|
823
931
|
(group) => group.links.map((link) => /* @__PURE__ */ jsxs8(
|
|
824
932
|
CommandItem,
|
|
825
933
|
{
|
|
826
934
|
value: `${service.label} ${group.heading ?? ""} ${link.label}`,
|
|
827
|
-
|
|
935
|
+
disabled,
|
|
936
|
+
onSelect: disabled ? void 0 : () => handleSelect(link.path),
|
|
828
937
|
children: [
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
831
|
-
group.heading && /* @__PURE__ */
|
|
938
|
+
/* @__PURE__ */ jsx11(Icon, { className: "mr-2 h-4 w-4 text-muted-foreground" }),
|
|
939
|
+
/* @__PURE__ */ jsx11("span", { children: link.label }),
|
|
940
|
+
disabled && reason ? /* @__PURE__ */ jsx11("span", { className: "ml-auto text-xs text-muted-foreground", children: reason }) : group.heading && /* @__PURE__ */ jsx11("span", { className: "ml-auto text-xs text-muted-foreground", children: group.heading })
|
|
832
941
|
]
|
|
833
942
|
},
|
|
834
943
|
link.path
|
|
@@ -837,8 +946,11 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
837
946
|
};
|
|
838
947
|
const renderCommandGroup = (service) => {
|
|
839
948
|
if (!service.commands?.length) return null;
|
|
949
|
+
const { effect, reason } = moduleEffect(service);
|
|
950
|
+
if (effect === "hidden" || effect === "redirect") return null;
|
|
951
|
+
const disabled = effect === "disabled";
|
|
840
952
|
const Icon = service.icon;
|
|
841
|
-
return /* @__PURE__ */
|
|
953
|
+
return /* @__PURE__ */ jsx11(
|
|
842
954
|
CommandGroup,
|
|
843
955
|
{
|
|
844
956
|
heading: service.commands[0].group ?? service.label,
|
|
@@ -848,13 +960,15 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
848
960
|
CommandItem,
|
|
849
961
|
{
|
|
850
962
|
value: `${service.label} ${cmd.label}`,
|
|
851
|
-
|
|
963
|
+
disabled,
|
|
964
|
+
onSelect: disabled ? void 0 : () => {
|
|
852
965
|
cmd.action();
|
|
853
966
|
onOpenChange(false);
|
|
854
967
|
},
|
|
855
968
|
children: [
|
|
856
|
-
/* @__PURE__ */
|
|
857
|
-
/* @__PURE__ */
|
|
969
|
+
/* @__PURE__ */ jsx11(CmdIcon, { className: "mr-2 h-4 w-4 text-muted-foreground" }),
|
|
970
|
+
/* @__PURE__ */ jsx11("span", { children: cmd.label }),
|
|
971
|
+
disabled && reason && /* @__PURE__ */ jsx11("span", { className: "ml-auto text-xs text-muted-foreground", children: reason })
|
|
858
972
|
]
|
|
859
973
|
},
|
|
860
974
|
cmd.id
|
|
@@ -865,45 +979,69 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
865
979
|
);
|
|
866
980
|
};
|
|
867
981
|
const allModules = [...mainModules, ...bottomModules];
|
|
982
|
+
const hasVisibleNav = (modules) => modules.some(
|
|
983
|
+
(m) => m.navigation.length > 0 && !["hidden", "redirect"].includes(moduleEffect(m).effect)
|
|
984
|
+
);
|
|
985
|
+
const hasVisibleCmds = allModules.some(
|
|
986
|
+
(m) => (m.commands?.length ?? 0) > 0 && !["hidden", "redirect"].includes(moduleEffect(m).effect)
|
|
987
|
+
);
|
|
868
988
|
return /* @__PURE__ */ jsxs8(CommandDialog, { open, onOpenChange, children: [
|
|
869
|
-
/* @__PURE__ */
|
|
989
|
+
/* @__PURE__ */ jsx11(CommandInput, { placeholder: "Search pages, services, actions..." }),
|
|
870
990
|
/* @__PURE__ */ jsxs8(CommandList, { children: [
|
|
871
|
-
/* @__PURE__ */
|
|
991
|
+
/* @__PURE__ */ jsx11(CommandEmpty, { children: "No results found." }),
|
|
872
992
|
mainModules.map(renderNavGroup),
|
|
873
|
-
/* @__PURE__ */
|
|
993
|
+
hasVisibleNav(mainModules) && hasVisibleNav(bottomModules) && /* @__PURE__ */ jsx11(CommandSeparator, {}),
|
|
874
994
|
bottomModules.map(renderNavGroup),
|
|
875
|
-
|
|
876
|
-
/* @__PURE__ */
|
|
995
|
+
hasVisibleCmds && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
996
|
+
/* @__PURE__ */ jsx11(CommandSeparator, {}),
|
|
877
997
|
allModules.map(renderCommandGroup)
|
|
878
998
|
] })
|
|
879
999
|
] })
|
|
880
1000
|
] });
|
|
881
1001
|
}
|
|
882
1002
|
|
|
883
|
-
// src/
|
|
884
|
-
import
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
1003
|
+
// src/ModuleEffects.tsx
|
|
1004
|
+
import React3 from "react";
|
|
1005
|
+
import { warnLog as warnLog4 } from "@petrarca/sonnet-core";
|
|
1006
|
+
import { Fragment as Fragment3, jsx as jsx12 } from "react/jsx-runtime";
|
|
1007
|
+
var ModuleEffectBoundary = class extends React3.Component {
|
|
1008
|
+
state = { caught: false };
|
|
1009
|
+
static getDerivedStateFromError() {
|
|
1010
|
+
return { caught: true };
|
|
890
1011
|
}
|
|
891
|
-
|
|
1012
|
+
componentDidCatch(error) {
|
|
1013
|
+
warnLog4(
|
|
1014
|
+
"[ModuleEffects] module '{}' useEffects threw \u2014 effects disabled for this module: {}",
|
|
1015
|
+
this.props.moduleId,
|
|
1016
|
+
error
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
render() {
|
|
1020
|
+
return this.state.caught ? null : this.props.children;
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
function ModuleEffectHost({ module }) {
|
|
1024
|
+
module.useEffects();
|
|
1025
|
+
return null;
|
|
1026
|
+
}
|
|
1027
|
+
function ModuleEffects({ modules }) {
|
|
1028
|
+
return /* @__PURE__ */ jsx12(Fragment3, { children: modules.filter((m) => typeof m.useEffects === "function").map((m) => /* @__PURE__ */ jsx12(ModuleEffectBoundary, { moduleId: m.id, children: /* @__PURE__ */ jsx12(ModuleEffectHost, { module: m }) }, m.id)) });
|
|
892
1029
|
}
|
|
893
1030
|
|
|
894
1031
|
// src/AppShell.tsx
|
|
895
|
-
import { Fragment as
|
|
896
|
-
var
|
|
897
|
-
narrow: "w-[480px]",
|
|
898
|
-
default: "w-[640px]",
|
|
899
|
-
wide: "w-[800px]",
|
|
900
|
-
half: "w-[50vw]",
|
|
901
|
-
full: "w-screen",
|
|
1032
|
+
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1033
|
+
var PANEL_WIDTHS = {
|
|
1034
|
+
narrow: { css: "w-[480px]", px: 480 },
|
|
1035
|
+
default: { css: "w-[640px]", px: 640 },
|
|
1036
|
+
wide: { css: "w-[800px]", px: 800 },
|
|
1037
|
+
half: { css: "w-[50vw]", px: 640 },
|
|
1038
|
+
full: { css: "w-screen", px: 640 },
|
|
902
1039
|
// legacy aliases
|
|
903
|
-
lg: "w-[640px]",
|
|
904
|
-
"1/3": "w-[33vw]",
|
|
905
|
-
"1/2": "w-[50vw]"
|
|
1040
|
+
lg: { css: "w-[640px]", px: 640 },
|
|
1041
|
+
"1/3": { css: "w-[33vw]", px: 640 },
|
|
1042
|
+
"1/2": { css: "w-[50vw]", px: 640 }
|
|
906
1043
|
};
|
|
1044
|
+
var DEFAULT_PANEL = PANEL_WIDTHS.default;
|
|
907
1045
|
function isSidePaneModule(service) {
|
|
908
1046
|
return !!service.sidePane && service.navigation.length === 0;
|
|
909
1047
|
}
|
|
@@ -951,7 +1089,7 @@ function useShellApiInit(deps) {
|
|
|
951
1089
|
}
|
|
952
1090
|
function useActiveService(modules) {
|
|
953
1091
|
const location = useLocation2();
|
|
954
|
-
const serviceByBasePath =
|
|
1092
|
+
const serviceByBasePath = useMemo5(
|
|
955
1093
|
() => new Map(
|
|
956
1094
|
modules.filter((m) => !m.hidden && m.basePath !== "/").map((m) => [m.basePath, m.id])
|
|
957
1095
|
),
|
|
@@ -1006,6 +1144,25 @@ function useSidePaneState2() {
|
|
|
1006
1144
|
handleSetFullWidth
|
|
1007
1145
|
};
|
|
1008
1146
|
}
|
|
1147
|
+
var DEFAULT_RESIZE_MIN = 240;
|
|
1148
|
+
var DEFAULT_RESIZE_MAX = 1200;
|
|
1149
|
+
function resizeOptionsFromPanel(state, widthEntry) {
|
|
1150
|
+
if (!state?.resizable) {
|
|
1151
|
+
return {
|
|
1152
|
+
enabled: false,
|
|
1153
|
+
defaultWidth: widthEntry.px,
|
|
1154
|
+
minWidth: DEFAULT_RESIZE_MIN,
|
|
1155
|
+
maxWidth: DEFAULT_RESIZE_MAX
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
const viewportMax = typeof window !== "undefined" ? Math.round(window.innerWidth * 0.9) : DEFAULT_RESIZE_MAX;
|
|
1159
|
+
return {
|
|
1160
|
+
enabled: true,
|
|
1161
|
+
defaultWidth: widthEntry.px,
|
|
1162
|
+
minWidth: state.minWidth ?? DEFAULT_RESIZE_MIN,
|
|
1163
|
+
maxWidth: state.maxWidth ?? viewportMax
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1009
1166
|
function usePanelState() {
|
|
1010
1167
|
const [panelState, setPanelState] = useState2(null);
|
|
1011
1168
|
const panelOnCloseRef = useRef2(void 0);
|
|
@@ -1017,7 +1174,8 @@ function usePanelState() {
|
|
|
1017
1174
|
panelOnCloseRef.current = panelState?.onClose;
|
|
1018
1175
|
setPanelState(null);
|
|
1019
1176
|
}, [panelState]);
|
|
1020
|
-
const
|
|
1177
|
+
const widthEntry = PANEL_WIDTHS[panelState?.width ?? "default"] ?? DEFAULT_PANEL;
|
|
1178
|
+
const panelWidth = widthEntry.css;
|
|
1021
1179
|
const panelOffsetTop = panelState?.coverage === "full" ? "0px" : "3rem";
|
|
1022
1180
|
return {
|
|
1023
1181
|
panelState,
|
|
@@ -1025,7 +1183,8 @@ function usePanelState() {
|
|
|
1025
1183
|
handleOpen,
|
|
1026
1184
|
handleClose,
|
|
1027
1185
|
panelWidth,
|
|
1028
|
-
panelOffsetTop
|
|
1186
|
+
panelOffsetTop,
|
|
1187
|
+
resize: resizeOptionsFromPanel(panelState, widthEntry)
|
|
1029
1188
|
};
|
|
1030
1189
|
}
|
|
1031
1190
|
function useDialogState() {
|
|
@@ -1041,7 +1200,7 @@ function useDialogState() {
|
|
|
1041
1200
|
return { dialogState, setDialogState, handleConfirm, handleCancel };
|
|
1042
1201
|
}
|
|
1043
1202
|
function useFeatureLookup(modules) {
|
|
1044
|
-
return
|
|
1203
|
+
return useMemo5(() => {
|
|
1045
1204
|
const map = /* @__PURE__ */ new Map();
|
|
1046
1205
|
for (const m of modules) {
|
|
1047
1206
|
for (const group of m.navigation) {
|
|
@@ -1120,7 +1279,7 @@ function AppShell({ registry, sidebar }) {
|
|
|
1120
1279
|
setSubNavCollapsed
|
|
1121
1280
|
]
|
|
1122
1281
|
);
|
|
1123
|
-
const sidePaneContextValue =
|
|
1282
|
+
const sidePaneContextValue = useMemo5(
|
|
1124
1283
|
() => ({
|
|
1125
1284
|
pane: sidePane2.sidePaneState,
|
|
1126
1285
|
open: sidePane2.handleOpen,
|
|
@@ -1143,82 +1302,118 @@ function AppShell({ registry, sidebar }) {
|
|
|
1143
1302
|
onToggleSubNav: () => setSubNavCollapsed((c) => !c),
|
|
1144
1303
|
onServiceSelect: handleServiceSelect
|
|
1145
1304
|
};
|
|
1146
|
-
return /* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1305
|
+
return /* @__PURE__ */ jsx13(ShellModulesContext.Provider, { value: registry, children: /* @__PURE__ */ jsx13(SidePaneContext.Provider, { value: sidePaneContextValue, children: /* @__PURE__ */ jsx13(ShellNavigationContext.Provider, { value: navigationValue, children: /* @__PURE__ */ jsxs9(TooltipProvider, { children: [
|
|
1306
|
+
/* @__PURE__ */ jsx13(ModuleEffects, { modules }),
|
|
1307
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex h-screen w-screen flex-col overflow-hidden", children: [
|
|
1308
|
+
/* @__PURE__ */ jsx13(TopBar, { children: config.topBar }),
|
|
1309
|
+
/* @__PURE__ */ jsx13(
|
|
1310
|
+
CommandMenu,
|
|
1311
|
+
{
|
|
1312
|
+
open: commandMenuOpen,
|
|
1313
|
+
onOpenChange: setCommandMenuOpen
|
|
1314
|
+
}
|
|
1315
|
+
),
|
|
1316
|
+
/* @__PURE__ */ jsx13(
|
|
1317
|
+
ShellBody,
|
|
1318
|
+
{
|
|
1319
|
+
activeService,
|
|
1320
|
+
sidePaneFullWidth: sidePane2.sidePaneState?.fullWidth,
|
|
1321
|
+
sidebar
|
|
1322
|
+
}
|
|
1323
|
+
),
|
|
1324
|
+
config.footer && /* @__PURE__ */ jsx13(ShellFooter, { children: config.footer }),
|
|
1325
|
+
dialog2.dialogState && /* @__PURE__ */ jsx13(
|
|
1326
|
+
ConfirmDialog,
|
|
1327
|
+
{
|
|
1328
|
+
open: true,
|
|
1329
|
+
title: dialog2.dialogState.opts.title,
|
|
1330
|
+
description: dialog2.dialogState.opts.description,
|
|
1331
|
+
confirmLabel: dialog2.dialogState.opts.confirmLabel,
|
|
1332
|
+
cancelLabel: dialog2.dialogState.opts.cancelLabel,
|
|
1333
|
+
variant: dialog2.dialogState.opts.variant,
|
|
1334
|
+
onConfirm: dialog2.handleConfirm,
|
|
1335
|
+
onCancel: dialog2.handleCancel
|
|
1336
|
+
}
|
|
1337
|
+
),
|
|
1338
|
+
fullscreenState && /* @__PURE__ */ jsx13("div", { className: "fixed inset-0 z-50 bg-background overflow-auto", children: fullscreenState.content }),
|
|
1339
|
+
/* @__PURE__ */ jsx13(
|
|
1340
|
+
SlideOverPanel,
|
|
1341
|
+
{
|
|
1342
|
+
panelState: panel2.panelState,
|
|
1343
|
+
panelWidth: panel2.panelWidth,
|
|
1344
|
+
panelOffsetTop: panel2.panelOffsetTop,
|
|
1345
|
+
panelOnCloseRef: panel2.panelOnCloseRef,
|
|
1346
|
+
onClose: panel2.handleClose,
|
|
1347
|
+
resize: panel2.resize
|
|
1348
|
+
}
|
|
1349
|
+
)
|
|
1350
|
+
] })
|
|
1351
|
+
] }) }) }) });
|
|
1189
1352
|
}
|
|
1190
1353
|
function SlideOverPanel({
|
|
1191
1354
|
panelState,
|
|
1192
1355
|
panelWidth,
|
|
1193
1356
|
panelOffsetTop,
|
|
1194
1357
|
panelOnCloseRef,
|
|
1195
|
-
onClose
|
|
1358
|
+
onClose,
|
|
1359
|
+
resize
|
|
1196
1360
|
}) {
|
|
1197
|
-
|
|
1361
|
+
const sheetProps = {
|
|
1362
|
+
side: "right",
|
|
1363
|
+
offsetTop: panelOffsetTop,
|
|
1364
|
+
onCloseAutoFocus: (e) => {
|
|
1365
|
+
if (panelOnCloseRef.current) {
|
|
1366
|
+
e.preventDefault();
|
|
1367
|
+
panelOnCloseRef.current();
|
|
1368
|
+
}
|
|
1369
|
+
},
|
|
1370
|
+
...!panelState?.description && { "aria-describedby": void 0 }
|
|
1371
|
+
};
|
|
1372
|
+
return /* @__PURE__ */ jsx13(
|
|
1198
1373
|
Sheet,
|
|
1199
1374
|
{
|
|
1200
1375
|
open: panelState !== null,
|
|
1201
1376
|
onOpenChange: (open) => {
|
|
1202
1377
|
if (!open) onClose();
|
|
1203
1378
|
},
|
|
1204
|
-
children: /* @__PURE__ */
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1379
|
+
children: resize.enabled ? /* @__PURE__ */ jsx13(ResizableSheetContent, { ...sheetProps, resize, children: panelState && /* @__PURE__ */ jsx13(PanelContent, { state: panelState }) }) : /* @__PURE__ */ jsx13(SheetContent, { ...sheetProps, className: `${panelWidth} max-w-[90vw]`, children: panelState && /* @__PURE__ */ jsx13(PanelContent, { state: panelState }) })
|
|
1380
|
+
}
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
function ResizableSheetContent({
|
|
1384
|
+
resize,
|
|
1385
|
+
children,
|
|
1386
|
+
...sheetProps
|
|
1387
|
+
}) {
|
|
1388
|
+
const {
|
|
1389
|
+
panelWidth: dynWidth,
|
|
1390
|
+
handlePointerDown,
|
|
1391
|
+
handleDoubleClick,
|
|
1392
|
+
separatorProps
|
|
1393
|
+
} = useResizablePanel2({
|
|
1394
|
+
defaultWidth: resize.defaultWidth,
|
|
1395
|
+
minWidth: resize.minWidth,
|
|
1396
|
+
maxWidth: resize.maxWidth,
|
|
1397
|
+
direction: "left-edge"
|
|
1398
|
+
});
|
|
1399
|
+
return /* @__PURE__ */ jsxs9(
|
|
1400
|
+
SheetContent,
|
|
1401
|
+
{
|
|
1402
|
+
...sheetProps,
|
|
1403
|
+
className: "max-w-[90vw]",
|
|
1404
|
+
style: { width: dynWidth },
|
|
1405
|
+
children: [
|
|
1406
|
+
/* @__PURE__ */ jsx13(
|
|
1407
|
+
DragHandle,
|
|
1408
|
+
{
|
|
1409
|
+
edge: "left",
|
|
1410
|
+
separatorProps,
|
|
1411
|
+
onPointerDown: handlePointerDown,
|
|
1412
|
+
onDoubleClick: handleDoubleClick
|
|
1413
|
+
}
|
|
1414
|
+
),
|
|
1415
|
+
children
|
|
1416
|
+
]
|
|
1222
1417
|
}
|
|
1223
1418
|
);
|
|
1224
1419
|
}
|
|
@@ -1228,24 +1423,24 @@ function ShellBody({
|
|
|
1228
1423
|
sidebar
|
|
1229
1424
|
}) {
|
|
1230
1425
|
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
1231
|
-
sidebar ?? /* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
sidePaneFullWidth !== true && /* @__PURE__ */
|
|
1426
|
+
sidebar ?? /* @__PURE__ */ jsx13(ShellRail, {}),
|
|
1427
|
+
/* @__PURE__ */ jsx13(SidePane, {}),
|
|
1428
|
+
sidePaneFullWidth !== true && /* @__PURE__ */ jsx13("div", { className: "flex-1 min-w-0 h-full overflow-hidden", children: /* @__PURE__ */ jsx13(ContentArea, { layout: activeService?.layout }) })
|
|
1234
1429
|
] });
|
|
1235
1430
|
}
|
|
1236
1431
|
function ContentArea({ layout }) {
|
|
1237
1432
|
if (layout === "full") {
|
|
1238
|
-
return /* @__PURE__ */
|
|
1433
|
+
return /* @__PURE__ */ jsx13("div", { className: "h-full w-full overflow-hidden", children: /* @__PURE__ */ jsx13(Outlet, {}) });
|
|
1239
1434
|
}
|
|
1240
|
-
return /* @__PURE__ */
|
|
1435
|
+
return /* @__PURE__ */ jsx13(ScrollArea2, { className: "h-full", children: /* @__PURE__ */ jsx13("main", { className: "p-6", children: /* @__PURE__ */ jsx13(Outlet, {}) }) });
|
|
1241
1436
|
}
|
|
1242
1437
|
function PanelContent({ state }) {
|
|
1243
|
-
return /* @__PURE__ */ jsxs9(
|
|
1438
|
+
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1244
1439
|
state.title ? /* @__PURE__ */ jsxs9(SheetHeader, { children: [
|
|
1245
|
-
/* @__PURE__ */
|
|
1246
|
-
state.description && /* @__PURE__ */
|
|
1247
|
-
] }) : /* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1440
|
+
/* @__PURE__ */ jsx13(SheetTitle, { children: state.title }),
|
|
1441
|
+
state.description && /* @__PURE__ */ jsx13(SheetDescription, { children: state.description })
|
|
1442
|
+
] }) : /* @__PURE__ */ jsx13(SheetTitle, { className: "sr-only", children: "Panel" }),
|
|
1443
|
+
/* @__PURE__ */ jsx13(SheetBody, { children: state.content })
|
|
1249
1444
|
] });
|
|
1250
1445
|
}
|
|
1251
1446
|
|
|
@@ -1253,36 +1448,36 @@ function PanelContent({ state }) {
|
|
|
1253
1448
|
import { Toaster } from "sonner";
|
|
1254
1449
|
|
|
1255
1450
|
// src/ShellConfigProvider.tsx
|
|
1256
|
-
import { jsx as
|
|
1451
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1257
1452
|
function ShellConfigProvider({
|
|
1258
1453
|
config,
|
|
1259
1454
|
children
|
|
1260
1455
|
}) {
|
|
1261
|
-
return /* @__PURE__ */
|
|
1456
|
+
return /* @__PURE__ */ jsx14(ShellConfigContext.Provider, { value: config, children });
|
|
1262
1457
|
}
|
|
1263
1458
|
|
|
1264
1459
|
// src/RootLayout.tsx
|
|
1265
|
-
import { jsx as
|
|
1460
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1266
1461
|
function RootLayout({
|
|
1267
1462
|
config,
|
|
1268
1463
|
registry,
|
|
1269
1464
|
sidebar
|
|
1270
1465
|
}) {
|
|
1271
1466
|
return /* @__PURE__ */ jsxs10(ShellConfigProvider, { config, children: [
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1467
|
+
/* @__PURE__ */ jsx15(Toaster, { position: "top-right", richColors: true, closeButton: true }),
|
|
1468
|
+
/* @__PURE__ */ jsx15(AppShell, { registry, sidebar })
|
|
1274
1469
|
] });
|
|
1275
1470
|
}
|
|
1276
1471
|
|
|
1277
1472
|
// src/PlaceholderPage.tsx
|
|
1278
1473
|
import { useLocation as useLocation3 } from "react-router-dom";
|
|
1279
|
-
import { jsx as
|
|
1474
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1280
1475
|
function PlaceholderPage() {
|
|
1281
1476
|
const { pathname } = useLocation3();
|
|
1282
1477
|
return /* @__PURE__ */ jsxs11("div", { children: [
|
|
1283
|
-
/* @__PURE__ */
|
|
1284
|
-
/* @__PURE__ */
|
|
1285
|
-
/* @__PURE__ */
|
|
1478
|
+
/* @__PURE__ */ jsx16("h1", { className: "mb-1", children: pathToTitle(pathname) }),
|
|
1479
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground mb-6", children: pathname }),
|
|
1480
|
+
/* @__PURE__ */ jsx16("div", { className: "rounded-lg border-2 border-dashed border-border p-12 flex items-center justify-center", children: /* @__PURE__ */ jsx16("span", { className: "text-sm text-muted-foreground", children: "Content area \u2014 not yet implemented" }) })
|
|
1286
1481
|
] });
|
|
1287
1482
|
}
|
|
1288
1483
|
function pathToTitle(path) {
|
|
@@ -1292,9 +1487,9 @@ function pathToTitle(path) {
|
|
|
1292
1487
|
}
|
|
1293
1488
|
|
|
1294
1489
|
// src/Sidebar.tsx
|
|
1295
|
-
import { cn as
|
|
1490
|
+
import { cn as cn6 } from "@petrarca/sonnet-core";
|
|
1296
1491
|
import { ScrollArea as ScrollArea3 } from "@petrarca/sonnet-ui";
|
|
1297
|
-
import { jsx as
|
|
1492
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1298
1493
|
function Sidebar({
|
|
1299
1494
|
children,
|
|
1300
1495
|
header,
|
|
@@ -1305,20 +1500,20 @@ function Sidebar({
|
|
|
1305
1500
|
"aside",
|
|
1306
1501
|
{
|
|
1307
1502
|
style: { width },
|
|
1308
|
-
className:
|
|
1503
|
+
className: cn6(
|
|
1309
1504
|
"shrink-0 border-r bg-muted/30 flex flex-col h-full",
|
|
1310
1505
|
className
|
|
1311
1506
|
),
|
|
1312
1507
|
children: [
|
|
1313
1508
|
header,
|
|
1314
|
-
/* @__PURE__ */
|
|
1509
|
+
/* @__PURE__ */ jsx17(ScrollArea3, { className: "flex-1", children: /* @__PURE__ */ jsx17("nav", { className: "px-1.5 py-2 space-y-3", children }) })
|
|
1315
1510
|
]
|
|
1316
1511
|
}
|
|
1317
1512
|
);
|
|
1318
1513
|
}
|
|
1319
1514
|
|
|
1320
1515
|
// src/ShellSidebar.tsx
|
|
1321
|
-
import { jsx as
|
|
1516
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1322
1517
|
function ShellSidebar({
|
|
1323
1518
|
bottomGroupLabel = "Tools",
|
|
1324
1519
|
...sidebarProps
|
|
@@ -1328,7 +1523,7 @@ function ShellSidebar({
|
|
|
1328
1523
|
(mod) => (mod.topNav ?? []).map((link) => ({ link, icon: mod.icon }))
|
|
1329
1524
|
);
|
|
1330
1525
|
return /* @__PURE__ */ jsxs13(Sidebar, { ...sidebarProps, children: [
|
|
1331
|
-
topNavItems.length > 0 && /* @__PURE__ */
|
|
1526
|
+
topNavItems.length > 0 && /* @__PURE__ */ jsx18(SidebarGroup, { separator: true, children: topNavItems.map(({ link, icon }) => /* @__PURE__ */ jsx18(
|
|
1332
1527
|
SidebarItem,
|
|
1333
1528
|
{
|
|
1334
1529
|
icon,
|
|
@@ -1340,7 +1535,7 @@ function ShellSidebar({
|
|
|
1340
1535
|
)) }),
|
|
1341
1536
|
mainModules.map((mod) => {
|
|
1342
1537
|
if (mod.navigation.length === 0) {
|
|
1343
|
-
return /* @__PURE__ */
|
|
1538
|
+
return /* @__PURE__ */ jsx18(
|
|
1344
1539
|
SidebarItem,
|
|
1345
1540
|
{
|
|
1346
1541
|
icon: mod.icon,
|
|
@@ -1350,15 +1545,15 @@ function ShellSidebar({
|
|
|
1350
1545
|
mod.id
|
|
1351
1546
|
);
|
|
1352
1547
|
}
|
|
1353
|
-
return /* @__PURE__ */
|
|
1548
|
+
return /* @__PURE__ */ jsx18(SidebarGroup, { heading: mod.label, collapsible: true, children: mod.navigation.flatMap((group) => [
|
|
1354
1549
|
// Render NavGroup heading if it has one
|
|
1355
1550
|
...group.heading ? [
|
|
1356
|
-
/* @__PURE__ */
|
|
1551
|
+
/* @__PURE__ */ jsx18(
|
|
1357
1552
|
SidebarGroup,
|
|
1358
1553
|
{
|
|
1359
1554
|
heading: group.heading,
|
|
1360
1555
|
collapsible: group.collapsible,
|
|
1361
|
-
children: group.links.map((link) => /* @__PURE__ */
|
|
1556
|
+
children: group.links.map((link) => /* @__PURE__ */ jsx18(
|
|
1362
1557
|
SidebarItem,
|
|
1363
1558
|
{
|
|
1364
1559
|
icon: mod.icon,
|
|
@@ -1371,7 +1566,7 @@ function ShellSidebar({
|
|
|
1371
1566
|
},
|
|
1372
1567
|
group.id
|
|
1373
1568
|
)
|
|
1374
|
-
] : group.links.map((link) => /* @__PURE__ */
|
|
1569
|
+
] : group.links.map((link) => /* @__PURE__ */ jsx18(
|
|
1375
1570
|
SidebarItem,
|
|
1376
1571
|
{
|
|
1377
1572
|
icon: mod.icon,
|
|
@@ -1383,7 +1578,7 @@ function ShellSidebar({
|
|
|
1383
1578
|
))
|
|
1384
1579
|
]) }, mod.id);
|
|
1385
1580
|
}),
|
|
1386
|
-
bottomModules.length > 0 && /* @__PURE__ */
|
|
1581
|
+
bottomModules.length > 0 && /* @__PURE__ */ jsx18(SidebarGroup, { heading: bottomGroupLabel, collapsible: true, children: bottomModules.map((mod) => /* @__PURE__ */ jsx18(
|
|
1387
1582
|
SidebarItem,
|
|
1388
1583
|
{
|
|
1389
1584
|
icon: mod.icon,
|
|
@@ -1396,13 +1591,13 @@ function ShellSidebar({
|
|
|
1396
1591
|
}
|
|
1397
1592
|
|
|
1398
1593
|
// src/ShellVersion.tsx
|
|
1399
|
-
import { jsx as
|
|
1594
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1400
1595
|
function ShellVersion({
|
|
1401
1596
|
name,
|
|
1402
1597
|
version
|
|
1403
1598
|
}) {
|
|
1404
1599
|
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1405
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsx19("span", { children: name }),
|
|
1406
1601
|
version && /* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground/50", children: [
|
|
1407
1602
|
"v",
|
|
1408
1603
|
version
|
|
@@ -1413,7 +1608,7 @@ function ShellVersion({
|
|
|
1413
1608
|
// src/SearchTrigger.tsx
|
|
1414
1609
|
import { Search } from "lucide-react";
|
|
1415
1610
|
import { Button as Button3 } from "@petrarca/sonnet-ui";
|
|
1416
|
-
import { jsx as
|
|
1611
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1417
1612
|
function SearchTrigger() {
|
|
1418
1613
|
return /* @__PURE__ */ jsxs15(
|
|
1419
1614
|
Button3,
|
|
@@ -1423,10 +1618,10 @@ function SearchTrigger() {
|
|
|
1423
1618
|
className: "h-8 gap-2 text-sm text-muted-foreground w-56 justify-start",
|
|
1424
1619
|
onClick: () => navigation.openCommandMenu(),
|
|
1425
1620
|
children: [
|
|
1426
|
-
/* @__PURE__ */
|
|
1427
|
-
/* @__PURE__ */
|
|
1621
|
+
/* @__PURE__ */ jsx20(Search, { className: "h-4 w-4" }),
|
|
1622
|
+
/* @__PURE__ */ jsx20("span", { children: "Search..." }),
|
|
1428
1623
|
/* @__PURE__ */ jsxs15("kbd", { className: "ml-auto pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground", children: [
|
|
1429
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs", children: "\u2318" }),
|
|
1430
1625
|
"K"
|
|
1431
1626
|
] })
|
|
1432
1627
|
]
|
|
@@ -1446,23 +1641,23 @@ import {
|
|
|
1446
1641
|
DropdownMenuSeparator,
|
|
1447
1642
|
DropdownMenuTrigger
|
|
1448
1643
|
} from "@petrarca/sonnet-ui";
|
|
1449
|
-
import { jsx as
|
|
1644
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1450
1645
|
function UserMenu({ user, onSignOut }) {
|
|
1451
1646
|
return /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1452
|
-
/* @__PURE__ */
|
|
1647
|
+
/* @__PURE__ */ jsx21(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(Button4, { variant: "ghost", size: "compact", className: "rounded-full", children: /* @__PURE__ */ jsx21(Avatar, { className: "h-7 w-7", children: /* @__PURE__ */ jsx21(AvatarFallback, { className: "text-xs", children: user.initials }) }) }) }),
|
|
1453
1648
|
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", className: "w-48", children: [
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1649
|
+
/* @__PURE__ */ jsx21(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
1650
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm font-medium", children: user.name }),
|
|
1651
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: user.email })
|
|
1457
1652
|
] }) }),
|
|
1458
|
-
/* @__PURE__ */
|
|
1653
|
+
/* @__PURE__ */ jsx21(DropdownMenuSeparator, {}),
|
|
1459
1654
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { children: [
|
|
1460
|
-
/* @__PURE__ */
|
|
1655
|
+
/* @__PURE__ */ jsx21(User, { className: "mr-2 h-4 w-4" }),
|
|
1461
1656
|
"Profile"
|
|
1462
1657
|
] }),
|
|
1463
|
-
/* @__PURE__ */
|
|
1658
|
+
/* @__PURE__ */ jsx21(DropdownMenuSeparator, {}),
|
|
1464
1659
|
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onSelect: onSignOut, children: [
|
|
1465
|
-
/* @__PURE__ */
|
|
1660
|
+
/* @__PURE__ */ jsx21(LogOut, { className: "mr-2 h-4 w-4" }),
|
|
1466
1661
|
"Sign out"
|
|
1467
1662
|
] })
|
|
1468
1663
|
] })
|
|
@@ -1493,13 +1688,13 @@ function createModuleRegistry(modules) {
|
|
|
1493
1688
|
}
|
|
1494
1689
|
|
|
1495
1690
|
// src/OverviewCard.tsx
|
|
1496
|
-
import { cn as
|
|
1497
|
-
import { jsx as
|
|
1691
|
+
import { cn as cn7 } from "@petrarca/sonnet-core";
|
|
1692
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1498
1693
|
function FeatureLink({
|
|
1499
1694
|
feature,
|
|
1500
1695
|
children
|
|
1501
1696
|
}) {
|
|
1502
|
-
return /* @__PURE__ */
|
|
1697
|
+
return /* @__PURE__ */ jsx22(
|
|
1503
1698
|
"span",
|
|
1504
1699
|
{
|
|
1505
1700
|
role: "link",
|
|
@@ -1532,17 +1727,17 @@ function OverviewCard({
|
|
|
1532
1727
|
{
|
|
1533
1728
|
onClick: feature ? () => navigation.goToFeature(feature) : void 0,
|
|
1534
1729
|
disabled: !feature,
|
|
1535
|
-
className:
|
|
1730
|
+
className: cn7(
|
|
1536
1731
|
"rounded-lg border bg-card p-5 text-left flex flex-col gap-3",
|
|
1537
1732
|
"disabled:cursor-default",
|
|
1538
1733
|
feature && "hover:bg-accent/50 transition-colors",
|
|
1539
1734
|
className
|
|
1540
1735
|
),
|
|
1541
1736
|
children: [
|
|
1542
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx22("div", { className: "h-9 w-9 rounded-md bg-blue-50 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx22(Icon, { className: "h-5 w-5 text-blue-600" }) }),
|
|
1543
1738
|
/* @__PURE__ */ jsxs17("div", { children: [
|
|
1544
|
-
/* @__PURE__ */
|
|
1545
|
-
/* @__PURE__ */
|
|
1739
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm font-medium mb-1", children: title }),
|
|
1740
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground leading-relaxed", children: description })
|
|
1546
1741
|
] })
|
|
1547
1742
|
]
|
|
1548
1743
|
}
|
|
@@ -1552,6 +1747,7 @@ export {
|
|
|
1552
1747
|
AppShell,
|
|
1553
1748
|
CommandMenu,
|
|
1554
1749
|
ConfirmDialog,
|
|
1750
|
+
DEFAULT_CAPABILITY_POLICY,
|
|
1555
1751
|
FeatureLink,
|
|
1556
1752
|
IconRail,
|
|
1557
1753
|
OverviewCard,
|
|
@@ -1575,6 +1771,7 @@ export {
|
|
|
1575
1771
|
UserMenu,
|
|
1576
1772
|
createModuleRegistry,
|
|
1577
1773
|
dialog,
|
|
1774
|
+
evaluateModule,
|
|
1578
1775
|
events,
|
|
1579
1776
|
fullscreen,
|
|
1580
1777
|
initDialog,
|
|
@@ -1586,6 +1783,7 @@ export {
|
|
|
1586
1783
|
navigation,
|
|
1587
1784
|
notification,
|
|
1588
1785
|
panel,
|
|
1786
|
+
resolveCapabilityPolicy,
|
|
1589
1787
|
sidePane,
|
|
1590
1788
|
useExtensionPoint,
|
|
1591
1789
|
useMainModules,
|