@agent-native/core 0.178.1 → 0.178.2-nightly-20260910195009
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/corpus/templates/analytics/app/components/layout/Sidebar.tsx +108 -121
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +87 -220
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +83 -221
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +324 -460
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +57 -247
- package/corpus/templates/clips/app/components/library/library-layout.tsx +15 -48
- package/corpus/templates/clips/changelog/2026-09-10-open-mcp-connections-in-new-tabs.md +1 -0
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +84 -94
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +1 -1
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +108 -296
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +55 -212
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +72 -260
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +143 -362
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +64 -159
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +152 -165
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +82 -207
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +61 -234
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +73 -225
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/EnvironmentBadge.d.ts +7 -4
- package/dist/client/EnvironmentBadge.js +26 -18
- package/dist/client/FeedbackButton.js +23 -8
- package/dist/client/app-providers.js +1 -1
- package/dist/client/auth/AuthPage.js +0 -38
- package/dist/client/components/icons/AgentNativeIcon.js +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -0
- package/dist/client/ui/AppSidebar.d.ts +15 -0
- package/dist/client/ui/AppSidebar.js +34 -0
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +19 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +15 -15
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/beta-opt-out-html.js +2 -2
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +57 -247
- package/dist/vite/client.js +4 -1
- package/docs/content/template-clips-anonymous-intake.mdx +7 -5
- package/docs/content/template-clips-developers.mdx +1 -1
- package/package.json +3 -3
- package/src/templates/chat/app/components/layout/Sidebar.tsx +57 -247
|
@@ -3,8 +3,12 @@ import { useT } from "@agent-native/core/client/i18n";
|
|
|
3
3
|
import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
|
|
4
4
|
import { openCommandMenu } from "@agent-native/core/client/navigation";
|
|
5
5
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
AppSidebar,
|
|
8
|
+
AppSidebarNavItem,
|
|
9
|
+
FeedbackButton,
|
|
10
|
+
type AppSidebarItemDefinition,
|
|
11
|
+
} from "@agent-native/core/client/ui";
|
|
8
12
|
import { getWeekdayOrder, getWeekStartsOn } from "@shared/calendar-week";
|
|
9
13
|
import {
|
|
10
14
|
IconCalendar,
|
|
@@ -21,8 +25,6 @@ import {
|
|
|
21
25
|
IconCheck,
|
|
22
26
|
IconEye,
|
|
23
27
|
IconEyeOff,
|
|
24
|
-
IconLayoutSidebarLeftCollapse,
|
|
25
|
-
IconLayoutSidebarLeftExpand,
|
|
26
28
|
IconSearch,
|
|
27
29
|
IconAlertTriangle,
|
|
28
30
|
} from "@tabler/icons-react";
|
|
@@ -484,7 +486,7 @@ function GoogleCalendarsSections({
|
|
|
484
486
|
return (
|
|
485
487
|
<div
|
|
486
488
|
key={preferenceKey}
|
|
487
|
-
className="group flex min-h-7 items-center gap-2 px-
|
|
489
|
+
className="group flex min-h-7 items-center gap-2 px-2 text-xs"
|
|
488
490
|
>
|
|
489
491
|
<Popover>
|
|
490
492
|
<PopoverTrigger asChild>
|
|
@@ -720,33 +722,6 @@ export function Sidebar({
|
|
|
720
722
|
onClose();
|
|
721
723
|
}
|
|
722
724
|
|
|
723
|
-
const collapseButton = onCollapsedChange ? (
|
|
724
|
-
<Tooltip>
|
|
725
|
-
<TooltipTrigger asChild>
|
|
726
|
-
<Button
|
|
727
|
-
type="button"
|
|
728
|
-
variant="ghost"
|
|
729
|
-
size="icon"
|
|
730
|
-
className="h-8 w-8 shrink-0 text-muted-foreground"
|
|
731
|
-
onClick={() => onCollapsedChange(!collapsed)}
|
|
732
|
-
aria-label={
|
|
733
|
-
collapsed
|
|
734
|
-
? t("sidebar.expandSidebar")
|
|
735
|
-
: t("sidebar.collapseSidebar")
|
|
736
|
-
}
|
|
737
|
-
>
|
|
738
|
-
{collapsed ? (
|
|
739
|
-
<IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
|
|
740
|
-
) : (
|
|
741
|
-
<IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
|
|
742
|
-
)}
|
|
743
|
-
</Button>
|
|
744
|
-
</TooltipTrigger>
|
|
745
|
-
<TooltipContent side="top">
|
|
746
|
-
{collapsed ? t("sidebar.expandSidebar") : t("sidebar.collapseSidebar")}
|
|
747
|
-
</TooltipContent>
|
|
748
|
-
</Tooltip>
|
|
749
|
-
) : null;
|
|
750
725
|
const searchButton = (
|
|
751
726
|
<Tooltip>
|
|
752
727
|
<TooltipTrigger asChild>
|
|
@@ -764,14 +739,22 @@ export function Sidebar({
|
|
|
764
739
|
<TooltipContent side="top">{t("root.commandSearch")}</TooltipContent>
|
|
765
740
|
</Tooltip>
|
|
766
741
|
);
|
|
742
|
+
const secondaryItems: AppSidebarItemDefinition[] = bottomNavItems.map(
|
|
743
|
+
(item) => ({
|
|
744
|
+
to: item.path,
|
|
745
|
+
label: t(item.labelKey),
|
|
746
|
+
icon: item.icon,
|
|
747
|
+
active: location.pathname.startsWith(item.path),
|
|
748
|
+
onClick: onClose,
|
|
749
|
+
}),
|
|
750
|
+
);
|
|
751
|
+
|
|
767
752
|
const feedbackButton = (
|
|
768
|
-
<FeedbackButton
|
|
769
|
-
variant={collapsed ? "icon" : "sidebar"}
|
|
770
|
-
side="right"
|
|
771
|
-
className={collapsed ? "h-8 w-8" : "min-w-0"}
|
|
772
|
-
/>
|
|
753
|
+
<FeedbackButton variant={collapsed ? "icon" : "sidebar"} side="right" />
|
|
773
754
|
);
|
|
774
755
|
|
|
756
|
+
const orgSwitcher = <OrgSwitcher compact={collapsed} />;
|
|
757
|
+
|
|
775
758
|
return (
|
|
776
759
|
<>
|
|
777
760
|
{/* Mobile overlay */}
|
|
@@ -782,467 +765,348 @@ export function Sidebar({
|
|
|
782
765
|
/>
|
|
783
766
|
)}
|
|
784
767
|
|
|
785
|
-
<
|
|
786
|
-
|
|
787
|
-
|
|
768
|
+
<AppSidebar
|
|
769
|
+
collapsed={collapsed}
|
|
770
|
+
collapsible={Boolean(onCollapsedChange)}
|
|
771
|
+
onCollapsedChange={onCollapsedChange}
|
|
772
|
+
brandName={t("navigation.brand")}
|
|
773
|
+
brandHref="/home"
|
|
774
|
+
secondaryItems={secondaryItems}
|
|
775
|
+
feedback={feedbackButton}
|
|
776
|
+
orgSwitcher={orgSwitcher}
|
|
777
|
+
footerExtras={
|
|
778
|
+
<>
|
|
779
|
+
{searchButton}
|
|
780
|
+
<DevDatabaseLink />
|
|
781
|
+
</>
|
|
782
|
+
}
|
|
788
783
|
className={cn(
|
|
789
|
-
"
|
|
790
|
-
|
|
784
|
+
"calendar-app-sidebar",
|
|
785
|
+
// Match calendar's lg mobile breakpoint (shared sidebar defaults to md).
|
|
786
|
+
"max-lg:!fixed max-lg:inset-y-0 max-lg:start-0 max-lg:z-50 lg:!static",
|
|
787
|
+
open
|
|
788
|
+
? "translate-x-0"
|
|
789
|
+
: "-translate-x-full rtl:translate-x-full lg:translate-x-0",
|
|
791
790
|
)}
|
|
792
791
|
>
|
|
793
|
-
{
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
}}
|
|
817
|
-
className={cn(
|
|
818
|
-
"flex items-center gap-2 rounded text-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
819
|
-
collapsed ? "size-8 justify-center" : "flex-1",
|
|
820
|
-
)}
|
|
821
|
-
aria-label={
|
|
822
|
-
onCollapsedChange
|
|
823
|
-
? collapsed
|
|
824
|
-
? t("sidebar.expandSidebar")
|
|
825
|
-
: t("sidebar.collapseSidebar")
|
|
826
|
-
: collapsed
|
|
827
|
-
? t("navigation.brand")
|
|
828
|
-
: undefined
|
|
829
|
-
}
|
|
830
|
-
data-sidebar-brand-toggle
|
|
831
|
-
>
|
|
832
|
-
<AgentNativeIcon
|
|
833
|
-
aria-hidden="true"
|
|
834
|
-
className="h-3.5 w-6 shrink-0 text-foreground"
|
|
792
|
+
{collapsed ? (
|
|
793
|
+
navItems.map((item) => {
|
|
794
|
+
const isActive =
|
|
795
|
+
item.path === "/"
|
|
796
|
+
? location.pathname === "/"
|
|
797
|
+
: location.pathname.startsWith(item.path);
|
|
798
|
+
return (
|
|
799
|
+
<AppSidebarNavItem
|
|
800
|
+
key={item.path}
|
|
801
|
+
to={item.path}
|
|
802
|
+
label={t(item.labelKey)}
|
|
803
|
+
icon={item.icon}
|
|
804
|
+
active={isActive}
|
|
805
|
+
onClick={onClose}
|
|
806
|
+
/>
|
|
807
|
+
);
|
|
808
|
+
})
|
|
809
|
+
) : (
|
|
810
|
+
<>
|
|
811
|
+
{/* Mini calendar */}
|
|
812
|
+
<MiniCalendar
|
|
813
|
+
selectedDate={selectedDate}
|
|
814
|
+
onDateSelect={handleMiniCalendarDateSelect}
|
|
835
815
|
/>
|
|
836
|
-
{!collapsed && (
|
|
837
|
-
<span className="text-base font-semibold tracking-tight">
|
|
838
|
-
{t("navigation.brand")}
|
|
839
|
-
</span>
|
|
840
|
-
)}
|
|
841
|
-
</Link>
|
|
842
|
-
</div>
|
|
843
816
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
<nav className="flex flex-col items-center gap-1 px-1 py-2">
|
|
817
|
+
{/* Nav */}
|
|
818
|
+
<div className="space-y-0.5">
|
|
847
819
|
{navItems.map((item) => {
|
|
848
820
|
const isActive =
|
|
849
821
|
item.path === "/"
|
|
850
822
|
? location.pathname === "/"
|
|
851
823
|
: location.pathname.startsWith(item.path);
|
|
824
|
+
|
|
852
825
|
return (
|
|
853
|
-
<
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
isActive && "bg-primary/10 text-primary",
|
|
862
|
-
)}
|
|
863
|
-
>
|
|
864
|
-
<item.icon className="h-4 w-4" />
|
|
865
|
-
</Link>
|
|
866
|
-
</TooltipTrigger>
|
|
867
|
-
<TooltipContent side="right">
|
|
868
|
-
{t(item.labelKey)}
|
|
869
|
-
</TooltipContent>
|
|
870
|
-
</Tooltip>
|
|
826
|
+
<AppSidebarNavItem
|
|
827
|
+
key={item.path}
|
|
828
|
+
to={item.path}
|
|
829
|
+
label={t(item.labelKey)}
|
|
830
|
+
icon={item.icon}
|
|
831
|
+
active={isActive}
|
|
832
|
+
onClick={onClose}
|
|
833
|
+
/>
|
|
871
834
|
);
|
|
872
835
|
})}
|
|
873
|
-
</
|
|
874
|
-
) : (
|
|
875
|
-
<>
|
|
876
|
-
{/* Mini calendar */}
|
|
877
|
-
<MiniCalendar
|
|
878
|
-
selectedDate={selectedDate}
|
|
879
|
-
onDateSelect={handleMiniCalendarDateSelect}
|
|
880
|
-
/>
|
|
881
|
-
|
|
882
|
-
{/* Nav */}
|
|
883
|
-
<nav className="space-y-0.5 p-2.5">
|
|
884
|
-
{navItems.map((item) => {
|
|
885
|
-
const isActive =
|
|
886
|
-
item.path === "/"
|
|
887
|
-
? location.pathname === "/"
|
|
888
|
-
: location.pathname.startsWith(item.path);
|
|
836
|
+
</div>
|
|
889
837
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
className={cn(
|
|
896
|
-
"flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
|
|
897
|
-
isActive
|
|
898
|
-
? "bg-primary/10 text-primary"
|
|
899
|
-
: "text-muted-foreground hover:bg-accent/60 hover:text-foreground",
|
|
900
|
-
)}
|
|
901
|
-
>
|
|
902
|
-
<item.icon className="h-4 w-4" />
|
|
903
|
-
{t(item.labelKey)}
|
|
904
|
-
</Link>
|
|
905
|
-
);
|
|
906
|
-
})}
|
|
907
|
-
</nav>
|
|
838
|
+
{/* Google status / connect CTA */}
|
|
839
|
+
{!googleStatus.isLoading &&
|
|
840
|
+
!isConnected &&
|
|
841
|
+
(googleStatus.data?.configured === true ||
|
|
842
|
+
canOfferGoogleOAuthSetup) && <GoogleConnectSidebarButton />}
|
|
908
843
|
|
|
909
|
-
|
|
910
|
-
{
|
|
911
|
-
|
|
912
|
-
(googleStatus.data?.configured === true ||
|
|
913
|
-
canOfferGoogleOAuthSetup) && <GoogleConnectSidebarButton />}
|
|
844
|
+
{isConnected && (googleStatus.data?.accounts?.length ?? 0) > 0 && (
|
|
845
|
+
<GoogleCalendarsSections onClose={onClose} />
|
|
846
|
+
)}
|
|
914
847
|
|
|
848
|
+
{/* Other Calendars — people overlays + external ICS feeds combined */}
|
|
849
|
+
<div className="px-1.5 py-1.5">
|
|
850
|
+
<div className="flex min-h-8 items-center justify-between px-3">
|
|
851
|
+
<div className="flex items-center gap-1">
|
|
852
|
+
<span className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground">
|
|
853
|
+
{t("sidebar.otherCalendars")}
|
|
854
|
+
</span>
|
|
855
|
+
<Tooltip>
|
|
856
|
+
<TooltipTrigger asChild>
|
|
857
|
+
<span className="flex items-center text-muted-foreground/40 hover:text-muted-foreground cursor-default">
|
|
858
|
+
<IconInfoCircle className="h-3 w-3" />
|
|
859
|
+
</span>
|
|
860
|
+
</TooltipTrigger>
|
|
861
|
+
<TooltipContent
|
|
862
|
+
side="right"
|
|
863
|
+
className="pointer-events-none"
|
|
864
|
+
>
|
|
865
|
+
<p>{t("sidebar.otherCalendarsDescription")}</p>
|
|
866
|
+
</TooltipContent>
|
|
867
|
+
</Tooltip>
|
|
868
|
+
</div>
|
|
869
|
+
<button
|
|
870
|
+
type="button"
|
|
871
|
+
aria-label={t("eventForm.addCalendar")}
|
|
872
|
+
onClick={() => {
|
|
873
|
+
setAddCalendarDefaultTab("people");
|
|
874
|
+
setAddCalendarOpen(true);
|
|
875
|
+
}}
|
|
876
|
+
className="flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground"
|
|
877
|
+
>
|
|
878
|
+
<IconPlus className="h-3.5 w-3.5" />
|
|
879
|
+
</button>
|
|
880
|
+
</div>
|
|
915
881
|
{isConnected &&
|
|
916
882
|
(googleStatus.data?.accounts?.length ?? 0) > 0 && (
|
|
917
|
-
<GoogleCalendarsSections onClose={onClose} />
|
|
883
|
+
<GoogleCalendarsSections onClose={onClose} section="other" />
|
|
918
884
|
)}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
>
|
|
950
|
-
<IconPlus className="h-3.5 w-3.5" />
|
|
951
|
-
</button>
|
|
952
|
-
</div>
|
|
953
|
-
{isConnected &&
|
|
954
|
-
(googleStatus.data?.accounts?.length ?? 0) > 0 && (
|
|
955
|
-
<GoogleCalendarsSections
|
|
956
|
-
onClose={onClose}
|
|
957
|
-
section="other"
|
|
958
|
-
/>
|
|
959
|
-
)}
|
|
960
|
-
{(overlayPeople.length > 0 || externalCalendars.length > 0) && (
|
|
961
|
-
<div className="mt-1 space-y-1">
|
|
962
|
-
{overlayPeople.length > 0 && (
|
|
963
|
-
<Collapsible
|
|
964
|
-
open={peopleGroupOpen}
|
|
965
|
-
onOpenChange={setPeopleGroupOpen}
|
|
966
|
-
>
|
|
967
|
-
<CollapsibleTrigger asChild>
|
|
968
|
-
<button
|
|
969
|
-
type="button"
|
|
970
|
-
className="flex h-7 w-full items-center gap-1 rounded px-3 text-xs text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
885
|
+
{(overlayPeople.length > 0 || externalCalendars.length > 0) && (
|
|
886
|
+
<div className="mt-1 space-y-1">
|
|
887
|
+
{overlayPeople.length > 0 && (
|
|
888
|
+
<Collapsible
|
|
889
|
+
open={peopleGroupOpen}
|
|
890
|
+
onOpenChange={setPeopleGroupOpen}
|
|
891
|
+
>
|
|
892
|
+
<CollapsibleTrigger asChild>
|
|
893
|
+
<button
|
|
894
|
+
type="button"
|
|
895
|
+
className="flex h-7 w-full items-center gap-1 rounded px-3 text-xs text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
896
|
+
>
|
|
897
|
+
{peopleGroupOpen ? (
|
|
898
|
+
<IconChevronDown className="h-3 w-3" />
|
|
899
|
+
) : (
|
|
900
|
+
<IconChevronRight className="h-3 w-3 rtl:-scale-x-100" />
|
|
901
|
+
)}
|
|
902
|
+
<span className="min-w-0 flex-1 text-start">
|
|
903
|
+
People
|
|
904
|
+
</span>
|
|
905
|
+
<span className="text-[10px]">
|
|
906
|
+
{overlayPeople.length}
|
|
907
|
+
</span>
|
|
908
|
+
</button>
|
|
909
|
+
</CollapsibleTrigger>
|
|
910
|
+
<CollapsibleContent className="space-y-0.5">
|
|
911
|
+
{overlayPeople.map((person) => (
|
|
912
|
+
<div
|
|
913
|
+
key={person.email}
|
|
914
|
+
className="group flex min-h-7 items-center gap-2 px-2 text-xs"
|
|
971
915
|
>
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
<span className="text-[10px]">
|
|
981
|
-
{overlayPeople.length}
|
|
982
|
-
</span>
|
|
983
|
-
</button>
|
|
984
|
-
</CollapsibleTrigger>
|
|
985
|
-
<CollapsibleContent className="space-y-0.5">
|
|
986
|
-
{overlayPeople.map((person) => (
|
|
987
|
-
<div
|
|
988
|
-
key={person.email}
|
|
989
|
-
className="group flex min-h-7 items-center gap-2 px-3 text-xs"
|
|
916
|
+
<ColorPickerPopover
|
|
917
|
+
color={person.color}
|
|
918
|
+
onColorChange={(color) =>
|
|
919
|
+
updatePersonColor.mutate({
|
|
920
|
+
email: person.email,
|
|
921
|
+
color,
|
|
922
|
+
})
|
|
923
|
+
}
|
|
990
924
|
>
|
|
991
|
-
<
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
updatePersonColor.mutate({
|
|
995
|
-
email: person.email,
|
|
996
|
-
color,
|
|
997
|
-
})
|
|
998
|
-
}
|
|
925
|
+
<button
|
|
926
|
+
type="button"
|
|
927
|
+
className="shrink-0 cursor-pointer rounded-full p-0.5 hover:ring-2 hover:ring-border"
|
|
999
928
|
>
|
|
1000
|
-
<
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
929
|
+
<span
|
|
930
|
+
className={cn(
|
|
931
|
+
"block h-2.5 w-2.5 rounded-full",
|
|
932
|
+
isHiddenCalendar("people", person.email) &&
|
|
933
|
+
"opacity-40",
|
|
934
|
+
)}
|
|
935
|
+
style={{ backgroundColor: person.color }}
|
|
936
|
+
/>
|
|
937
|
+
</button>
|
|
938
|
+
</ColorPickerPopover>
|
|
939
|
+
<span
|
|
940
|
+
className={cn(
|
|
941
|
+
"min-w-0 flex-1 truncate",
|
|
942
|
+
isHiddenCalendar("people", person.email)
|
|
943
|
+
? "text-muted-foreground/40"
|
|
944
|
+
: "text-muted-foreground",
|
|
945
|
+
)}
|
|
946
|
+
>
|
|
947
|
+
{person.name || person.email}
|
|
948
|
+
</span>
|
|
949
|
+
{overlayStatusByEmail?.get(
|
|
950
|
+
person.email.toLowerCase(),
|
|
951
|
+
)?.status === "error" && (
|
|
952
|
+
<Tooltip>
|
|
953
|
+
<TooltipTrigger asChild>
|
|
1004
954
|
<span
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
) && "opacity-40",
|
|
955
|
+
tabIndex={0}
|
|
956
|
+
className="inline-flex shrink-0 rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
957
|
+
aria-label={t(
|
|
958
|
+
"sidebar.overlayCalendarUnavailable",
|
|
959
|
+
{ email: person.name || person.email },
|
|
1011
960
|
)}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
961
|
+
>
|
|
962
|
+
<IconAlertTriangle
|
|
963
|
+
className="h-3 w-3 text-muted-foreground/60"
|
|
964
|
+
aria-hidden="true"
|
|
965
|
+
/>
|
|
966
|
+
</span>
|
|
967
|
+
</TooltipTrigger>
|
|
968
|
+
<TooltipContent side="right">
|
|
969
|
+
{t("sidebar.overlayCalendarUnavailable", {
|
|
970
|
+
email: person.name || person.email,
|
|
971
|
+
})}
|
|
972
|
+
</TooltipContent>
|
|
973
|
+
</Tooltip>
|
|
974
|
+
)}
|
|
975
|
+
<div className="flex items-center">
|
|
976
|
+
<button
|
|
977
|
+
type="button"
|
|
978
|
+
onClick={() =>
|
|
979
|
+
toggleHiddenCalendar("people", person.email)
|
|
980
|
+
}
|
|
981
|
+
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground group-hover:text-muted-foreground/80"
|
|
982
|
+
aria-label={
|
|
1019
983
|
isHiddenCalendar("people", person.email)
|
|
1020
|
-
? "
|
|
1021
|
-
: "
|
|
984
|
+
? t("sidebar.showCalendar")
|
|
985
|
+
: t("sidebar.hideCalendar")
|
|
986
|
+
}
|
|
987
|
+
>
|
|
988
|
+
{isHiddenCalendar("people", person.email) ? (
|
|
989
|
+
<IconEyeOff className="h-3 w-3" />
|
|
990
|
+
) : (
|
|
991
|
+
<IconEye className="h-3 w-3" />
|
|
1022
992
|
)}
|
|
993
|
+
</button>
|
|
994
|
+
<button
|
|
995
|
+
type="button"
|
|
996
|
+
onClick={() =>
|
|
997
|
+
removePerson.mutate(person.email)
|
|
998
|
+
}
|
|
999
|
+
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/60 opacity-0 hover:text-foreground group-hover:opacity-100"
|
|
1023
1000
|
>
|
|
1024
|
-
|
|
1025
|
-
</
|
|
1026
|
-
{overlayStatusByEmail?.get(
|
|
1027
|
-
person.email.toLowerCase(),
|
|
1028
|
-
)?.status === "error" && (
|
|
1029
|
-
<Tooltip>
|
|
1030
|
-
<TooltipTrigger asChild>
|
|
1031
|
-
<span
|
|
1032
|
-
tabIndex={0}
|
|
1033
|
-
className="inline-flex shrink-0 rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
1034
|
-
aria-label={t(
|
|
1035
|
-
"sidebar.overlayCalendarUnavailable",
|
|
1036
|
-
{ email: person.name || person.email },
|
|
1037
|
-
)}
|
|
1038
|
-
>
|
|
1039
|
-
<IconAlertTriangle
|
|
1040
|
-
className="h-3 w-3 text-muted-foreground/60"
|
|
1041
|
-
aria-hidden="true"
|
|
1042
|
-
/>
|
|
1043
|
-
</span>
|
|
1044
|
-
</TooltipTrigger>
|
|
1045
|
-
<TooltipContent side="right">
|
|
1046
|
-
{t("sidebar.overlayCalendarUnavailable", {
|
|
1047
|
-
email: person.name || person.email,
|
|
1048
|
-
})}
|
|
1049
|
-
</TooltipContent>
|
|
1050
|
-
</Tooltip>
|
|
1051
|
-
)}
|
|
1052
|
-
<div className="flex items-center">
|
|
1053
|
-
<button
|
|
1054
|
-
type="button"
|
|
1055
|
-
onClick={() =>
|
|
1056
|
-
toggleHiddenCalendar("people", person.email)
|
|
1057
|
-
}
|
|
1058
|
-
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground group-hover:text-muted-foreground/80"
|
|
1059
|
-
aria-label={
|
|
1060
|
-
isHiddenCalendar("people", person.email)
|
|
1061
|
-
? t("sidebar.showCalendar")
|
|
1062
|
-
: t("sidebar.hideCalendar")
|
|
1063
|
-
}
|
|
1064
|
-
>
|
|
1065
|
-
{isHiddenCalendar("people", person.email) ? (
|
|
1066
|
-
<IconEyeOff className="h-3 w-3" />
|
|
1067
|
-
) : (
|
|
1068
|
-
<IconEye className="h-3 w-3" />
|
|
1069
|
-
)}
|
|
1070
|
-
</button>
|
|
1071
|
-
<button
|
|
1072
|
-
type="button"
|
|
1073
|
-
onClick={() =>
|
|
1074
|
-
removePerson.mutate(person.email)
|
|
1075
|
-
}
|
|
1076
|
-
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/60 opacity-0 hover:text-foreground group-hover:opacity-100"
|
|
1077
|
-
>
|
|
1078
|
-
<IconX className="h-3 w-3" />
|
|
1079
|
-
</button>
|
|
1080
|
-
</div>
|
|
1001
|
+
<IconX className="h-3 w-3" />
|
|
1002
|
+
</button>
|
|
1081
1003
|
</div>
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
</
|
|
1085
|
-
|
|
1004
|
+
</div>
|
|
1005
|
+
))}
|
|
1006
|
+
</CollapsibleContent>
|
|
1007
|
+
</Collapsible>
|
|
1008
|
+
)}
|
|
1086
1009
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1010
|
+
{externalCalendars.length > 0 && (
|
|
1011
|
+
<Collapsible
|
|
1012
|
+
open={feedsGroupOpen}
|
|
1013
|
+
onOpenChange={setFeedsGroupOpen}
|
|
1014
|
+
>
|
|
1015
|
+
<CollapsibleTrigger asChild>
|
|
1016
|
+
<button
|
|
1017
|
+
type="button"
|
|
1018
|
+
className="flex h-7 w-full items-center gap-1 rounded px-3 text-xs text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
1019
|
+
>
|
|
1020
|
+
{feedsGroupOpen ? (
|
|
1021
|
+
<IconChevronDown className="h-3 w-3" />
|
|
1022
|
+
) : (
|
|
1023
|
+
<IconChevronRight className="h-3 w-3 rtl:-scale-x-100" />
|
|
1024
|
+
)}
|
|
1025
|
+
<span className="min-w-0 flex-1 text-start">
|
|
1026
|
+
Feeds
|
|
1027
|
+
</span>
|
|
1028
|
+
<span className="text-[10px]">
|
|
1029
|
+
{externalCalendars.length}
|
|
1030
|
+
</span>
|
|
1031
|
+
</button>
|
|
1032
|
+
</CollapsibleTrigger>
|
|
1033
|
+
<CollapsibleContent className="space-y-0.5">
|
|
1034
|
+
{externalCalendars.map((cal) => (
|
|
1035
|
+
<div
|
|
1036
|
+
key={cal.id}
|
|
1037
|
+
className="group flex min-h-7 items-center gap-2 px-2 text-xs"
|
|
1096
1038
|
>
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
<span className="text-[10px]">
|
|
1106
|
-
{externalCalendars.length}
|
|
1107
|
-
</span>
|
|
1108
|
-
</button>
|
|
1109
|
-
</CollapsibleTrigger>
|
|
1110
|
-
<CollapsibleContent className="space-y-0.5">
|
|
1111
|
-
{externalCalendars.map((cal) => (
|
|
1112
|
-
<div
|
|
1113
|
-
key={cal.id}
|
|
1114
|
-
className="group flex min-h-7 items-center gap-2 px-3 text-xs"
|
|
1039
|
+
<ColorPickerPopover
|
|
1040
|
+
color={cal.color}
|
|
1041
|
+
onColorChange={(color) =>
|
|
1042
|
+
updateExternalColor.mutate({
|
|
1043
|
+
id: cal.id,
|
|
1044
|
+
color,
|
|
1045
|
+
})
|
|
1046
|
+
}
|
|
1115
1047
|
>
|
|
1116
|
-
<
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
updateExternalColor.mutate({
|
|
1120
|
-
id: cal.id,
|
|
1121
|
-
color,
|
|
1122
|
-
})
|
|
1123
|
-
}
|
|
1048
|
+
<button
|
|
1049
|
+
type="button"
|
|
1050
|
+
className="shrink-0 cursor-pointer rounded-full p-0.5 hover:ring-2 hover:ring-border"
|
|
1124
1051
|
>
|
|
1125
|
-
<
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1052
|
+
<span
|
|
1053
|
+
className={cn(
|
|
1054
|
+
"block h-2.5 w-2.5 rounded-full",
|
|
1055
|
+
isHiddenCalendar("external", cal.id) &&
|
|
1056
|
+
"opacity-40",
|
|
1057
|
+
)}
|
|
1058
|
+
style={{ backgroundColor: cal.color }}
|
|
1059
|
+
/>
|
|
1060
|
+
</button>
|
|
1061
|
+
</ColorPickerPopover>
|
|
1062
|
+
<span
|
|
1063
|
+
className={cn(
|
|
1064
|
+
"min-w-0 flex-1 truncate",
|
|
1065
|
+
isHiddenCalendar("external", cal.id)
|
|
1066
|
+
? "text-muted-foreground/40"
|
|
1067
|
+
: "text-muted-foreground",
|
|
1068
|
+
)}
|
|
1069
|
+
>
|
|
1070
|
+
{cal.name}
|
|
1071
|
+
</span>
|
|
1072
|
+
<div className="flex items-center">
|
|
1073
|
+
<button
|
|
1074
|
+
type="button"
|
|
1075
|
+
onClick={() =>
|
|
1076
|
+
toggleHiddenCalendar("external", cal.id)
|
|
1077
|
+
}
|
|
1078
|
+
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground group-hover:text-muted-foreground/80"
|
|
1079
|
+
aria-label={
|
|
1142
1080
|
isHiddenCalendar("external", cal.id)
|
|
1143
|
-
? "
|
|
1144
|
-
: "
|
|
1081
|
+
? t("sidebar.showCalendar")
|
|
1082
|
+
: t("sidebar.hideCalendar")
|
|
1083
|
+
}
|
|
1084
|
+
>
|
|
1085
|
+
{isHiddenCalendar("external", cal.id) ? (
|
|
1086
|
+
<IconEyeOff className="h-3 w-3" />
|
|
1087
|
+
) : (
|
|
1088
|
+
<IconEye className="h-3 w-3" />
|
|
1145
1089
|
)}
|
|
1090
|
+
</button>
|
|
1091
|
+
<button
|
|
1092
|
+
type="button"
|
|
1093
|
+
onClick={() => removeExternal.mutate(cal.id)}
|
|
1094
|
+
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/60 opacity-0 hover:text-foreground group-hover:opacity-100"
|
|
1146
1095
|
>
|
|
1147
|
-
|
|
1148
|
-
</
|
|
1149
|
-
<div className="flex items-center">
|
|
1150
|
-
<button
|
|
1151
|
-
type="button"
|
|
1152
|
-
onClick={() =>
|
|
1153
|
-
toggleHiddenCalendar("external", cal.id)
|
|
1154
|
-
}
|
|
1155
|
-
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground group-hover:text-muted-foreground/80"
|
|
1156
|
-
aria-label={
|
|
1157
|
-
isHiddenCalendar("external", cal.id)
|
|
1158
|
-
? t("sidebar.showCalendar")
|
|
1159
|
-
: t("sidebar.hideCalendar")
|
|
1160
|
-
}
|
|
1161
|
-
>
|
|
1162
|
-
{isHiddenCalendar("external", cal.id) ? (
|
|
1163
|
-
<IconEyeOff className="h-3 w-3" />
|
|
1164
|
-
) : (
|
|
1165
|
-
<IconEye className="h-3 w-3" />
|
|
1166
|
-
)}
|
|
1167
|
-
</button>
|
|
1168
|
-
<button
|
|
1169
|
-
type="button"
|
|
1170
|
-
onClick={() => removeExternal.mutate(cal.id)}
|
|
1171
|
-
className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/60 opacity-0 hover:text-foreground group-hover:opacity-100"
|
|
1172
|
-
>
|
|
1173
|
-
<IconX className="h-3 w-3" />
|
|
1174
|
-
</button>
|
|
1175
|
-
</div>
|
|
1096
|
+
<IconX className="h-3 w-3" />
|
|
1097
|
+
</button>
|
|
1176
1098
|
</div>
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
</
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
</>
|
|
1185
|
-
)}
|
|
1186
|
-
</div>
|
|
1187
|
-
|
|
1188
|
-
<nav
|
|
1189
|
-
className={cn(
|
|
1190
|
-
"shrink-0",
|
|
1191
|
-
collapsed
|
|
1192
|
-
? "flex flex-col items-center gap-1 px-1 py-2"
|
|
1193
|
-
: "space-y-0.5 px-2.5 pt-2.5",
|
|
1194
|
-
)}
|
|
1195
|
-
>
|
|
1196
|
-
{bottomNavItems.map((item) => {
|
|
1197
|
-
const isActive = location.pathname.startsWith(item.path);
|
|
1198
|
-
const link = (
|
|
1199
|
-
<Link
|
|
1200
|
-
to={item.path}
|
|
1201
|
-
onClick={onClose}
|
|
1202
|
-
aria-label={collapsed ? t(item.labelKey) : undefined}
|
|
1203
|
-
className={cn(
|
|
1204
|
-
"flex items-center rounded-lg font-medium transition-colors",
|
|
1205
|
-
collapsed
|
|
1206
|
-
? "h-10 w-10 justify-center"
|
|
1207
|
-
: "gap-3 px-3 py-2 text-sm",
|
|
1208
|
-
isActive
|
|
1209
|
-
? "bg-primary/10 text-primary"
|
|
1210
|
-
: "text-muted-foreground hover:bg-accent/60 hover:text-foreground",
|
|
1211
|
-
)}
|
|
1212
|
-
>
|
|
1213
|
-
<item.icon className="h-4 w-4" />
|
|
1214
|
-
{!collapsed && t(item.labelKey)}
|
|
1215
|
-
</Link>
|
|
1216
|
-
);
|
|
1217
|
-
return collapsed ? (
|
|
1218
|
-
<Tooltip key={item.path}>
|
|
1219
|
-
<TooltipTrigger asChild>{link}</TooltipTrigger>
|
|
1220
|
-
<TooltipContent side="right">{t(item.labelKey)}</TooltipContent>
|
|
1221
|
-
</Tooltip>
|
|
1222
|
-
) : (
|
|
1223
|
-
<div key={item.path}>{link}</div>
|
|
1224
|
-
);
|
|
1225
|
-
})}
|
|
1226
|
-
</nav>
|
|
1227
|
-
|
|
1228
|
-
{!collapsed ? (
|
|
1229
|
-
<>
|
|
1230
|
-
<div className="px-3 py-2 empty:hidden">
|
|
1231
|
-
<OrgSwitcher />
|
|
1232
|
-
</div>
|
|
1233
|
-
|
|
1234
|
-
<div className="px-3 py-2 empty:hidden">
|
|
1235
|
-
<DevDatabaseLink />
|
|
1099
|
+
</div>
|
|
1100
|
+
))}
|
|
1101
|
+
</CollapsibleContent>
|
|
1102
|
+
</Collapsible>
|
|
1103
|
+
)}
|
|
1104
|
+
</div>
|
|
1105
|
+
)}
|
|
1236
1106
|
</div>
|
|
1237
1107
|
</>
|
|
1238
|
-
)
|
|
1239
|
-
|
|
1240
|
-
collapsed={collapsed}
|
|
1241
|
-
feedback={feedbackButton}
|
|
1242
|
-
search={searchButton}
|
|
1243
|
-
collapse={collapseButton}
|
|
1244
|
-
/>
|
|
1245
|
-
</aside>
|
|
1108
|
+
)}
|
|
1109
|
+
</AppSidebar>
|
|
1246
1110
|
</>
|
|
1247
1111
|
);
|
|
1248
1112
|
}
|