@almadar/ui 4.22.4 → 4.23.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/avl/index.cjs +35 -29
- package/dist/avl/index.js +36 -30
- package/dist/components/index.cjs +35 -29
- package/dist/components/index.js +36 -30
- package/dist/components/templates/DashboardLayout.d.ts +40 -4
- package/dist/providers/index.cjs +35 -29
- package/dist/providers/index.js +36 -30
- package/dist/runtime/index.cjs +35 -29
- package/dist/runtime/index.js +36 -30
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -21617,6 +21617,7 @@ var init_DashboardLayout = __esm({
|
|
|
21617
21617
|
init_Typography();
|
|
21618
21618
|
init_Icon();
|
|
21619
21619
|
init_useAuthContext();
|
|
21620
|
+
init_useEventBus();
|
|
21620
21621
|
init_useTranslate();
|
|
21621
21622
|
DashboardLayout = ({
|
|
21622
21623
|
appName = "{{APP_TITLE}}",
|
|
@@ -21624,11 +21625,29 @@ var init_DashboardLayout = __esm({
|
|
|
21624
21625
|
navItems = [],
|
|
21625
21626
|
user: userProp,
|
|
21626
21627
|
headerActions,
|
|
21627
|
-
showSearch =
|
|
21628
|
+
showSearch = false,
|
|
21629
|
+
searchEvent,
|
|
21630
|
+
onSearchSubmit,
|
|
21631
|
+
notifications,
|
|
21632
|
+
notificationClickEvent,
|
|
21633
|
+
onNotificationClick,
|
|
21634
|
+
showThemeToggle = true,
|
|
21628
21635
|
sidebarFooter,
|
|
21629
21636
|
onSignOut: onSignOutProp,
|
|
21630
21637
|
children
|
|
21631
21638
|
}) => {
|
|
21639
|
+
const eventBus = useEventBus();
|
|
21640
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
21641
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
21642
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
21643
|
+
const handleSearchSubmit = (value) => {
|
|
21644
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
21645
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
21646
|
+
};
|
|
21647
|
+
const handleNotificationClick = () => {
|
|
21648
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
21649
|
+
if (onNotificationClick) onNotificationClick();
|
|
21650
|
+
};
|
|
21632
21651
|
const [sidebarOpen, setSidebarOpen] = React127.useState(false);
|
|
21633
21652
|
const [userMenuOpen, setUserMenuOpen] = React127.useState(false);
|
|
21634
21653
|
const location = reactRouterDom.useLocation();
|
|
@@ -21709,17 +21728,7 @@ var init_DashboardLayout = __esm({
|
|
|
21709
21728
|
))
|
|
21710
21729
|
}
|
|
21711
21730
|
),
|
|
21712
|
-
sidebarFooter
|
|
21713
|
-
reactRouterDom.Link,
|
|
21714
|
-
{
|
|
21715
|
-
to: "/settings",
|
|
21716
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
21717
|
-
children: [
|
|
21718
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-5 w-5" }),
|
|
21719
|
-
t("common.settings")
|
|
21720
|
-
]
|
|
21721
|
-
}
|
|
21722
|
-
) })
|
|
21731
|
+
sidebarFooter && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
21723
21732
|
]
|
|
21724
21733
|
}
|
|
21725
21734
|
),
|
|
@@ -21746,32 +21755,40 @@ var init_DashboardLayout = __esm({
|
|
|
21746
21755
|
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Menu, { className: "h-5 w-5" })
|
|
21747
21756
|
}
|
|
21748
21757
|
),
|
|
21749
|
-
|
|
21758
|
+
searchEnabled && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
|
|
21750
21759
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
21751
21760
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21752
21761
|
Input,
|
|
21753
21762
|
{
|
|
21754
21763
|
type: "search",
|
|
21755
21764
|
placeholder: t("common.search"),
|
|
21756
|
-
className: "pl-10 w-full"
|
|
21765
|
+
className: "pl-10 w-full",
|
|
21766
|
+
onKeyDown: (e) => {
|
|
21767
|
+
if (e.key === "Enter") {
|
|
21768
|
+
handleSearchSubmit(e.target.value);
|
|
21769
|
+
}
|
|
21770
|
+
}
|
|
21757
21771
|
}
|
|
21758
21772
|
)
|
|
21759
21773
|
] }) }),
|
|
21760
21774
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
21761
21775
|
headerActions,
|
|
21762
|
-
/* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
21763
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21776
|
+
showThemeToggle && /* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
21777
|
+
notificationsEnabled && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21764
21778
|
Button,
|
|
21765
21779
|
{
|
|
21766
21780
|
variant: "ghost",
|
|
21767
21781
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
21782
|
+
onClick: handleNotificationClick,
|
|
21783
|
+
"aria-label": t("common.notifications"),
|
|
21768
21784
|
children: [
|
|
21769
21785
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
21770
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21786
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21771
21787
|
Box,
|
|
21772
21788
|
{
|
|
21773
21789
|
as: "span",
|
|
21774
|
-
className: "absolute top-
|
|
21790
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
21791
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21775
21792
|
}
|
|
21776
21793
|
)
|
|
21777
21794
|
]
|
|
@@ -21836,17 +21853,6 @@ var init_DashboardLayout = __esm({
|
|
|
21836
21853
|
}
|
|
21837
21854
|
)
|
|
21838
21855
|
] }),
|
|
21839
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21840
|
-
reactRouterDom.Link,
|
|
21841
|
-
{
|
|
21842
|
-
to: "/settings",
|
|
21843
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
21844
|
-
children: [
|
|
21845
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-4 w-4" }),
|
|
21846
|
-
t("common.settings")
|
|
21847
|
-
]
|
|
21848
|
-
}
|
|
21849
|
-
),
|
|
21850
21856
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21851
21857
|
Button,
|
|
21852
21858
|
{
|
package/dist/avl/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Html, RoundedBox, OrbitControls as OrbitControls$1, Grid as Grid$1, Sta
|
|
|
3
3
|
import * as React127 from 'react';
|
|
4
4
|
import React127__default, { createContext, useContext, useRef, useState, useCallback, useMemo, useEffect, Suspense, useLayoutEffect, useReducer, lazy, useId, forwardRef, useImperativeHandle, Component } from 'react';
|
|
5
5
|
import * as LucideIcons from 'lucide-react';
|
|
6
|
-
import { Loader2, ChevronDown, X, Check, Copy, AlertTriangle, Info, AlertCircle, CheckCircle, List, Printer, ChevronRight, ChevronLeft, Code, FileText, WrapText, Trash2,
|
|
6
|
+
import { Loader2, ChevronDown, X, Check, Copy, AlertTriangle, Info, AlertCircle, CheckCircle, List, Printer, ChevronRight, ChevronLeft, Code, FileText, WrapText, Trash2, Menu as Menu$1, Search, Bell, LogOut, ZoomOut, ZoomIn, Download, FileQuestion, Inbox, XCircle, Filter, Plus, Pause, Play, RotateCcw, Package, Calendar, Pencil, Eye, MoreHorizontal, Image as Image$1, Upload, Minus, ArrowLeft, HelpCircle, ChevronUp, Eraser, Star, TrendingUp, TrendingDown, ArrowUp, ArrowDown, MoreVertical, Sun, Moon, Circle, Clock, CheckCircle2, ArrowRight, FileWarning, SkipForward, Bug, Send, Wrench, User, Tag, DollarSign, Zap, Sword, Move, Heart, Shield } from 'lucide-react';
|
|
7
7
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
8
8
|
import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1, isEntityAwarePattern } from '@almadar/patterns';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
@@ -21571,6 +21571,7 @@ var init_DashboardLayout = __esm({
|
|
|
21571
21571
|
init_Typography();
|
|
21572
21572
|
init_Icon();
|
|
21573
21573
|
init_useAuthContext();
|
|
21574
|
+
init_useEventBus();
|
|
21574
21575
|
init_useTranslate();
|
|
21575
21576
|
DashboardLayout = ({
|
|
21576
21577
|
appName = "{{APP_TITLE}}",
|
|
@@ -21578,11 +21579,29 @@ var init_DashboardLayout = __esm({
|
|
|
21578
21579
|
navItems = [],
|
|
21579
21580
|
user: userProp,
|
|
21580
21581
|
headerActions,
|
|
21581
|
-
showSearch =
|
|
21582
|
+
showSearch = false,
|
|
21583
|
+
searchEvent,
|
|
21584
|
+
onSearchSubmit,
|
|
21585
|
+
notifications,
|
|
21586
|
+
notificationClickEvent,
|
|
21587
|
+
onNotificationClick,
|
|
21588
|
+
showThemeToggle = true,
|
|
21582
21589
|
sidebarFooter,
|
|
21583
21590
|
onSignOut: onSignOutProp,
|
|
21584
21591
|
children
|
|
21585
21592
|
}) => {
|
|
21593
|
+
const eventBus = useEventBus();
|
|
21594
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
21595
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
21596
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
21597
|
+
const handleSearchSubmit = (value) => {
|
|
21598
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
21599
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
21600
|
+
};
|
|
21601
|
+
const handleNotificationClick = () => {
|
|
21602
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
21603
|
+
if (onNotificationClick) onNotificationClick();
|
|
21604
|
+
};
|
|
21586
21605
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
21587
21606
|
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
|
21588
21607
|
const location = useLocation();
|
|
@@ -21663,17 +21682,7 @@ var init_DashboardLayout = __esm({
|
|
|
21663
21682
|
))
|
|
21664
21683
|
}
|
|
21665
21684
|
),
|
|
21666
|
-
sidebarFooter
|
|
21667
|
-
Link,
|
|
21668
|
-
{
|
|
21669
|
-
to: "/settings",
|
|
21670
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
21671
|
-
children: [
|
|
21672
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-5 w-5" }),
|
|
21673
|
-
t("common.settings")
|
|
21674
|
-
]
|
|
21675
|
-
}
|
|
21676
|
-
) })
|
|
21685
|
+
sidebarFooter && /* @__PURE__ */ jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
21677
21686
|
]
|
|
21678
21687
|
}
|
|
21679
21688
|
),
|
|
@@ -21700,32 +21709,40 @@ var init_DashboardLayout = __esm({
|
|
|
21700
21709
|
children: /* @__PURE__ */ jsx(Menu$1, { className: "h-5 w-5" })
|
|
21701
21710
|
}
|
|
21702
21711
|
),
|
|
21703
|
-
|
|
21712
|
+
searchEnabled && /* @__PURE__ */ jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
|
|
21704
21713
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
21705
21714
|
/* @__PURE__ */ jsx(
|
|
21706
21715
|
Input,
|
|
21707
21716
|
{
|
|
21708
21717
|
type: "search",
|
|
21709
21718
|
placeholder: t("common.search"),
|
|
21710
|
-
className: "pl-10 w-full"
|
|
21719
|
+
className: "pl-10 w-full",
|
|
21720
|
+
onKeyDown: (e) => {
|
|
21721
|
+
if (e.key === "Enter") {
|
|
21722
|
+
handleSearchSubmit(e.target.value);
|
|
21723
|
+
}
|
|
21724
|
+
}
|
|
21711
21725
|
}
|
|
21712
21726
|
)
|
|
21713
21727
|
] }) }),
|
|
21714
21728
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
21715
21729
|
headerActions,
|
|
21716
|
-
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
21717
|
-
/* @__PURE__ */ jsxs(
|
|
21730
|
+
showThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
21731
|
+
notificationsEnabled && /* @__PURE__ */ jsxs(
|
|
21718
21732
|
Button,
|
|
21719
21733
|
{
|
|
21720
21734
|
variant: "ghost",
|
|
21721
21735
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
21736
|
+
onClick: handleNotificationClick,
|
|
21737
|
+
"aria-label": t("common.notifications"),
|
|
21722
21738
|
children: [
|
|
21723
21739
|
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
21724
|
-
/* @__PURE__ */ jsx(
|
|
21740
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
21725
21741
|
Box,
|
|
21726
21742
|
{
|
|
21727
21743
|
as: "span",
|
|
21728
|
-
className: "absolute top-
|
|
21744
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
21745
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21729
21746
|
}
|
|
21730
21747
|
)
|
|
21731
21748
|
]
|
|
@@ -21790,17 +21807,6 @@ var init_DashboardLayout = __esm({
|
|
|
21790
21807
|
}
|
|
21791
21808
|
)
|
|
21792
21809
|
] }),
|
|
21793
|
-
/* @__PURE__ */ jsxs(
|
|
21794
|
-
Link,
|
|
21795
|
-
{
|
|
21796
|
-
to: "/settings",
|
|
21797
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
21798
|
-
children: [
|
|
21799
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }),
|
|
21800
|
-
t("common.settings")
|
|
21801
|
-
]
|
|
21802
|
-
}
|
|
21803
|
-
),
|
|
21804
21810
|
/* @__PURE__ */ jsxs(
|
|
21805
21811
|
Button,
|
|
21806
21812
|
{
|
|
@@ -17041,6 +17041,7 @@ var init_DashboardLayout = __esm({
|
|
|
17041
17041
|
init_Typography();
|
|
17042
17042
|
init_Icon();
|
|
17043
17043
|
init_useAuthContext();
|
|
17044
|
+
init_useEventBus();
|
|
17044
17045
|
init_useTranslate();
|
|
17045
17046
|
exports.DashboardLayout = ({
|
|
17046
17047
|
appName = "{{APP_TITLE}}",
|
|
@@ -17048,11 +17049,29 @@ var init_DashboardLayout = __esm({
|
|
|
17048
17049
|
navItems = [],
|
|
17049
17050
|
user: userProp,
|
|
17050
17051
|
headerActions,
|
|
17051
|
-
showSearch =
|
|
17052
|
+
showSearch = false,
|
|
17053
|
+
searchEvent,
|
|
17054
|
+
onSearchSubmit,
|
|
17055
|
+
notifications,
|
|
17056
|
+
notificationClickEvent,
|
|
17057
|
+
onNotificationClick,
|
|
17058
|
+
showThemeToggle = true,
|
|
17052
17059
|
sidebarFooter,
|
|
17053
17060
|
onSignOut: onSignOutProp,
|
|
17054
17061
|
children
|
|
17055
17062
|
}) => {
|
|
17063
|
+
const eventBus = useEventBus();
|
|
17064
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
17065
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
17066
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
17067
|
+
const handleSearchSubmit = (value) => {
|
|
17068
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
17069
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
17070
|
+
};
|
|
17071
|
+
const handleNotificationClick = () => {
|
|
17072
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
17073
|
+
if (onNotificationClick) onNotificationClick();
|
|
17074
|
+
};
|
|
17056
17075
|
const [sidebarOpen, setSidebarOpen] = React110.useState(false);
|
|
17057
17076
|
const [userMenuOpen, setUserMenuOpen] = React110.useState(false);
|
|
17058
17077
|
const location = reactRouterDom.useLocation();
|
|
@@ -17137,17 +17156,7 @@ var init_DashboardLayout = __esm({
|
|
|
17137
17156
|
))
|
|
17138
17157
|
}
|
|
17139
17158
|
),
|
|
17140
|
-
sidebarFooter
|
|
17141
|
-
reactRouterDom.Link,
|
|
17142
|
-
{
|
|
17143
|
-
to: "/settings",
|
|
17144
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
17145
|
-
children: [
|
|
17146
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-5 w-5" }),
|
|
17147
|
-
t("common.settings")
|
|
17148
|
-
]
|
|
17149
|
-
}
|
|
17150
|
-
) })
|
|
17159
|
+
sidebarFooter && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
17151
17160
|
]
|
|
17152
17161
|
}
|
|
17153
17162
|
),
|
|
@@ -17174,32 +17183,40 @@ var init_DashboardLayout = __esm({
|
|
|
17174
17183
|
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Menu, { className: "h-5 w-5" })
|
|
17175
17184
|
}
|
|
17176
17185
|
),
|
|
17177
|
-
|
|
17186
|
+
searchEnabled && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "relative", children: [
|
|
17178
17187
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
17179
17188
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17180
17189
|
exports.Input,
|
|
17181
17190
|
{
|
|
17182
17191
|
type: "search",
|
|
17183
17192
|
placeholder: t("common.search"),
|
|
17184
|
-
className: "pl-10 w-full"
|
|
17193
|
+
className: "pl-10 w-full",
|
|
17194
|
+
onKeyDown: (e) => {
|
|
17195
|
+
if (e.key === "Enter") {
|
|
17196
|
+
handleSearchSubmit(e.target.value);
|
|
17197
|
+
}
|
|
17198
|
+
}
|
|
17185
17199
|
}
|
|
17186
17200
|
)
|
|
17187
17201
|
] }) }),
|
|
17188
17202
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { align: "center", gap: "xs", children: [
|
|
17189
17203
|
headerActions,
|
|
17190
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.ThemeToggle, {}),
|
|
17191
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17204
|
+
showThemeToggle && /* @__PURE__ */ jsxRuntime.jsx(exports.ThemeToggle, {}),
|
|
17205
|
+
notificationsEnabled && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17192
17206
|
exports.Button,
|
|
17193
17207
|
{
|
|
17194
17208
|
variant: "ghost",
|
|
17195
17209
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
17210
|
+
onClick: handleNotificationClick,
|
|
17211
|
+
"aria-label": t("common.notifications"),
|
|
17196
17212
|
children: [
|
|
17197
17213
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
17198
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17214
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17199
17215
|
exports.Box,
|
|
17200
17216
|
{
|
|
17201
17217
|
as: "span",
|
|
17202
|
-
className: "absolute top-
|
|
17218
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
17219
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
17203
17220
|
}
|
|
17204
17221
|
)
|
|
17205
17222
|
]
|
|
@@ -17264,17 +17281,6 @@ var init_DashboardLayout = __esm({
|
|
|
17264
17281
|
}
|
|
17265
17282
|
)
|
|
17266
17283
|
] }),
|
|
17267
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17268
|
-
reactRouterDom.Link,
|
|
17269
|
-
{
|
|
17270
|
-
to: "/settings",
|
|
17271
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
17272
|
-
children: [
|
|
17273
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-4 w-4" }),
|
|
17274
|
-
t("common.settings")
|
|
17275
|
-
]
|
|
17276
|
-
}
|
|
17277
|
-
),
|
|
17278
17284
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17279
17285
|
exports.Button,
|
|
17280
17286
|
{
|
package/dist/components/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as React110 from 'react';
|
|
|
4
4
|
import React110__default, { useContext, useMemo, useRef, useEffect, useCallback, createContext, useState, Suspense, lazy, useSyncExternalStore, useLayoutEffect, useId } from 'react';
|
|
5
5
|
import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
|
|
6
6
|
import * as LucideIcons from 'lucide-react';
|
|
7
|
-
import { Loader2, X, AlertTriangle, Info, AlertCircle, CheckCircle, ChevronDown, List, Printer, ChevronRight, ChevronLeft, XCircle, Wrench, RotateCcw, Send, Code, FileText, WrapText, Check, Copy, Zap, Sword, Move, Heart, Shield, Trash2,
|
|
7
|
+
import { Loader2, X, AlertTriangle, Info, AlertCircle, CheckCircle, ChevronDown, List, Printer, ChevronRight, ChevronLeft, XCircle, Wrench, RotateCcw, Send, Code, FileText, WrapText, Check, Copy, Zap, Sword, Move, Heart, Shield, Trash2, Menu as Menu$1, Search, Bell, LogOut, ChevronUp, MoreHorizontal, Bug, ZoomOut, ZoomIn, Download, Pause, Play, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ArrowRight, ArrowLeft, Eraser, SkipForward, TrendingUp, TrendingDown, Minus, ArrowUp, ArrowDown, MoreVertical, Circle, Clock, CheckCircle2, HelpCircle, FileQuestion, Inbox, Plus, User, Filter, Star, FileWarning, Tag, DollarSign, Sun, Moon } from 'lucide-react';
|
|
8
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
9
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
10
10
|
import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
|
|
@@ -16996,6 +16996,7 @@ var init_DashboardLayout = __esm({
|
|
|
16996
16996
|
init_Typography();
|
|
16997
16997
|
init_Icon();
|
|
16998
16998
|
init_useAuthContext();
|
|
16999
|
+
init_useEventBus();
|
|
16999
17000
|
init_useTranslate();
|
|
17000
17001
|
DashboardLayout = ({
|
|
17001
17002
|
appName = "{{APP_TITLE}}",
|
|
@@ -17003,11 +17004,29 @@ var init_DashboardLayout = __esm({
|
|
|
17003
17004
|
navItems = [],
|
|
17004
17005
|
user: userProp,
|
|
17005
17006
|
headerActions,
|
|
17006
|
-
showSearch =
|
|
17007
|
+
showSearch = false,
|
|
17008
|
+
searchEvent,
|
|
17009
|
+
onSearchSubmit,
|
|
17010
|
+
notifications,
|
|
17011
|
+
notificationClickEvent,
|
|
17012
|
+
onNotificationClick,
|
|
17013
|
+
showThemeToggle = true,
|
|
17007
17014
|
sidebarFooter,
|
|
17008
17015
|
onSignOut: onSignOutProp,
|
|
17009
17016
|
children
|
|
17010
17017
|
}) => {
|
|
17018
|
+
const eventBus = useEventBus();
|
|
17019
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
17020
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
17021
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
17022
|
+
const handleSearchSubmit = (value) => {
|
|
17023
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
17024
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
17025
|
+
};
|
|
17026
|
+
const handleNotificationClick = () => {
|
|
17027
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
17028
|
+
if (onNotificationClick) onNotificationClick();
|
|
17029
|
+
};
|
|
17011
17030
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
17012
17031
|
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
|
17013
17032
|
const location = useLocation();
|
|
@@ -17092,17 +17111,7 @@ var init_DashboardLayout = __esm({
|
|
|
17092
17111
|
))
|
|
17093
17112
|
}
|
|
17094
17113
|
),
|
|
17095
|
-
sidebarFooter
|
|
17096
|
-
Link,
|
|
17097
|
-
{
|
|
17098
|
-
to: "/settings",
|
|
17099
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
17100
|
-
children: [
|
|
17101
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-5 w-5" }),
|
|
17102
|
-
t("common.settings")
|
|
17103
|
-
]
|
|
17104
|
-
}
|
|
17105
|
-
) })
|
|
17114
|
+
sidebarFooter && /* @__PURE__ */ jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
17106
17115
|
]
|
|
17107
17116
|
}
|
|
17108
17117
|
),
|
|
@@ -17129,32 +17138,40 @@ var init_DashboardLayout = __esm({
|
|
|
17129
17138
|
children: /* @__PURE__ */ jsx(Menu$1, { className: "h-5 w-5" })
|
|
17130
17139
|
}
|
|
17131
17140
|
),
|
|
17132
|
-
|
|
17141
|
+
searchEnabled && /* @__PURE__ */ jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
|
|
17133
17142
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
17134
17143
|
/* @__PURE__ */ jsx(
|
|
17135
17144
|
Input,
|
|
17136
17145
|
{
|
|
17137
17146
|
type: "search",
|
|
17138
17147
|
placeholder: t("common.search"),
|
|
17139
|
-
className: "pl-10 w-full"
|
|
17148
|
+
className: "pl-10 w-full",
|
|
17149
|
+
onKeyDown: (e) => {
|
|
17150
|
+
if (e.key === "Enter") {
|
|
17151
|
+
handleSearchSubmit(e.target.value);
|
|
17152
|
+
}
|
|
17153
|
+
}
|
|
17140
17154
|
}
|
|
17141
17155
|
)
|
|
17142
17156
|
] }) }),
|
|
17143
17157
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
17144
17158
|
headerActions,
|
|
17145
|
-
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
17146
|
-
/* @__PURE__ */ jsxs(
|
|
17159
|
+
showThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
17160
|
+
notificationsEnabled && /* @__PURE__ */ jsxs(
|
|
17147
17161
|
Button,
|
|
17148
17162
|
{
|
|
17149
17163
|
variant: "ghost",
|
|
17150
17164
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
17165
|
+
onClick: handleNotificationClick,
|
|
17166
|
+
"aria-label": t("common.notifications"),
|
|
17151
17167
|
children: [
|
|
17152
17168
|
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
17153
|
-
/* @__PURE__ */ jsx(
|
|
17169
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
17154
17170
|
Box,
|
|
17155
17171
|
{
|
|
17156
17172
|
as: "span",
|
|
17157
|
-
className: "absolute top-
|
|
17173
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
17174
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
17158
17175
|
}
|
|
17159
17176
|
)
|
|
17160
17177
|
]
|
|
@@ -17219,17 +17236,6 @@ var init_DashboardLayout = __esm({
|
|
|
17219
17236
|
}
|
|
17220
17237
|
)
|
|
17221
17238
|
] }),
|
|
17222
|
-
/* @__PURE__ */ jsxs(
|
|
17223
|
-
Link,
|
|
17224
|
-
{
|
|
17225
|
-
to: "/settings",
|
|
17226
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
17227
|
-
children: [
|
|
17228
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }),
|
|
17229
|
-
t("common.settings")
|
|
17230
|
-
]
|
|
17231
|
-
}
|
|
17232
|
-
),
|
|
17233
17239
|
/* @__PURE__ */ jsxs(
|
|
17234
17240
|
Button,
|
|
17235
17241
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { LucideIcon } from "lucide-react";
|
|
3
|
+
import type { EventEmit } from "@almadar/core";
|
|
3
4
|
export interface NavItem {
|
|
4
5
|
label: string;
|
|
5
6
|
href: string;
|
|
@@ -8,12 +9,24 @@ export interface NavItem {
|
|
|
8
9
|
badge?: string | number;
|
|
9
10
|
children?: NavItem[];
|
|
10
11
|
}
|
|
12
|
+
export interface NotificationItem {
|
|
13
|
+
id: string;
|
|
14
|
+
/** Short label shown in the dropdown row. */
|
|
15
|
+
message: string;
|
|
16
|
+
/** Optional secondary text. */
|
|
17
|
+
description?: string;
|
|
18
|
+
/** Optional ISO timestamp string. */
|
|
19
|
+
createdAt?: string;
|
|
20
|
+
/** Optional flag — bell badge counts items where read !== true. */
|
|
21
|
+
read?: boolean;
|
|
22
|
+
}
|
|
11
23
|
export interface DashboardLayoutProps {
|
|
12
24
|
/** App name shown in sidebar */
|
|
13
25
|
appName?: string;
|
|
14
26
|
/** Logo component or URL */
|
|
15
27
|
logo?: React.ReactNode;
|
|
16
|
-
/** Navigation items
|
|
28
|
+
/** Navigation items. Apps that need a Settings page should add it
|
|
29
|
+
* as a navItems entry, not depend on baked-in chrome. */
|
|
17
30
|
navItems?: NavItem[];
|
|
18
31
|
/** Current user info (optional - auto-populated from auth context if not provided) */
|
|
19
32
|
user?: {
|
|
@@ -21,11 +34,34 @@ export interface DashboardLayoutProps {
|
|
|
21
34
|
email: string;
|
|
22
35
|
avatar?: string;
|
|
23
36
|
};
|
|
24
|
-
/** Header actions (
|
|
37
|
+
/** Header actions (extra slots beyond bell/search/theme). */
|
|
25
38
|
headerActions?: React.ReactNode;
|
|
26
|
-
/** Show search in
|
|
39
|
+
/** Show the top-bar search box. Default `false` — opt in by setting
|
|
40
|
+
* `searchEvent` (any truthy value implies showSearch) or this flag. */
|
|
27
41
|
showSearch?: boolean;
|
|
28
|
-
/**
|
|
42
|
+
/** Declarative search event — fires `UI:{searchEvent}` on the bus
|
|
43
|
+
* when the user submits the search box (Enter key). Setting this
|
|
44
|
+
* implies `showSearch=true`. Use `onSearchSubmit` for direct React
|
|
45
|
+
* usage instead. */
|
|
46
|
+
searchEvent?: EventEmit<{
|
|
47
|
+
value: string;
|
|
48
|
+
}>;
|
|
49
|
+
/** React-side search submit callback. Used when the host wires the
|
|
50
|
+
* layout directly (not via render-ui pattern resolution). */
|
|
51
|
+
onSearchSubmit?: (value: string) => void;
|
|
52
|
+
/** Notification list. Pass an empty array to show the bell with no
|
|
53
|
+
* badge; omit / pass null to hide the bell entirely. */
|
|
54
|
+
notifications?: NotificationItem[] | null;
|
|
55
|
+
/** Declarative bell click event — fires `UI:{notificationClickEvent}`
|
|
56
|
+
* on the bus with an empty payload when the user clicks the bell. */
|
|
57
|
+
notificationClickEvent?: EventEmit<Record<string, never>>;
|
|
58
|
+
/** React-side bell click callback. */
|
|
59
|
+
onNotificationClick?: () => void;
|
|
60
|
+
/** Show the theme toggle button in the header. Default `true` —
|
|
61
|
+
* universally useful for a11y / dark mode. */
|
|
62
|
+
showThemeToggle?: boolean;
|
|
63
|
+
/** Custom sidebar footer (optional). When omitted, the sidebar has
|
|
64
|
+
* no footer — apps that need Settings/etc. add them via navItems. */
|
|
29
65
|
sidebarFooter?: React.ReactNode;
|
|
30
66
|
/** Callback when user clicks sign out (optional - uses auth context signOut if not provided) */
|
|
31
67
|
onSignOut?: () => void;
|
package/dist/providers/index.cjs
CHANGED
|
@@ -18368,6 +18368,7 @@ var init_DashboardLayout = __esm({
|
|
|
18368
18368
|
init_Typography();
|
|
18369
18369
|
init_Icon();
|
|
18370
18370
|
init_useAuthContext();
|
|
18371
|
+
init_useEventBus();
|
|
18371
18372
|
init_useTranslate();
|
|
18372
18373
|
DashboardLayout = ({
|
|
18373
18374
|
appName = "{{APP_TITLE}}",
|
|
@@ -18375,11 +18376,29 @@ var init_DashboardLayout = __esm({
|
|
|
18375
18376
|
navItems = [],
|
|
18376
18377
|
user: userProp,
|
|
18377
18378
|
headerActions,
|
|
18378
|
-
showSearch =
|
|
18379
|
+
showSearch = false,
|
|
18380
|
+
searchEvent,
|
|
18381
|
+
onSearchSubmit,
|
|
18382
|
+
notifications,
|
|
18383
|
+
notificationClickEvent,
|
|
18384
|
+
onNotificationClick,
|
|
18385
|
+
showThemeToggle = true,
|
|
18379
18386
|
sidebarFooter,
|
|
18380
18387
|
onSignOut: onSignOutProp,
|
|
18381
18388
|
children
|
|
18382
18389
|
}) => {
|
|
18390
|
+
const eventBus = useEventBus();
|
|
18391
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
18392
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
18393
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
18394
|
+
const handleSearchSubmit = (value) => {
|
|
18395
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
18396
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
18397
|
+
};
|
|
18398
|
+
const handleNotificationClick = () => {
|
|
18399
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
18400
|
+
if (onNotificationClick) onNotificationClick();
|
|
18401
|
+
};
|
|
18383
18402
|
const [sidebarOpen, setSidebarOpen] = React115.useState(false);
|
|
18384
18403
|
const [userMenuOpen, setUserMenuOpen] = React115.useState(false);
|
|
18385
18404
|
const location = reactRouterDom.useLocation();
|
|
@@ -18460,17 +18479,7 @@ var init_DashboardLayout = __esm({
|
|
|
18460
18479
|
))
|
|
18461
18480
|
}
|
|
18462
18481
|
),
|
|
18463
|
-
sidebarFooter
|
|
18464
|
-
reactRouterDom.Link,
|
|
18465
|
-
{
|
|
18466
|
-
to: "/settings",
|
|
18467
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
18468
|
-
children: [
|
|
18469
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-5 w-5" }),
|
|
18470
|
-
t("common.settings")
|
|
18471
|
-
]
|
|
18472
|
-
}
|
|
18473
|
-
) })
|
|
18482
|
+
sidebarFooter && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
18474
18483
|
]
|
|
18475
18484
|
}
|
|
18476
18485
|
),
|
|
@@ -18497,32 +18506,40 @@ var init_DashboardLayout = __esm({
|
|
|
18497
18506
|
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Menu, { className: "h-5 w-5" })
|
|
18498
18507
|
}
|
|
18499
18508
|
),
|
|
18500
|
-
|
|
18509
|
+
searchEnabled && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
|
|
18501
18510
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
18502
18511
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18503
18512
|
Input,
|
|
18504
18513
|
{
|
|
18505
18514
|
type: "search",
|
|
18506
18515
|
placeholder: t("common.search"),
|
|
18507
|
-
className: "pl-10 w-full"
|
|
18516
|
+
className: "pl-10 w-full",
|
|
18517
|
+
onKeyDown: (e) => {
|
|
18518
|
+
if (e.key === "Enter") {
|
|
18519
|
+
handleSearchSubmit(e.target.value);
|
|
18520
|
+
}
|
|
18521
|
+
}
|
|
18508
18522
|
}
|
|
18509
18523
|
)
|
|
18510
18524
|
] }) }),
|
|
18511
18525
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
18512
18526
|
headerActions,
|
|
18513
|
-
/* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
18514
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18527
|
+
showThemeToggle && /* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
18528
|
+
notificationsEnabled && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18515
18529
|
Button,
|
|
18516
18530
|
{
|
|
18517
18531
|
variant: "ghost",
|
|
18518
18532
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
18533
|
+
onClick: handleNotificationClick,
|
|
18534
|
+
"aria-label": t("common.notifications"),
|
|
18519
18535
|
children: [
|
|
18520
18536
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
18521
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18537
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18522
18538
|
Box,
|
|
18523
18539
|
{
|
|
18524
18540
|
as: "span",
|
|
18525
|
-
className: "absolute top-
|
|
18541
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
18542
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
18526
18543
|
}
|
|
18527
18544
|
)
|
|
18528
18545
|
]
|
|
@@ -18587,17 +18604,6 @@ var init_DashboardLayout = __esm({
|
|
|
18587
18604
|
}
|
|
18588
18605
|
)
|
|
18589
18606
|
] }),
|
|
18590
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18591
|
-
reactRouterDom.Link,
|
|
18592
|
-
{
|
|
18593
|
-
to: "/settings",
|
|
18594
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
18595
|
-
children: [
|
|
18596
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-4 w-4" }),
|
|
18597
|
-
t("common.settings")
|
|
18598
|
-
]
|
|
18599
|
-
}
|
|
18600
|
-
),
|
|
18601
18607
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18602
18608
|
Button,
|
|
18603
18609
|
{
|
package/dist/providers/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/
|
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import * as LucideIcons from 'lucide-react';
|
|
8
|
-
import { X, AlertTriangle, Info, AlertCircle, CheckCircle, Loader2, List, Printer, ChevronRight, ChevronLeft, Check, Copy, Code, FileText, WrapText, Trash2,
|
|
8
|
+
import { X, AlertTriangle, Info, AlertCircle, CheckCircle, Loader2, List, Printer, ChevronRight, ChevronLeft, Check, Copy, Code, FileText, WrapText, Trash2, Menu as Menu$1, Search, Bell, ChevronDown, LogOut, ZoomOut, ZoomIn, Download, FileQuestion, Inbox, XCircle, Filter, Plus, Pause, Play, RotateCcw, Package, Calendar, Pencil, Eye, MoreHorizontal, Image as Image$1, Upload, Minus, ArrowLeft, HelpCircle, ChevronUp, Eraser, Star, TrendingUp, TrendingDown, ArrowUp, ArrowDown, MoreVertical, Sun, Moon, Circle, Clock, CheckCircle2, ArrowRight, FileWarning, SkipForward, Bug, Send, Wrench, User, Tag, DollarSign, Zap, Sword, Move, Heart, Shield } from 'lucide-react';
|
|
9
9
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
10
10
|
import { useUISlots } from '@almadar/ui/context';
|
|
11
11
|
import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
|
|
@@ -18323,6 +18323,7 @@ var init_DashboardLayout = __esm({
|
|
|
18323
18323
|
init_Typography();
|
|
18324
18324
|
init_Icon();
|
|
18325
18325
|
init_useAuthContext();
|
|
18326
|
+
init_useEventBus();
|
|
18326
18327
|
init_useTranslate();
|
|
18327
18328
|
DashboardLayout = ({
|
|
18328
18329
|
appName = "{{APP_TITLE}}",
|
|
@@ -18330,11 +18331,29 @@ var init_DashboardLayout = __esm({
|
|
|
18330
18331
|
navItems = [],
|
|
18331
18332
|
user: userProp,
|
|
18332
18333
|
headerActions,
|
|
18333
|
-
showSearch =
|
|
18334
|
+
showSearch = false,
|
|
18335
|
+
searchEvent,
|
|
18336
|
+
onSearchSubmit,
|
|
18337
|
+
notifications,
|
|
18338
|
+
notificationClickEvent,
|
|
18339
|
+
onNotificationClick,
|
|
18340
|
+
showThemeToggle = true,
|
|
18334
18341
|
sidebarFooter,
|
|
18335
18342
|
onSignOut: onSignOutProp,
|
|
18336
18343
|
children
|
|
18337
18344
|
}) => {
|
|
18345
|
+
const eventBus = useEventBus();
|
|
18346
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
18347
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
18348
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
18349
|
+
const handleSearchSubmit = (value) => {
|
|
18350
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
18351
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
18352
|
+
};
|
|
18353
|
+
const handleNotificationClick = () => {
|
|
18354
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
18355
|
+
if (onNotificationClick) onNotificationClick();
|
|
18356
|
+
};
|
|
18338
18357
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
18339
18358
|
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
|
18340
18359
|
const location = useLocation();
|
|
@@ -18415,17 +18434,7 @@ var init_DashboardLayout = __esm({
|
|
|
18415
18434
|
))
|
|
18416
18435
|
}
|
|
18417
18436
|
),
|
|
18418
|
-
sidebarFooter
|
|
18419
|
-
Link,
|
|
18420
|
-
{
|
|
18421
|
-
to: "/settings",
|
|
18422
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
18423
|
-
children: [
|
|
18424
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-5 w-5" }),
|
|
18425
|
-
t("common.settings")
|
|
18426
|
-
]
|
|
18427
|
-
}
|
|
18428
|
-
) })
|
|
18437
|
+
sidebarFooter && /* @__PURE__ */ jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
18429
18438
|
]
|
|
18430
18439
|
}
|
|
18431
18440
|
),
|
|
@@ -18452,32 +18461,40 @@ var init_DashboardLayout = __esm({
|
|
|
18452
18461
|
children: /* @__PURE__ */ jsx(Menu$1, { className: "h-5 w-5" })
|
|
18453
18462
|
}
|
|
18454
18463
|
),
|
|
18455
|
-
|
|
18464
|
+
searchEnabled && /* @__PURE__ */ jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
|
|
18456
18465
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
18457
18466
|
/* @__PURE__ */ jsx(
|
|
18458
18467
|
Input,
|
|
18459
18468
|
{
|
|
18460
18469
|
type: "search",
|
|
18461
18470
|
placeholder: t("common.search"),
|
|
18462
|
-
className: "pl-10 w-full"
|
|
18471
|
+
className: "pl-10 w-full",
|
|
18472
|
+
onKeyDown: (e) => {
|
|
18473
|
+
if (e.key === "Enter") {
|
|
18474
|
+
handleSearchSubmit(e.target.value);
|
|
18475
|
+
}
|
|
18476
|
+
}
|
|
18463
18477
|
}
|
|
18464
18478
|
)
|
|
18465
18479
|
] }) }),
|
|
18466
18480
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
18467
18481
|
headerActions,
|
|
18468
|
-
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
18469
|
-
/* @__PURE__ */ jsxs(
|
|
18482
|
+
showThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
18483
|
+
notificationsEnabled && /* @__PURE__ */ jsxs(
|
|
18470
18484
|
Button,
|
|
18471
18485
|
{
|
|
18472
18486
|
variant: "ghost",
|
|
18473
18487
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
18488
|
+
onClick: handleNotificationClick,
|
|
18489
|
+
"aria-label": t("common.notifications"),
|
|
18474
18490
|
children: [
|
|
18475
18491
|
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
18476
|
-
/* @__PURE__ */ jsx(
|
|
18492
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
18477
18493
|
Box,
|
|
18478
18494
|
{
|
|
18479
18495
|
as: "span",
|
|
18480
|
-
className: "absolute top-
|
|
18496
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
18497
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
18481
18498
|
}
|
|
18482
18499
|
)
|
|
18483
18500
|
]
|
|
@@ -18542,17 +18559,6 @@ var init_DashboardLayout = __esm({
|
|
|
18542
18559
|
}
|
|
18543
18560
|
)
|
|
18544
18561
|
] }),
|
|
18545
|
-
/* @__PURE__ */ jsxs(
|
|
18546
|
-
Link,
|
|
18547
|
-
{
|
|
18548
|
-
to: "/settings",
|
|
18549
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
18550
|
-
children: [
|
|
18551
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }),
|
|
18552
|
-
t("common.settings")
|
|
18553
|
-
]
|
|
18554
|
-
}
|
|
18555
|
-
),
|
|
18556
18562
|
/* @__PURE__ */ jsxs(
|
|
18557
18563
|
Button,
|
|
18558
18564
|
{
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -18144,6 +18144,7 @@ var init_DashboardLayout = __esm({
|
|
|
18144
18144
|
init_Typography();
|
|
18145
18145
|
init_Icon();
|
|
18146
18146
|
init_useAuthContext();
|
|
18147
|
+
init_useEventBus();
|
|
18147
18148
|
init_useTranslate();
|
|
18148
18149
|
DashboardLayout = ({
|
|
18149
18150
|
appName = "{{APP_TITLE}}",
|
|
@@ -18151,11 +18152,29 @@ var init_DashboardLayout = __esm({
|
|
|
18151
18152
|
navItems = [],
|
|
18152
18153
|
user: userProp,
|
|
18153
18154
|
headerActions,
|
|
18154
|
-
showSearch =
|
|
18155
|
+
showSearch = false,
|
|
18156
|
+
searchEvent,
|
|
18157
|
+
onSearchSubmit,
|
|
18158
|
+
notifications,
|
|
18159
|
+
notificationClickEvent,
|
|
18160
|
+
onNotificationClick,
|
|
18161
|
+
showThemeToggle = true,
|
|
18155
18162
|
sidebarFooter,
|
|
18156
18163
|
onSignOut: onSignOutProp,
|
|
18157
18164
|
children
|
|
18158
18165
|
}) => {
|
|
18166
|
+
const eventBus = useEventBus();
|
|
18167
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
18168
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
18169
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
18170
|
+
const handleSearchSubmit = (value) => {
|
|
18171
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
18172
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
18173
|
+
};
|
|
18174
|
+
const handleNotificationClick = () => {
|
|
18175
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
18176
|
+
if (onNotificationClick) onNotificationClick();
|
|
18177
|
+
};
|
|
18159
18178
|
const [sidebarOpen, setSidebarOpen] = React113.useState(false);
|
|
18160
18179
|
const [userMenuOpen, setUserMenuOpen] = React113.useState(false);
|
|
18161
18180
|
const location = reactRouterDom.useLocation();
|
|
@@ -18236,17 +18255,7 @@ var init_DashboardLayout = __esm({
|
|
|
18236
18255
|
))
|
|
18237
18256
|
}
|
|
18238
18257
|
),
|
|
18239
|
-
sidebarFooter
|
|
18240
|
-
reactRouterDom.Link,
|
|
18241
|
-
{
|
|
18242
|
-
to: "/settings",
|
|
18243
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
18244
|
-
children: [
|
|
18245
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-5 w-5" }),
|
|
18246
|
-
t("common.settings")
|
|
18247
|
-
]
|
|
18248
|
-
}
|
|
18249
|
-
) })
|
|
18258
|
+
sidebarFooter && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
18250
18259
|
]
|
|
18251
18260
|
}
|
|
18252
18261
|
),
|
|
@@ -18273,32 +18282,40 @@ var init_DashboardLayout = __esm({
|
|
|
18273
18282
|
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Menu, { className: "h-5 w-5" })
|
|
18274
18283
|
}
|
|
18275
18284
|
),
|
|
18276
|
-
|
|
18285
|
+
searchEnabled && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
|
|
18277
18286
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
18278
18287
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18279
18288
|
Input,
|
|
18280
18289
|
{
|
|
18281
18290
|
type: "search",
|
|
18282
18291
|
placeholder: t("common.search"),
|
|
18283
|
-
className: "pl-10 w-full"
|
|
18292
|
+
className: "pl-10 w-full",
|
|
18293
|
+
onKeyDown: (e) => {
|
|
18294
|
+
if (e.key === "Enter") {
|
|
18295
|
+
handleSearchSubmit(e.target.value);
|
|
18296
|
+
}
|
|
18297
|
+
}
|
|
18284
18298
|
}
|
|
18285
18299
|
)
|
|
18286
18300
|
] }) }),
|
|
18287
18301
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
18288
18302
|
headerActions,
|
|
18289
|
-
/* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
18290
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18303
|
+
showThemeToggle && /* @__PURE__ */ jsxRuntime.jsx(ThemeToggle, {}),
|
|
18304
|
+
notificationsEnabled && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18291
18305
|
Button,
|
|
18292
18306
|
{
|
|
18293
18307
|
variant: "ghost",
|
|
18294
18308
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
18309
|
+
onClick: handleNotificationClick,
|
|
18310
|
+
"aria-label": t("common.notifications"),
|
|
18295
18311
|
children: [
|
|
18296
18312
|
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
18297
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18313
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18298
18314
|
Box,
|
|
18299
18315
|
{
|
|
18300
18316
|
as: "span",
|
|
18301
|
-
className: "absolute top-
|
|
18317
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
18318
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
18302
18319
|
}
|
|
18303
18320
|
)
|
|
18304
18321
|
]
|
|
@@ -18363,17 +18380,6 @@ var init_DashboardLayout = __esm({
|
|
|
18363
18380
|
}
|
|
18364
18381
|
)
|
|
18365
18382
|
] }),
|
|
18366
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18367
|
-
reactRouterDom.Link,
|
|
18368
|
-
{
|
|
18369
|
-
to: "/settings",
|
|
18370
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
18371
|
-
children: [
|
|
18372
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Settings, { className: "h-4 w-4" }),
|
|
18373
|
-
t("common.settings")
|
|
18374
|
-
]
|
|
18375
|
-
}
|
|
18376
|
-
),
|
|
18377
18383
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18378
18384
|
Button,
|
|
18379
18385
|
{
|
package/dist/runtime/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import * as LucideIcons from 'lucide-react';
|
|
8
|
-
import { X, AlertTriangle, Info, AlertCircle, CheckCircle, Loader2, List, Printer, ChevronRight, ChevronLeft, Check, Copy, Code, FileText, WrapText, Trash2,
|
|
8
|
+
import { X, AlertTriangle, Info, AlertCircle, CheckCircle, Loader2, List, Printer, ChevronRight, ChevronLeft, Check, Copy, Code, FileText, WrapText, Trash2, Menu as Menu$1, Search, Bell, ChevronDown, LogOut, ZoomOut, ZoomIn, Download, FileQuestion, Inbox, XCircle, Filter, Plus, Pause, Play, RotateCcw, Package, Calendar, Pencil, Eye, MoreHorizontal, Image as Image$1, Upload, Minus, ArrowLeft, HelpCircle, ChevronUp, Eraser, Star, TrendingUp, TrendingDown, ArrowUp, ArrowDown, MoreVertical, Sun, Moon, Circle, Clock, CheckCircle2, ArrowRight, FileWarning, SkipForward, Bug, Send, Wrench, User, Tag, DollarSign, Zap, Sword, Move, Heart, Shield } from 'lucide-react';
|
|
9
9
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
10
10
|
import { useUISlots, UISlotProvider } from '@almadar/ui/context';
|
|
11
11
|
import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
|
|
@@ -18099,6 +18099,7 @@ var init_DashboardLayout = __esm({
|
|
|
18099
18099
|
init_Typography();
|
|
18100
18100
|
init_Icon();
|
|
18101
18101
|
init_useAuthContext();
|
|
18102
|
+
init_useEventBus();
|
|
18102
18103
|
init_useTranslate();
|
|
18103
18104
|
DashboardLayout = ({
|
|
18104
18105
|
appName = "{{APP_TITLE}}",
|
|
@@ -18106,11 +18107,29 @@ var init_DashboardLayout = __esm({
|
|
|
18106
18107
|
navItems = [],
|
|
18107
18108
|
user: userProp,
|
|
18108
18109
|
headerActions,
|
|
18109
|
-
showSearch =
|
|
18110
|
+
showSearch = false,
|
|
18111
|
+
searchEvent,
|
|
18112
|
+
onSearchSubmit,
|
|
18113
|
+
notifications,
|
|
18114
|
+
notificationClickEvent,
|
|
18115
|
+
onNotificationClick,
|
|
18116
|
+
showThemeToggle = true,
|
|
18110
18117
|
sidebarFooter,
|
|
18111
18118
|
onSignOut: onSignOutProp,
|
|
18112
18119
|
children
|
|
18113
18120
|
}) => {
|
|
18121
|
+
const eventBus = useEventBus();
|
|
18122
|
+
const searchEnabled = showSearch || Boolean(searchEvent) || Boolean(onSearchSubmit);
|
|
18123
|
+
const notificationsEnabled = Array.isArray(notifications);
|
|
18124
|
+
const unreadCount = notificationsEnabled ? notifications.filter((n) => n.read !== true).length : 0;
|
|
18125
|
+
const handleSearchSubmit = (value) => {
|
|
18126
|
+
if (searchEvent) eventBus.emit(`UI:${searchEvent}`, { value });
|
|
18127
|
+
if (onSearchSubmit) onSearchSubmit(value);
|
|
18128
|
+
};
|
|
18129
|
+
const handleNotificationClick = () => {
|
|
18130
|
+
if (notificationClickEvent) eventBus.emit(`UI:${notificationClickEvent}`, {});
|
|
18131
|
+
if (onNotificationClick) onNotificationClick();
|
|
18132
|
+
};
|
|
18114
18133
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
18115
18134
|
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
|
18116
18135
|
const location = useLocation();
|
|
@@ -18191,17 +18210,7 @@ var init_DashboardLayout = __esm({
|
|
|
18191
18210
|
))
|
|
18192
18211
|
}
|
|
18193
18212
|
),
|
|
18194
|
-
sidebarFooter
|
|
18195
|
-
Link,
|
|
18196
|
-
{
|
|
18197
|
-
to: "/settings",
|
|
18198
|
-
className: "flex items-center gap-3 px-3 py-2 text-sm text-muted-foreground dark:text-muted-foreground rounded-lg hover:bg-muted dark:hover:bg-muted",
|
|
18199
|
-
children: [
|
|
18200
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-5 w-5" }),
|
|
18201
|
-
t("common.settings")
|
|
18202
|
-
]
|
|
18203
|
-
}
|
|
18204
|
-
) })
|
|
18213
|
+
sidebarFooter && /* @__PURE__ */ jsx(Box, { className: "p-4 border-t border-border dark:border-border", children: sidebarFooter })
|
|
18205
18214
|
]
|
|
18206
18215
|
}
|
|
18207
18216
|
),
|
|
@@ -18228,32 +18237,40 @@ var init_DashboardLayout = __esm({
|
|
|
18228
18237
|
children: /* @__PURE__ */ jsx(Menu$1, { className: "h-5 w-5" })
|
|
18229
18238
|
}
|
|
18230
18239
|
),
|
|
18231
|
-
|
|
18240
|
+
searchEnabled && /* @__PURE__ */ jsx(Box, { className: "hidden sm:block flex-1 max-w-md", children: /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
|
|
18232
18241
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground dark:text-muted-foreground" }),
|
|
18233
18242
|
/* @__PURE__ */ jsx(
|
|
18234
18243
|
Input,
|
|
18235
18244
|
{
|
|
18236
18245
|
type: "search",
|
|
18237
18246
|
placeholder: t("common.search"),
|
|
18238
|
-
className: "pl-10 w-full"
|
|
18247
|
+
className: "pl-10 w-full",
|
|
18248
|
+
onKeyDown: (e) => {
|
|
18249
|
+
if (e.key === "Enter") {
|
|
18250
|
+
handleSearchSubmit(e.target.value);
|
|
18251
|
+
}
|
|
18252
|
+
}
|
|
18239
18253
|
}
|
|
18240
18254
|
)
|
|
18241
18255
|
] }) }),
|
|
18242
18256
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "xs", children: [
|
|
18243
18257
|
headerActions,
|
|
18244
|
-
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
18245
|
-
/* @__PURE__ */ jsxs(
|
|
18258
|
+
showThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
18259
|
+
notificationsEnabled && /* @__PURE__ */ jsxs(
|
|
18246
18260
|
Button,
|
|
18247
18261
|
{
|
|
18248
18262
|
variant: "ghost",
|
|
18249
18263
|
className: "relative p-2 rounded-full hover:bg-muted dark:hover:bg-muted",
|
|
18264
|
+
onClick: handleNotificationClick,
|
|
18265
|
+
"aria-label": t("common.notifications"),
|
|
18250
18266
|
children: [
|
|
18251
18267
|
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground dark:text-muted-foreground" }),
|
|
18252
|
-
/* @__PURE__ */ jsx(
|
|
18268
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
18253
18269
|
Box,
|
|
18254
18270
|
{
|
|
18255
18271
|
as: "span",
|
|
18256
|
-
className: "absolute top-
|
|
18272
|
+
className: "absolute -top-0.5 -right-0.5 min-w-[18px] h-[18px] px-1 bg-error rounded-full text-[10px] font-semibold text-white flex items-center justify-center",
|
|
18273
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
18257
18274
|
}
|
|
18258
18275
|
)
|
|
18259
18276
|
]
|
|
@@ -18318,17 +18335,6 @@ var init_DashboardLayout = __esm({
|
|
|
18318
18335
|
}
|
|
18319
18336
|
)
|
|
18320
18337
|
] }),
|
|
18321
|
-
/* @__PURE__ */ jsxs(
|
|
18322
|
-
Link,
|
|
18323
|
-
{
|
|
18324
|
-
to: "/settings",
|
|
18325
|
-
className: "flex items-center gap-2 px-4 py-2 text-sm text-foreground dark:text-foreground hover:bg-muted dark:hover:bg-muted",
|
|
18326
|
-
children: [
|
|
18327
|
-
/* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }),
|
|
18328
|
-
t("common.settings")
|
|
18329
|
-
]
|
|
18330
|
-
}
|
|
18331
|
-
),
|
|
18332
18338
|
/* @__PURE__ */ jsxs(
|
|
18333
18339
|
Button,
|
|
18334
18340
|
{
|