@uipath/apollo-vertex 1.2.0 → 1.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/dist/lib/i18n.d.ts +10 -0
- package/dist/lib/table-features.d.ts +38 -0
- package/dist/lib/table-features.js +32 -0
- package/dist/locales/en.json +5 -0
- package/dist/registry/calendar/calendar.js +2 -2
- package/dist/registry/command/command.js +3 -0
- package/dist/registry/confidence-signal/confidence-signal-chip.js +1 -1
- package/dist/registry/data-table/data-table-column-header.d.ts +5 -4
- package/dist/registry/data-table/data-table-column-header.js +21 -18
- package/dist/registry/data-table/data-table-expand-toggle.d.ts +5 -4
- package/dist/registry/data-table/data-table-expand-toggle.js +1 -1
- package/dist/registry/data-table/data-table-filters.d.ts +4 -3
- package/dist/registry/data-table/data-table-filters.js +4 -4
- package/dist/registry/data-table/data-table-pagination.d.ts +5 -4
- package/dist/registry/data-table/data-table-pagination.js +2 -3
- package/dist/registry/data-table/data-table-search.d.ts +5 -4
- package/dist/registry/data-table/data-table-search.js +2 -2
- package/dist/registry/data-table/data-table-toolbar.d.ts +5 -4
- package/dist/registry/data-table/data-table-view-options.d.ts +5 -4
- package/dist/registry/data-table/data-table-view-options.js +2 -2
- package/dist/registry/data-table/data-table.d.ts +13 -12
- package/dist/registry/data-table/data-table.js +9 -12
- package/dist/registry/data-table/index.d.ts +3 -2
- package/dist/registry/data-table/index.js +1 -1
- package/dist/registry/filter-dropdown/filter-dropdown.d.ts +4 -4
- package/dist/registry/filter-dropdown/filter-dropdown.js +1 -1
- package/dist/registry/shell/shell-company.js +2 -1
- package/dist/registry/shell/shell-locale-provider.d.ts +2 -1
- package/dist/registry/shell/shell-locale-provider.js +12 -8
- package/dist/registry/shell/shell-minimal-nav-item.d.ts +4 -3
- package/dist/registry/shell/shell-minimal-nav-item.js +3 -7
- package/dist/registry/shell/shell-nav-active.d.ts +12 -0
- package/dist/registry/shell/shell-nav-active.js +24 -0
- package/dist/registry/shell/shell-nav-label.d.ts +7 -0
- package/dist/registry/shell/shell-nav-label.js +54 -0
- package/dist/registry/shell/shell-sidebar.js +126 -114
- package/dist/registry/shell/shell-text.d.ts +2 -2
- package/dist/registry/shell/shell-text.js +3 -2
- package/dist/registry/shell/shell-translation-key.d.ts +5 -0
- package/dist/registry/shell/shell.d.ts +6 -3
- package/dist/registry/shell/shell.js +18 -13
- package/dist/registry/solution-tests/config.d.ts +5 -5
- package/dist/registry/solution-tests/solution-tests-view.js +1 -1
- package/dist/registry/table-chart/table-chart-view.js +9 -5
- package/dist/registry/timeline/timeline-marker.js +2 -2
- package/dist/registry/use-data-table/types.d.ts +3 -2
- package/dist/registry/use-data-table/useColumnVisibility.d.ts +3 -3
- package/dist/registry/use-data-table/useDataTable.d.ts +8 -7
- package/dist/registry/use-data-table/useEntityColumns.d.ts +2 -2
- package/dist/registry/use-data-table/useEntityDataTable.d.ts +3 -3
- package/package.json +2 -2
- package/skills/setup/SKILL.md +123 -0
- package/dist/registry/use-data-table/useReactTableCompat.d.ts +0 -13
- package/dist/registry/use-data-table/useReactTableCompat.js +0 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Column } from "@tanstack/react-table";
|
|
2
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import type { DataTableColumn, RowData } from "../../lib/table-features";
|
|
3
3
|
interface FilterDropdownOption {
|
|
4
4
|
label: string;
|
|
5
5
|
value: string;
|
|
@@ -7,14 +7,14 @@ interface FilterDropdownOption {
|
|
|
7
7
|
className?: string;
|
|
8
8
|
}>;
|
|
9
9
|
}
|
|
10
|
-
interface FilterDropdownProps<TData =
|
|
10
|
+
interface FilterDropdownProps<TData extends RowData = RowData, TValue = unknown> {
|
|
11
11
|
title: string;
|
|
12
12
|
options: FilterDropdownOption[];
|
|
13
13
|
className?: string;
|
|
14
14
|
/** Multi-select (default) or single-select mode */
|
|
15
15
|
multiSelect?: boolean;
|
|
16
16
|
/** TanStack Table column integration (optional) */
|
|
17
|
-
column?:
|
|
17
|
+
column?: DataTableColumn<TData, TValue>;
|
|
18
18
|
/** Standalone value — used when no column is provided */
|
|
19
19
|
value?: string[] | string;
|
|
20
20
|
/** Standalone onChange — used when no column is provided */
|
|
@@ -56,6 +56,6 @@ interface FilterDropdownProps<TData = unknown, TValue = unknown> {
|
|
|
56
56
|
/** Known options for selected values that may not be loaded yet (used for the trigger label) */
|
|
57
57
|
selectedOptions?: FilterDropdownOption[];
|
|
58
58
|
}
|
|
59
|
-
declare function FilterDropdown<TData, TValue>({ title, options, className, multiSelect, column, value: valueProp, onChange: onChangeProp, enableSearch, searchThreshold, searchPlaceholder, noOptionsMessage, noResultsMessage, align, popoverWidth, isLoading, hasMore, onLoadMore, loadingMessage, onSearchChange, searchDebounceMs, error, errorMessage, onRetry, retryLabel, selectedOptions, }: FilterDropdownProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
declare function FilterDropdown<TData extends RowData = RowData, TValue = unknown>({ title, options, className, multiSelect, column, value: valueProp, onChange: onChangeProp, enableSearch, searchThreshold, searchPlaceholder, noOptionsMessage, noResultsMessage, align, popoverWidth, isLoading, hasMore, onLoadMore, loadingMessage, onSearchChange, searchDebounceMs, error, errorMessage, onRetry, retryLabel, selectedOptions, }: FilterDropdownProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
|
|
60
60
|
export { FilterDropdown };
|
|
61
61
|
export type { FilterDropdownOption, FilterDropdownProps };
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronDownIcon, SearchIcon, XIcon } from "lucide-react";
|
|
4
4
|
import { useState } from "react";
|
|
5
|
-
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
6
5
|
import { Button } from "../button/button.js";
|
|
7
6
|
import { Input } from "../input/input.js";
|
|
8
7
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover/popover.js";
|
|
9
8
|
import { Separator } from "../separator/separator.js";
|
|
10
9
|
import { cn } from "../../lib/utils.js";
|
|
10
|
+
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
11
11
|
import { FilterDropdownOptionRow } from "./filter-dropdown-option.js";
|
|
12
12
|
import { FILTER_DROPDOWN_LIST_SLOT, FilterDropdownError, FilterDropdownLoadingMore, FilterDropdownSentinel, FilterDropdownSkeleton } from "./filter-dropdown-states.js";
|
|
13
13
|
import { useFilterDropdownSearch } from "./use-filter-dropdown-search.js";
|
|
@@ -3,11 +3,11 @@ import { Link } from "@tanstack/react-router";
|
|
|
3
3
|
import { AnimatePresence, motion } from "framer-motion";
|
|
4
4
|
import { PanelLeft } from "lucide-react";
|
|
5
5
|
import { useState } from "react";
|
|
6
|
-
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
7
6
|
import { Button } from "../button/button.js";
|
|
8
7
|
import { useSidebar } from "../sidebar/sidebar.js";
|
|
9
8
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../tooltip/tooltip.js";
|
|
10
9
|
import { cn } from "../../lib/utils.js";
|
|
10
|
+
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
11
11
|
import { fastFadeTransition, iconHoverScale, scaleVariants, textFadeVariants } from "./shell-animations.js";
|
|
12
12
|
import { CompanyLogoIcon } from "./shell-company-logo.js";
|
|
13
13
|
function CollapsedLogo({ companyLogo, sidebarHovered, onExpand }) {
|
|
@@ -162,6 +162,7 @@ const Company = ({ companyName, productName, companyLogo, sidebarHovered = false
|
|
|
162
162
|
children: /*#__PURE__*/ jsx(Button, {
|
|
163
163
|
variant: "ghost",
|
|
164
164
|
size: "icon-sm",
|
|
165
|
+
"aria-label": t("close_sidebar"),
|
|
165
166
|
onClick: toggleSidebar,
|
|
166
167
|
className: "ml-auto shrink-0 text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground cursor-pointer",
|
|
167
168
|
children: /*#__PURE__*/ jsx(PanelLeft, {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type PropsWithChildren, type ReactNode } from "react";
|
|
2
2
|
interface LocaleProviderProps {
|
|
3
3
|
loadingElement?: ReactNode;
|
|
4
|
+
configureI18n?: () => Promise<void>;
|
|
4
5
|
}
|
|
5
6
|
export declare const LocaleProviderComponent: ({ children }: PropsWithChildren) => ReactNode;
|
|
6
|
-
export declare const LocaleProvider: ({ children, loadingElement, }: PropsWithChildren<LocaleProviderProps>) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const LocaleProvider: ({ children, loadingElement, configureI18n, }: PropsWithChildren<LocaleProviderProps>) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useEffectEvent, useState } from "react";
|
|
4
|
-
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
5
4
|
import { Spinner } from "../spinner/spinner.js";
|
|
6
5
|
import { configurei18n } from "../../lib/i18n.js";
|
|
6
|
+
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
7
7
|
import { LANGUAGE_CHANGED_EVENT } from "./shell-constants.js";
|
|
8
8
|
const LocaleProviderComponent = ({ children })=>{
|
|
9
9
|
const { i18n } = useVertexTranslation();
|
|
@@ -21,15 +21,19 @@ const LocaleProviderComponent = ({ children })=>{
|
|
|
21
21
|
}, []);
|
|
22
22
|
return children;
|
|
23
23
|
};
|
|
24
|
-
const LocaleProvider = ({ children, loadingElement })=>{
|
|
24
|
+
const LocaleProvider = ({ children, loadingElement, configureI18n = configurei18n })=>{
|
|
25
25
|
const [isConfigured, setIsConfigured] = useState(false);
|
|
26
|
-
const configure = async ()=>{
|
|
27
|
-
await configurei18n();
|
|
28
|
-
setIsConfigured(true);
|
|
29
|
-
};
|
|
30
26
|
useEffect(()=>{
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
let cancelled = false;
|
|
28
|
+
configureI18n().then(()=>{
|
|
29
|
+
if (!cancelled) setIsConfigured(true);
|
|
30
|
+
});
|
|
31
|
+
return ()=>{
|
|
32
|
+
cancelled = true;
|
|
33
|
+
};
|
|
34
|
+
}, [
|
|
35
|
+
configureI18n
|
|
36
|
+
]);
|
|
33
37
|
if (!isConfigured) return loadingElement ?? /*#__PURE__*/ jsx("div", {
|
|
34
38
|
className: "flex h-full w-full items-center justify-center",
|
|
35
39
|
children: /*#__PURE__*/ jsx(Spinner, {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShellNavLabel } from "./shell-translation-key";
|
|
2
2
|
interface MinimalNavItemProps {
|
|
3
3
|
to: string;
|
|
4
|
-
|
|
4
|
+
active: boolean;
|
|
5
|
+
label: ShellNavLabel;
|
|
5
6
|
}
|
|
6
|
-
export declare const MinimalNavItem: ({ to, label }: MinimalNavItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const MinimalNavItem: ({ to, active, label }: MinimalNavItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Link
|
|
2
|
+
import { Link } from "@tanstack/react-router";
|
|
3
3
|
import { cn } from "../../lib/utils.js";
|
|
4
4
|
import { Text } from "./shell-text.js";
|
|
5
|
-
const MinimalNavItem = ({ to, label })
|
|
6
|
-
const { pathname } = useLocation();
|
|
7
|
-
const isActive = pathname === to;
|
|
8
|
-
return /*#__PURE__*/ jsx(Link, {
|
|
5
|
+
const MinimalNavItem = ({ to, active, label })=>/*#__PURE__*/ jsx(Link, {
|
|
9
6
|
to: to,
|
|
10
|
-
className: cn("px-4 py-1.5 rounded-full text-sm font-medium transition-colors duration-200 shrink-0 whitespace-nowrap",
|
|
7
|
+
className: cn("px-4 py-1.5 rounded-full text-sm font-medium transition-colors duration-200 shrink-0 whitespace-nowrap", active ? "bg-[oklch(0.92_0.035_218)] dark:bg-primary-900/30 text-primary-700 dark:text-primary-400 font-semibold" : "text-muted-foreground hover:text-foreground hover:bg-black/[0.04] dark:hover:bg-white/[0.06]"),
|
|
11
8
|
children: /*#__PURE__*/ jsx(Text, {
|
|
12
9
|
value: label
|
|
13
10
|
})
|
|
14
11
|
});
|
|
15
|
-
};
|
|
16
12
|
export { MinimalNavItem };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function navPathIsActive(pathname: string, path: string): boolean;
|
|
2
|
+
export declare function navItemIsCurrent(pathname: string, path: string, childPaths?: readonly string[]): boolean;
|
|
3
|
+
export declare function mostSpecificActivePath(pathname: string, paths: readonly string[]): string | null;
|
|
4
|
+
export declare function navItemState(pathname: string, item: {
|
|
5
|
+
path: string;
|
|
6
|
+
to?: string;
|
|
7
|
+
childPaths?: readonly string[];
|
|
8
|
+
}): {
|
|
9
|
+
href: string;
|
|
10
|
+
prefixActive: boolean;
|
|
11
|
+
current: boolean;
|
|
12
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function navPathIsActive(pathname, path) {
|
|
2
|
+
if ("/" === path) return "/" === pathname;
|
|
3
|
+
return pathname === path || pathname.startsWith(`${path}/`);
|
|
4
|
+
}
|
|
5
|
+
function navItemIsCurrent(pathname, path, childPaths = []) {
|
|
6
|
+
return navPathIsActive(pathname, path) && !childPaths.some((childPath)=>navPathIsActive(pathname, childPath));
|
|
7
|
+
}
|
|
8
|
+
function mostSpecificActivePath(pathname, paths) {
|
|
9
|
+
let match = null;
|
|
10
|
+
for (const path of paths)if (navPathIsActive(pathname, path)) {
|
|
11
|
+
if (null === match || path.length > match.length) match = path;
|
|
12
|
+
}
|
|
13
|
+
return match;
|
|
14
|
+
}
|
|
15
|
+
function navItemState(pathname, item) {
|
|
16
|
+
const childPaths = item.childPaths ?? [];
|
|
17
|
+
const childActive = childPaths.some((childPath)=>navPathIsActive(pathname, childPath));
|
|
18
|
+
return {
|
|
19
|
+
href: item.to ?? item.path,
|
|
20
|
+
prefixActive: navPathIsActive(pathname, item.path) || childActive,
|
|
21
|
+
current: navItemIsCurrent(pathname, item.path, childPaths)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export { mostSpecificActivePath, navItemIsCurrent, navItemState, navPathIsActive };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface NavCatalog {
|
|
2
|
+
namespaces: readonly string[];
|
|
3
|
+
exists: (key: string, namespace: string) => boolean;
|
|
4
|
+
translate: (key: string, namespace: string) => string;
|
|
5
|
+
}
|
|
6
|
+
export declare function navCatalogFromHook(i18n: object): NavCatalog;
|
|
7
|
+
export declare function readNavLabel(catalog: NavCatalog, key: string): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { VERTEX_NAMESPACE } from "../../lib/vertex-translation.js";
|
|
2
|
+
function configuredNamespaces(defaultNS) {
|
|
3
|
+
if ("string" == typeof defaultNS) return defaultNS.length > 0 ? [
|
|
4
|
+
defaultNS
|
|
5
|
+
] : [
|
|
6
|
+
"translation"
|
|
7
|
+
];
|
|
8
|
+
if (!Array.isArray(defaultNS)) return [
|
|
9
|
+
"translation"
|
|
10
|
+
];
|
|
11
|
+
const namespaces = [];
|
|
12
|
+
for (const namespace of defaultNS)if ("string" == typeof namespace && namespace.length > 0) namespaces.push(namespace);
|
|
13
|
+
return namespaces.length > 0 ? namespaces : [
|
|
14
|
+
"translation"
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
function lookupNamespaces(defaultNS) {
|
|
18
|
+
const configured = configuredNamespaces(defaultNS);
|
|
19
|
+
if (configured.includes(VERTEX_NAMESPACE)) return configured;
|
|
20
|
+
return [
|
|
21
|
+
...configured,
|
|
22
|
+
VERTEX_NAMESPACE
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
function isNamespacedI18n(value) {
|
|
26
|
+
return "options" in value && "exists" in value && "function" == typeof value.exists && "t" in value && "function" == typeof value.t;
|
|
27
|
+
}
|
|
28
|
+
function navCatalogFromHook(i18n) {
|
|
29
|
+
if (!isNamespacedI18n(i18n)) return {
|
|
30
|
+
namespaces: [
|
|
31
|
+
"translation",
|
|
32
|
+
VERTEX_NAMESPACE
|
|
33
|
+
],
|
|
34
|
+
exists: ()=>false,
|
|
35
|
+
translate: (key)=>key
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
namespaces: lookupNamespaces(i18n.options.defaultNS),
|
|
39
|
+
exists: (key, namespace)=>i18n.exists(key, {
|
|
40
|
+
ns: namespace
|
|
41
|
+
}),
|
|
42
|
+
translate: (key, namespace)=>{
|
|
43
|
+
const value = i18n.t(key, {
|
|
44
|
+
ns: namespace
|
|
45
|
+
});
|
|
46
|
+
return "string" == typeof value ? value : key;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function readNavLabel(catalog, key) {
|
|
51
|
+
for (const namespace of catalog.namespaces)if (catalog.exists(key, namespace)) return catalog.translate(key, namespace);
|
|
52
|
+
return key;
|
|
53
|
+
}
|
|
54
|
+
export { navCatalogFromHook, readNavLabel };
|
|
@@ -4,45 +4,54 @@ import { Link, useLocation } from "@tanstack/react-router";
|
|
|
4
4
|
import { AnimatePresence, motion } from "framer-motion";
|
|
5
5
|
import { ChevronDown } from "lucide-react";
|
|
6
6
|
import { useEffect, useState } from "react";
|
|
7
|
-
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
8
7
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../collapsible/collapsible.js";
|
|
9
8
|
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, useSidebar } from "../sidebar/sidebar.js";
|
|
10
9
|
import { cn } from "../../lib/utils.js";
|
|
10
|
+
import { useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
11
11
|
import { fastFadeTransition, iconHoverScale, textFadeVariants } from "./shell-animations.js";
|
|
12
12
|
import { Company } from "./shell-company.js";
|
|
13
13
|
import { MinimalCompany } from "./shell-minimal-company.js";
|
|
14
14
|
import { MinimalNavItem } from "./shell-minimal-nav-item.js";
|
|
15
|
+
import { mostSpecificActivePath, navItemState } from "./shell-nav-active.js";
|
|
16
|
+
import { navCatalogFromHook, readNavLabel } from "./shell-nav-label.js";
|
|
15
17
|
import { Text } from "./shell-text.js";
|
|
16
18
|
import { UserProfile } from "./shell-user-profile.js";
|
|
17
19
|
const activeNavClass = "text-sidebar-foreground/85 hover:text-sidebar-foreground data-[active=true]:text-primary-700 dark:data-[active=true]:text-primary-400 data-[active=true]:font-semibold data-[active=true]:bg-primary-100/40 dark:data-[active=true]:bg-primary-900/30";
|
|
18
20
|
const navButtonClass = `font-medium ${activeNavClass}`;
|
|
19
21
|
const subButtonClass = activeNavClass;
|
|
22
|
+
const prefixActiveClass = "font-semibold text-primary-700 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-400 active:text-primary-700 dark:active:text-primary-400";
|
|
23
|
+
const currentPillClass = "bg-primary-100/40 dark:bg-primary-900/30";
|
|
20
24
|
const ShellSidebar = ({ companyName, productName, variant, companyLogo, navItems })=>{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
const { pathname } = useLocation();
|
|
26
|
+
if ("minimal" === variant) {
|
|
27
|
+
const activePath = mostSpecificActivePath(pathname, navItems.map((item)=>item.path));
|
|
28
|
+
return /*#__PURE__*/ jsxs("header", {
|
|
29
|
+
className: "relative flex items-center justify-between px-4 sm:px-6 lg:px-8 py-6 transition-[padding] duration-300 ease-in-out",
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ jsx(MinimalCompany, {
|
|
32
|
+
companyName: companyName,
|
|
33
|
+
productName: productName,
|
|
34
|
+
companyLogo: companyLogo
|
|
35
|
+
}),
|
|
36
|
+
navItems.length > 0 && /*#__PURE__*/ jsx("nav", {
|
|
37
|
+
className: "absolute left-1/2 -translate-x-1/2 flex items-center bg-muted dark:bg-[oklch(0.24_0.033_254)] rounded-full p-1.5 overflow-x-auto scrollbar-thin",
|
|
38
|
+
children: navItems.map((item)=>/*#__PURE__*/ jsx(MinimalNavItem, {
|
|
39
|
+
to: item.to ?? item.path,
|
|
40
|
+
active: item.path === activePath,
|
|
41
|
+
label: item.label
|
|
42
|
+
}, item.path))
|
|
43
|
+
}),
|
|
44
|
+
/*#__PURE__*/ jsx("div", {
|
|
45
|
+
className: "flex items-center gap-2",
|
|
46
|
+
children: /*#__PURE__*/ jsx(UserProfile, {
|
|
47
|
+
isCollapsed: true,
|
|
48
|
+
collapsedMenuSide: "bottom",
|
|
49
|
+
collapsedMenuAlign: "end"
|
|
50
|
+
})
|
|
42
51
|
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
}
|
|
46
55
|
return /*#__PURE__*/ jsx(SidebarNav, {
|
|
47
56
|
companyName: companyName,
|
|
48
57
|
productName: productName,
|
|
@@ -51,8 +60,9 @@ const ShellSidebar = ({ companyName, productName, variant, companyLogo, navItems
|
|
|
51
60
|
});
|
|
52
61
|
};
|
|
53
62
|
function SidebarNav({ companyName, productName, companyLogo, navItems }) {
|
|
54
|
-
const { t } = useVertexTranslation();
|
|
55
|
-
const
|
|
63
|
+
const { t, i18n } = useVertexTranslation();
|
|
64
|
+
const catalog = navCatalogFromHook(i18n);
|
|
65
|
+
const { state } = useSidebar();
|
|
56
66
|
const { pathname } = useLocation();
|
|
57
67
|
const isCollapsed = "collapsed" === state;
|
|
58
68
|
const [sidebarHovered, setSidebarHovered] = useState(false);
|
|
@@ -75,24 +85,16 @@ function SidebarNav({ companyName, productName, companyLogo, navItems }) {
|
|
|
75
85
|
pathname,
|
|
76
86
|
navItems
|
|
77
87
|
]);
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
toggleSidebar();
|
|
81
|
-
setExpandedItems((prev)=>new Set(prev).add(path));
|
|
82
|
-
} else setExpandedItems((prev)=>{
|
|
88
|
+
const toggleGroup = (path)=>{
|
|
89
|
+
setExpandedItems((prev)=>{
|
|
83
90
|
const next = new Set(prev);
|
|
84
91
|
if (next.has(path)) next.delete(path);
|
|
85
92
|
else next.add(path);
|
|
86
93
|
return next;
|
|
87
94
|
});
|
|
88
95
|
};
|
|
89
|
-
const isActive = (path)=>{
|
|
90
|
-
if ("/" === path) return "/" === pathname;
|
|
91
|
-
return pathname === path || pathname.startsWith(`${path}/`);
|
|
92
|
-
};
|
|
93
|
-
const isParentActive = (item)=>item.subItems?.some((sub)=>isActive(sub.path)) ?? false;
|
|
94
96
|
const getTooltipText = (label)=>{
|
|
95
|
-
if ("string" == typeof label) return
|
|
97
|
+
if ("string" == typeof label) return readNavLabel(catalog, label);
|
|
96
98
|
return t(label.i18nKey, label.values);
|
|
97
99
|
};
|
|
98
100
|
return /*#__PURE__*/ jsxs(Sidebar, {
|
|
@@ -119,97 +121,107 @@ function SidebarNav({ companyName, productName, companyLogo, navItems }) {
|
|
|
119
121
|
children: /*#__PURE__*/ jsx(SidebarMenu, {
|
|
120
122
|
children: navItems.map((item)=>{
|
|
121
123
|
const Icon = item.icon;
|
|
122
|
-
const active = isActive(item.path);
|
|
123
|
-
const parentActive = isParentActive(item);
|
|
124
124
|
const isExpanded = expandedItems.has(item.path);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
125
|
+
const childPaths = item.subItems?.map((sub)=>sub.path) ?? [];
|
|
126
|
+
const row = navItemState(pathname, {
|
|
127
|
+
path: item.path,
|
|
128
|
+
to: item.to,
|
|
129
|
+
childPaths
|
|
130
|
+
});
|
|
131
|
+
if (item.subItems && item.subItems.length > 0) return /*#__PURE__*/ jsx(Collapsible, {
|
|
132
|
+
open: isExpanded && !isCollapsed,
|
|
133
|
+
onOpenChange: ()=>toggleGroup(item.path),
|
|
134
|
+
className: "group/collapsible",
|
|
135
|
+
children: /*#__PURE__*/ jsxs(SidebarMenuItem, {
|
|
136
|
+
children: [
|
|
137
|
+
/*#__PURE__*/ jsxs("div", {
|
|
138
|
+
className: cn("flex w-full min-w-0 items-center rounded-md", !isCollapsed && row.current && currentPillClass, !isCollapsed && !row.current && "hover:bg-sidebar-accent/50"),
|
|
139
|
+
children: [
|
|
140
|
+
/*#__PURE__*/ jsx(SidebarMenuButton, {
|
|
141
|
+
asChild: true,
|
|
136
142
|
tooltip: getTooltipText(item.label),
|
|
137
|
-
isActive:
|
|
138
|
-
className: navButtonClass,
|
|
139
|
-
children:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/*#__PURE__*/ jsx(AnimatePresence, {
|
|
150
|
-
initial: false,
|
|
151
|
-
children: !isCollapsed && /*#__PURE__*/ jsx(motion.span, {
|
|
152
|
-
variants: textFadeVariants,
|
|
153
|
-
initial: "initial",
|
|
154
|
-
animate: "animate",
|
|
155
|
-
exit: "exit",
|
|
156
|
-
transition: fastFadeTransition,
|
|
157
|
-
className: "whitespace-nowrap truncate",
|
|
158
|
-
children: /*#__PURE__*/ jsx(Text, {
|
|
159
|
-
value: item.label
|
|
143
|
+
isActive: isCollapsed && row.current,
|
|
144
|
+
className: cn(navButtonClass, row.prefixActive && prefixActiveClass, !isCollapsed && "w-auto min-w-0 flex-1 bg-transparent hover:bg-transparent"),
|
|
145
|
+
children: /*#__PURE__*/ jsxs(Link, {
|
|
146
|
+
to: row.href,
|
|
147
|
+
children: [
|
|
148
|
+
/*#__PURE__*/ jsx(motion.span, {
|
|
149
|
+
className: "inline-flex items-center justify-center shrink-0",
|
|
150
|
+
...isCollapsed ? {
|
|
151
|
+
whileHover: iconHoverScale
|
|
152
|
+
} : {},
|
|
153
|
+
children: /*#__PURE__*/ jsx(Icon, {
|
|
154
|
+
className: "size-4 shrink-0"
|
|
160
155
|
})
|
|
161
|
-
},
|
|
156
|
+
}),
|
|
157
|
+
/*#__PURE__*/ jsx(AnimatePresence, {
|
|
158
|
+
initial: false,
|
|
159
|
+
children: !isCollapsed && /*#__PURE__*/ jsx(motion.span, {
|
|
160
|
+
variants: textFadeVariants,
|
|
161
|
+
initial: "initial",
|
|
162
|
+
animate: "animate",
|
|
163
|
+
exit: "exit",
|
|
164
|
+
transition: fastFadeTransition,
|
|
165
|
+
className: "whitespace-nowrap truncate",
|
|
166
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
167
|
+
value: item.label
|
|
168
|
+
})
|
|
169
|
+
}, "text")
|
|
170
|
+
})
|
|
171
|
+
]
|
|
172
|
+
})
|
|
173
|
+
}),
|
|
174
|
+
!isCollapsed && /*#__PURE__*/ jsx(CollapsibleTrigger, {
|
|
175
|
+
asChild: true,
|
|
176
|
+
children: /*#__PURE__*/ jsx("button", {
|
|
177
|
+
type: "button",
|
|
178
|
+
"aria-expanded": isExpanded,
|
|
179
|
+
"aria-label": t(isExpanded ? "nav_collapse" : "nav_expand", {
|
|
180
|
+
label: getTooltipText(item.label)
|
|
162
181
|
}),
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
variants: textFadeVariants,
|
|
167
|
-
initial: "initial",
|
|
168
|
-
animate: "animate",
|
|
169
|
-
exit: "exit",
|
|
170
|
-
transition: fastFadeTransition,
|
|
171
|
-
className: "ml-auto",
|
|
172
|
-
children: /*#__PURE__*/ jsx(ChevronDown, {
|
|
173
|
-
className: cn("size-4 transition-transform duration-200", isExpanded && "rotate-180")
|
|
174
|
-
})
|
|
175
|
-
}, "chevron")
|
|
182
|
+
className: "flex size-8 shrink-0 items-center justify-center text-sidebar-foreground/70 hover:text-sidebar-foreground",
|
|
183
|
+
children: /*#__PURE__*/ jsx(ChevronDown, {
|
|
184
|
+
className: cn("size-4 transition-transform duration-200", isExpanded && "rotate-180")
|
|
176
185
|
})
|
|
177
|
-
|
|
186
|
+
})
|
|
178
187
|
})
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
188
|
+
]
|
|
189
|
+
}),
|
|
190
|
+
/*#__PURE__*/ jsx(CollapsibleContent, {
|
|
191
|
+
children: /*#__PURE__*/ jsx(SidebarMenuSub, {
|
|
192
|
+
className: "ml-4 mr-0 mt-1 gap-0.5 pl-3 pr-0",
|
|
193
|
+
children: item.subItems.map((subItem)=>{
|
|
194
|
+
const sub = navItemState(pathname, {
|
|
195
|
+
path: subItem.path,
|
|
196
|
+
to: subItem.to
|
|
197
|
+
});
|
|
198
|
+
return /*#__PURE__*/ jsx(SidebarMenuSubItem, {
|
|
199
|
+
children: /*#__PURE__*/ jsx(SidebarMenuSubButton, {
|
|
200
|
+
asChild: true,
|
|
201
|
+
isActive: sub.current,
|
|
202
|
+
className: cn("cursor-pointer whitespace-nowrap", subButtonClass),
|
|
203
|
+
children: /*#__PURE__*/ jsx(Link, {
|
|
204
|
+
to: sub.href,
|
|
205
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
206
|
+
value: subItem.label
|
|
195
207
|
})
|
|
196
208
|
})
|
|
197
|
-
}
|
|
198
|
-
})
|
|
209
|
+
})
|
|
210
|
+
}, subItem.path);
|
|
199
211
|
})
|
|
200
212
|
})
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
}
|
|
213
|
+
})
|
|
214
|
+
]
|
|
215
|
+
})
|
|
216
|
+
}, item.path);
|
|
205
217
|
return /*#__PURE__*/ jsx(SidebarMenuItem, {
|
|
206
218
|
children: /*#__PURE__*/ jsx(SidebarMenuButton, {
|
|
207
219
|
tooltip: getTooltipText(item.label),
|
|
208
|
-
isActive:
|
|
220
|
+
isActive: row.current,
|
|
209
221
|
asChild: true,
|
|
210
222
|
className: navButtonClass,
|
|
211
223
|
children: /*#__PURE__*/ jsxs(Link, {
|
|
212
|
-
to:
|
|
224
|
+
to: row.href,
|
|
213
225
|
children: [
|
|
214
226
|
/*#__PURE__*/ jsx(motion.span, {
|
|
215
227
|
className: "inline-flex items-center justify-center shrink-0",
|
|
@@ -252,7 +264,7 @@ function SidebarNav({ companyName, productName, companyLogo, navItems }) {
|
|
|
252
264
|
/*#__PURE__*/ jsx("div", {
|
|
253
265
|
className: "absolute inset-0 pointer-events-none",
|
|
254
266
|
style: {
|
|
255
|
-
boxShadow: "inset -1px 0 0 0 color-mix(in srgb, var(--
|
|
267
|
+
boxShadow: "inset -1px 0 0 0 color-mix(in srgb, var(--border) 50%, transparent)"
|
|
256
268
|
}
|
|
257
269
|
})
|
|
258
270
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShellNavLabel } from "./shell-translation-key";
|
|
2
2
|
export declare const Text: ({ value }: {
|
|
3
|
-
value:
|
|
3
|
+
value: ShellNavLabel;
|
|
4
4
|
}) => string | import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Trans } from "react-i18next";
|
|
3
3
|
import { VERTEX_NAMESPACE, useVertexTranslation } from "../../lib/vertex-translation.js";
|
|
4
|
+
import { navCatalogFromHook, readNavLabel } from "./shell-nav-label.js";
|
|
4
5
|
const Text = ({ value })=>{
|
|
5
|
-
const {
|
|
6
|
-
if ("string" == typeof value) return
|
|
6
|
+
const { i18n } = useVertexTranslation();
|
|
7
|
+
if ("string" == typeof value) return readNavLabel(navCatalogFromHook(i18n), value);
|
|
7
8
|
return /*#__PURE__*/ jsx(Trans, {
|
|
8
9
|
ns: VERTEX_NAMESPACE,
|
|
9
10
|
i18nKey: value.i18nKey,
|
|
@@ -5,3 +5,8 @@ export type TranslationKey = {
|
|
|
5
5
|
values: Record<string, string | number | string[]>;
|
|
6
6
|
components: Record<string, ReactElement>;
|
|
7
7
|
} | ParseKeys;
|
|
8
|
+
type TranslationObject = Extract<TranslationKey, {
|
|
9
|
+
i18nKey: ParseKeys;
|
|
10
|
+
}>;
|
|
11
|
+
export type ShellNavLabel = string | TranslationObject;
|
|
12
|
+
export {};
|