@fluxo-dev/shell 26.3.6 → 26.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/index.esm.js CHANGED
@@ -3,15 +3,15 @@ import * as React from 'react';
3
3
  import React__default, { forwardRef, createElement as createElement$2, useState, useEffect, Suspense, useRef, useCallback as useCallback$1, useContext, useMemo as useMemo$1, createContext, useLayoutEffect, memo, isValidElement, cloneElement, useImperativeHandle } from 'react';
4
4
  import { useSelector, connect, Provider } from 'react-redux';
5
5
  import { useRouteError, useNavigate, Navigate, Outlet, useLocation, Link, useOutlet, matchPath, useSearchParams, createBrowserRouter, RouterProvider } from 'react-router-dom';
6
- import { Center, Card, Stack, Text, Button, Box, TextInput, Popover, UnstyledButton, Group, Highlight, Modal, ActionIcon, useMantineTheme, AppShell, Burger, Badge, Tooltip, Drawer, NavLink, Avatar, Divider, FocusTrap, Tabs, ScrollArea, ThemeIcon, Anchor, Space, useMantineColorScheme, Collapse, Menu, rem, Loader, Overlay, Grid, PasswordInput, Paper, Alert, Title, ColorSwatch, FileButton, NumberInput, ColorInput, Checkbox, Switch, Select, Radio, LoadingOverlay, Chip, Image as Image$1, Table, SegmentedControl, MultiSelect, Code, Portal, useDirection, px as px$1, parseThemeColor, rgba as rgba$1, Breadcrumbs, TagsInput, Textarea, Accordion, MantineProvider } from '@mantine/core';
7
- import { ShellSessionContext, DataCard, useFlxNavigate, SessionIdContext, TabActiveContext, IconFactory, useSuggestions, useFrontendTool, useHumanInTheLoop, ApprovalRequestCard, useBackendToolRenderer, AiChatPanel, ShellSessionProvider, ShellConfigProvider, AgentProvider, useShellLayout, ShellPage, NoData, ConfirmModal, CronGenerator, Datagrid, SlidingPanel, usePromptTemplates, useSkills, RichTextEditorInput, useFlxSessionTitle, ErrorPage as ErrorPage$1, WaitData } from '@fluxo-dev/ui-components';
6
+ import { Center, Card, Stack, Text, Button, Box, TextInput, Popover, UnstyledButton, Group, Highlight, Modal, ActionIcon, useMantineTheme, AppShell, Burger, Badge, Tooltip, Drawer, NavLink, Avatar, Divider, FocusTrap, Tabs, ScrollArea, ThemeIcon, Anchor, Space, useMantineColorScheme, Collapse, Menu, rem, Loader, Overlay, Paper, Alert, PasswordInput, Grid, Title, ColorSwatch, FileButton, NumberInput, ColorInput, Checkbox, Switch, Select, Radio, LoadingOverlay, Image as Image$1, Table, SegmentedControl, MultiSelect, Code, Portal, useDirection, px as px$1, parseThemeColor, rgba as rgba$1, Breadcrumbs, TagsInput, Textarea, Accordion, MantineProvider } from '@mantine/core';
7
+ import { useShellLayout, ShellSessionContext, DataCard, useFlxNavigate, SessionIdContext, TabActiveContext, IconFactory, useSuggestions, useFrontendTool, useHumanInTheLoop, ApprovalRequestCard, useBackendToolRenderer, AiChatPanel, AgentProvider, ShellSessionProvider, ShellConfigProvider, ShellPage, NoData, ConfirmModal, CronGenerator, Datagrid, SlidingPanel, usePromptTemplates, useSkills, RichTextEditorInput, useFlxSessionTitle, ErrorPage as ErrorPage$1, WaitData } from '@fluxo-dev/ui-components';
8
8
  import { ModuleLoader } from '@fluxo-dev/shell-mfe';
9
- import { MinimalStateViewer, RavifyProvider, JobsViewer } from '@fluxo-dev/shell-ravify';
10
9
  import { useAppSelector, store as store$4 } from '@fluxo-dev/state';
11
10
  import { openSpotlight, Spotlight, spotlight } from '@mantine/spotlight';
12
11
  import { useOs, useMediaQuery, useHotkeys, useDocumentTitle, useIdle, useWindowEvent, useResizeObserver, useTimeout, useDisclosure } from '@mantine/hooks';
13
12
  import { AppState, AppType, FluxoStateDispatcher, FluxoClientSys, DeviceIdManager, ApiKeyService, UserService, AppMenuContextType, DomainRoleService, FluxoACLMode, NewUserAccessType, EmailServerProviderType, RavifyInstanceProtocol, RavifyInstanceVersion, LlmProvider, McpServerTransport, McpServerAuthType, AiSkillScriptLanguage, AiSkillScriptRunner, WorkflowPattern, EmailTemplateType } from '@fluxo-dev/api-client-base';
14
13
  import { showNotification, notifications, Notifications } from '@mantine/notifications';
14
+ import { MinimalStateViewer, RavifyProvider, JobsViewer } from '@fluxo-dev/shell-ravify';
15
15
  import { useForm } from '@mantine/form';
16
16
  import QRCode from 'qrcode';
17
17
  import { DatePickerInput, DatesProvider } from '@mantine/dates';
@@ -4083,8 +4083,8 @@ const createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
4083
4083
  */
4084
4084
 
4085
4085
 
4086
- const __iconNode$1H = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4087
- const IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode$1H);
4086
+ const __iconNode$1J = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4087
+ const IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode$1J);
4088
4088
 
4089
4089
  /**
4090
4090
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4094,8 +4094,8 @@ const IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCi
4094
4094
  */
4095
4095
 
4096
4096
 
4097
- const __iconNode$1G = [["path", { "d": "M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0z", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4098
- const IconAlertOctagon = createReactComponent("outline", "alert-octagon", "AlertOctagon", __iconNode$1G);
4097
+ const __iconNode$1I = [["path", { "d": "M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0z", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4098
+ const IconAlertOctagon = createReactComponent("outline", "alert-octagon", "AlertOctagon", __iconNode$1I);
4099
4099
 
4100
4100
  /**
4101
4101
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4105,8 +4105,8 @@ const IconAlertOctagon = createReactComponent("outline", "alert-octagon", "Alert
4105
4105
  */
4106
4106
 
4107
4107
 
4108
- const __iconNode$1F = [["path", { "d": "M12 9v4", "key": "svg-0" }], ["path", { "d": "M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4109
- const IconAlertTriangle = createReactComponent("outline", "alert-triangle", "AlertTriangle", __iconNode$1F);
4108
+ const __iconNode$1H = [["path", { "d": "M12 9v4", "key": "svg-0" }], ["path", { "d": "M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
4109
+ const IconAlertTriangle = createReactComponent("outline", "alert-triangle", "AlertTriangle", __iconNode$1H);
4110
4110
 
4111
4111
  /**
4112
4112
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4116,8 +4116,8 @@ const IconAlertTriangle = createReactComponent("outline", "alert-triangle", "Ale
4116
4116
  */
4117
4117
 
4118
4118
 
4119
- const __iconNode$1E = [["path", { "d": "M4 13h5", "key": "svg-0" }], ["path", { "d": "M12 16v-8h3a2 2 0 0 1 2 2v1a2 2 0 0 1 -2 2h-3", "key": "svg-1" }], ["path", { "d": "M20 8v8", "key": "svg-2" }], ["path", { "d": "M9 16v-5.5a2.5 2.5 0 0 0 -5 0v5.5", "key": "svg-3" }]];
4120
- const IconApi = createReactComponent("outline", "api", "Api", __iconNode$1E);
4119
+ const __iconNode$1G = [["path", { "d": "M4 13h5", "key": "svg-0" }], ["path", { "d": "M12 16v-8h3a2 2 0 0 1 2 2v1a2 2 0 0 1 -2 2h-3", "key": "svg-1" }], ["path", { "d": "M20 8v8", "key": "svg-2" }], ["path", { "d": "M9 16v-5.5a2.5 2.5 0 0 0 -5 0v5.5", "key": "svg-3" }]];
4120
+ const IconApi = createReactComponent("outline", "api", "Api", __iconNode$1G);
4121
4121
 
4122
4122
  /**
4123
4123
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4127,8 +4127,8 @@ const IconApi = createReactComponent("outline", "api", "Api", __iconNode$1E);
4127
4127
  */
4128
4128
 
4129
4129
 
4130
- const __iconNode$1D = [["path", { "d": "M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-0" }], ["path", { "d": "M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-1" }], ["path", { "d": "M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-2" }], ["path", { "d": "M14 7l6 0", "key": "svg-3" }], ["path", { "d": "M17 4l0 6", "key": "svg-4" }]];
4131
- const IconApps = createReactComponent("outline", "apps", "Apps", __iconNode$1D);
4130
+ const __iconNode$1F = [["path", { "d": "M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-0" }], ["path", { "d": "M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-1" }], ["path", { "d": "M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z", "key": "svg-2" }], ["path", { "d": "M14 7l6 0", "key": "svg-3" }], ["path", { "d": "M17 4l0 6", "key": "svg-4" }]];
4131
+ const IconApps = createReactComponent("outline", "apps", "Apps", __iconNode$1F);
4132
4132
 
4133
4133
  /**
4134
4134
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4138,8 +4138,8 @@ const IconApps = createReactComponent("outline", "apps", "Apps", __iconNode$1D);
4138
4138
  */
4139
4139
 
4140
4140
 
4141
- const __iconNode$1C = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M18 13l-6 6", "key": "svg-1" }], ["path", { "d": "M6 13l6 6", "key": "svg-2" }]];
4142
- const IconArrowDown = createReactComponent("outline", "arrow-down", "ArrowDown", __iconNode$1C);
4141
+ const __iconNode$1E = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M18 13l-6 6", "key": "svg-1" }], ["path", { "d": "M6 13l6 6", "key": "svg-2" }]];
4142
+ const IconArrowDown = createReactComponent("outline", "arrow-down", "ArrowDown", __iconNode$1E);
4143
4143
 
4144
4144
  /**
4145
4145
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4149,8 +4149,8 @@ const IconArrowDown = createReactComponent("outline", "arrow-down", "ArrowDown",
4149
4149
  */
4150
4150
 
4151
4151
 
4152
- const __iconNode$1B = [["path", { "d": "M5 12l14 0", "key": "svg-0" }], ["path", { "d": "M5 12l6 6", "key": "svg-1" }], ["path", { "d": "M5 12l6 -6", "key": "svg-2" }]];
4153
- const IconArrowLeft = createReactComponent("outline", "arrow-left", "ArrowLeft", __iconNode$1B);
4152
+ const __iconNode$1D = [["path", { "d": "M5 12l14 0", "key": "svg-0" }], ["path", { "d": "M5 12l6 6", "key": "svg-1" }], ["path", { "d": "M5 12l6 -6", "key": "svg-2" }]];
4153
+ const IconArrowLeft = createReactComponent("outline", "arrow-left", "ArrowLeft", __iconNode$1D);
4154
4154
 
4155
4155
  /**
4156
4156
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4160,8 +4160,8 @@ const IconArrowLeft = createReactComponent("outline", "arrow-left", "ArrowLeft",
4160
4160
  */
4161
4161
 
4162
4162
 
4163
- const __iconNode$1A = [["path", { "d": "M5 12l14 0", "key": "svg-0" }], ["path", { "d": "M13 18l6 -6", "key": "svg-1" }], ["path", { "d": "M13 6l6 6", "key": "svg-2" }]];
4164
- const IconArrowRight = createReactComponent("outline", "arrow-right", "ArrowRight", __iconNode$1A);
4163
+ const __iconNode$1C = [["path", { "d": "M5 12l14 0", "key": "svg-0" }], ["path", { "d": "M13 18l6 -6", "key": "svg-1" }], ["path", { "d": "M13 6l6 6", "key": "svg-2" }]];
4164
+ const IconArrowRight = createReactComponent("outline", "arrow-right", "ArrowRight", __iconNode$1C);
4165
4165
 
4166
4166
  /**
4167
4167
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4171,8 +4171,8 @@ const IconArrowRight = createReactComponent("outline", "arrow-right", "ArrowRigh
4171
4171
  */
4172
4172
 
4173
4173
 
4174
- const __iconNode$1z = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M18 11l-6 -6", "key": "svg-1" }], ["path", { "d": "M6 11l6 -6", "key": "svg-2" }]];
4175
- const IconArrowUp = createReactComponent("outline", "arrow-up", "ArrowUp", __iconNode$1z);
4174
+ const __iconNode$1B = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M18 11l-6 -6", "key": "svg-1" }], ["path", { "d": "M6 11l6 -6", "key": "svg-2" }]];
4175
+ const IconArrowUp = createReactComponent("outline", "arrow-up", "ArrowUp", __iconNode$1B);
4176
4176
 
4177
4177
  /**
4178
4178
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4182,8 +4182,8 @@ const IconArrowUp = createReactComponent("outline", "arrow-up", "ArrowUp", __ico
4182
4182
  */
4183
4183
 
4184
4184
 
4185
- const __iconNode$1y = [["path", { "d": "M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", "key": "svg-0" }], ["path", { "d": "M16 12v1.5a2.5 2.5 0 0 0 5 0v-1.5a9 9 0 1 0 -5.5 8.28", "key": "svg-1" }]];
4186
- const IconAt = createReactComponent("outline", "at", "At", __iconNode$1y);
4185
+ const __iconNode$1A = [["path", { "d": "M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", "key": "svg-0" }], ["path", { "d": "M16 12v1.5a2.5 2.5 0 0 0 5 0v-1.5a9 9 0 1 0 -5.5 8.28", "key": "svg-1" }]];
4186
+ const IconAt = createReactComponent("outline", "at", "At", __iconNode$1A);
4187
4187
 
4188
4188
  /**
4189
4189
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4193,8 +4193,8 @@ const IconAt = createReactComponent("outline", "at", "At", __iconNode$1y);
4193
4193
  */
4194
4194
 
4195
4195
 
4196
- const __iconNode$1x = [["path", { "d": "M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6", "key": "svg-0" }], ["path", { "d": "M9 17v1a3 3 0 0 0 6 0v-1", "key": "svg-1" }]];
4197
- const IconBell = createReactComponent("outline", "bell", "Bell", __iconNode$1x);
4196
+ const __iconNode$1z = [["path", { "d": "M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6", "key": "svg-0" }], ["path", { "d": "M9 17v1a3 3 0 0 0 6 0v-1", "key": "svg-1" }]];
4197
+ const IconBell = createReactComponent("outline", "bell", "Bell", __iconNode$1z);
4198
4198
 
4199
4199
  /**
4200
4200
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4204,8 +4204,8 @@ const IconBell = createReactComponent("outline", "bell", "Bell", __iconNode$1x);
4204
4204
  */
4205
4205
 
4206
4206
 
4207
- const __iconNode$1w = [["path", { "d": "M8 8h8v8h-8z", "key": "svg-0" }], ["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-1" }], ["path", { "d": "M16 16l3.3 3.3", "key": "svg-2" }], ["path", { "d": "M16 8l3.3 -3.3", "key": "svg-3" }], ["path", { "d": "M8 8l-3.3 -3.3", "key": "svg-4" }], ["path", { "d": "M8 16l-3.3 3.3", "key": "svg-5" }]];
4208
- const IconBoxModel = createReactComponent("outline", "box-model", "BoxModel", __iconNode$1w);
4207
+ const __iconNode$1y = [["path", { "d": "M8 8h8v8h-8z", "key": "svg-0" }], ["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-1" }], ["path", { "d": "M16 16l3.3 3.3", "key": "svg-2" }], ["path", { "d": "M16 8l3.3 -3.3", "key": "svg-3" }], ["path", { "d": "M8 8l-3.3 -3.3", "key": "svg-4" }], ["path", { "d": "M8 16l-3.3 3.3", "key": "svg-5" }]];
4208
+ const IconBoxModel = createReactComponent("outline", "box-model", "BoxModel", __iconNode$1y);
4209
4209
 
4210
4210
  /**
4211
4211
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4215,8 +4215,8 @@ const IconBoxModel = createReactComponent("outline", "box-model", "BoxModel", __
4215
4215
  */
4216
4216
 
4217
4217
 
4218
- const __iconNode$1v = [["path", { "d": "M7 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M17 17v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h2", "key": "svg-1" }]];
4219
- const IconBoxMultiple = createReactComponent("outline", "box-multiple", "BoxMultiple", __iconNode$1v);
4218
+ const __iconNode$1x = [["path", { "d": "M7 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M17 17v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h2", "key": "svg-1" }]];
4219
+ const IconBoxMultiple = createReactComponent("outline", "box-multiple", "BoxMultiple", __iconNode$1x);
4220
4220
 
4221
4221
  /**
4222
4222
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4226,8 +4226,8 @@ const IconBoxMultiple = createReactComponent("outline", "box-multiple", "BoxMult
4226
4226
  */
4227
4227
 
4228
4228
 
4229
- const __iconNode$1u = [["path", { "d": "M15.5 13a3.5 3.5 0 0 0 -3.5 3.5v1a3.5 3.5 0 0 0 7 0v-1.8", "key": "svg-0" }], ["path", { "d": "M8.5 13a3.5 3.5 0 0 1 3.5 3.5v1a3.5 3.5 0 0 1 -7 0v-1.8", "key": "svg-1" }], ["path", { "d": "M17.5 16a3.5 3.5 0 0 0 0 -7h-.5", "key": "svg-2" }], ["path", { "d": "M19 9.3v-2.8a3.5 3.5 0 0 0 -7 0", "key": "svg-3" }], ["path", { "d": "M6.5 16a3.5 3.5 0 0 1 0 -7h.5", "key": "svg-4" }], ["path", { "d": "M5 9.3v-2.8a3.5 3.5 0 0 1 7 0v10", "key": "svg-5" }]];
4230
- const IconBrain = createReactComponent("outline", "brain", "Brain", __iconNode$1u);
4229
+ const __iconNode$1w = [["path", { "d": "M15.5 13a3.5 3.5 0 0 0 -3.5 3.5v1a3.5 3.5 0 0 0 7 0v-1.8", "key": "svg-0" }], ["path", { "d": "M8.5 13a3.5 3.5 0 0 1 3.5 3.5v1a3.5 3.5 0 0 1 -7 0v-1.8", "key": "svg-1" }], ["path", { "d": "M17.5 16a3.5 3.5 0 0 0 0 -7h-.5", "key": "svg-2" }], ["path", { "d": "M19 9.3v-2.8a3.5 3.5 0 0 0 -7 0", "key": "svg-3" }], ["path", { "d": "M6.5 16a3.5 3.5 0 0 1 0 -7h.5", "key": "svg-4" }], ["path", { "d": "M5 9.3v-2.8a3.5 3.5 0 0 1 7 0v10", "key": "svg-5" }]];
4230
+ const IconBrain = createReactComponent("outline", "brain", "Brain", __iconNode$1w);
4231
4231
 
4232
4232
  /**
4233
4233
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4237,8 +4237,8 @@ const IconBrain = createReactComponent("outline", "brain", "Brain", __iconNode$1
4237
4237
  */
4238
4238
 
4239
4239
 
4240
- const __iconNode$1t = [["path", { "d": "M18.364 19.364a9 9 0 1 0 -12.728 0", "key": "svg-0" }], ["path", { "d": "M15.536 16.536a5 5 0 1 0 -7.072 0", "key": "svg-1" }], ["path", { "d": "M12 13m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }]];
4241
- const IconBroadcast = createReactComponent("outline", "broadcast", "Broadcast", __iconNode$1t);
4240
+ const __iconNode$1v = [["path", { "d": "M18.364 19.364a9 9 0 1 0 -12.728 0", "key": "svg-0" }], ["path", { "d": "M15.536 16.536a5 5 0 1 0 -7.072 0", "key": "svg-1" }], ["path", { "d": "M12 13m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }]];
4241
+ const IconBroadcast = createReactComponent("outline", "broadcast", "Broadcast", __iconNode$1v);
4242
4242
 
4243
4243
  /**
4244
4244
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4248,8 +4248,8 @@ const IconBroadcast = createReactComponent("outline", "broadcast", "Broadcast",
4248
4248
  */
4249
4249
 
4250
4250
 
4251
- const __iconNode$1s = [["path", { "d": "M9 9v-1a3 3 0 0 1 6 0v1", "key": "svg-0" }], ["path", { "d": "M8 9h8a6 6 0 0 1 1 3v3a5 5 0 0 1 -10 0v-3a6 6 0 0 1 1 -3", "key": "svg-1" }], ["path", { "d": "M3 13l4 0", "key": "svg-2" }], ["path", { "d": "M17 13l4 0", "key": "svg-3" }], ["path", { "d": "M12 20l0 -6", "key": "svg-4" }], ["path", { "d": "M4 19l3.35 -2", "key": "svg-5" }], ["path", { "d": "M20 19l-3.35 -2", "key": "svg-6" }], ["path", { "d": "M4 7l3.75 2.4", "key": "svg-7" }], ["path", { "d": "M20 7l-3.75 2.4", "key": "svg-8" }]];
4252
- const IconBug = createReactComponent("outline", "bug", "Bug", __iconNode$1s);
4251
+ const __iconNode$1u = [["path", { "d": "M9 9v-1a3 3 0 0 1 6 0v1", "key": "svg-0" }], ["path", { "d": "M8 9h8a6 6 0 0 1 1 3v3a5 5 0 0 1 -10 0v-3a6 6 0 0 1 1 -3", "key": "svg-1" }], ["path", { "d": "M3 13l4 0", "key": "svg-2" }], ["path", { "d": "M17 13l4 0", "key": "svg-3" }], ["path", { "d": "M12 20l0 -6", "key": "svg-4" }], ["path", { "d": "M4 19l3.35 -2", "key": "svg-5" }], ["path", { "d": "M20 19l-3.35 -2", "key": "svg-6" }], ["path", { "d": "M4 7l3.75 2.4", "key": "svg-7" }], ["path", { "d": "M20 7l-3.75 2.4", "key": "svg-8" }]];
4252
+ const IconBug = createReactComponent("outline", "bug", "Bug", __iconNode$1u);
4253
4253
 
4254
4254
  /**
4255
4255
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4259,8 +4259,8 @@ const IconBug = createReactComponent("outline", "bug", "Bug", __iconNode$1s);
4259
4259
  */
4260
4260
 
4261
4261
 
4262
- const __iconNode$1r = [["path", { "d": "M3 21l18 0", "key": "svg-0" }], ["path", { "d": "M9 8l1 0", "key": "svg-1" }], ["path", { "d": "M9 12l1 0", "key": "svg-2" }], ["path", { "d": "M9 16l1 0", "key": "svg-3" }], ["path", { "d": "M14 8l1 0", "key": "svg-4" }], ["path", { "d": "M14 12l1 0", "key": "svg-5" }], ["path", { "d": "M14 16l1 0", "key": "svg-6" }], ["path", { "d": "M5 21v-16a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v16", "key": "svg-7" }]];
4263
- const IconBuilding = createReactComponent("outline", "building", "Building", __iconNode$1r);
4262
+ const __iconNode$1t = [["path", { "d": "M3 21l18 0", "key": "svg-0" }], ["path", { "d": "M9 8l1 0", "key": "svg-1" }], ["path", { "d": "M9 12l1 0", "key": "svg-2" }], ["path", { "d": "M9 16l1 0", "key": "svg-3" }], ["path", { "d": "M14 8l1 0", "key": "svg-4" }], ["path", { "d": "M14 12l1 0", "key": "svg-5" }], ["path", { "d": "M14 16l1 0", "key": "svg-6" }], ["path", { "d": "M5 21v-16a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v16", "key": "svg-7" }]];
4263
+ const IconBuilding = createReactComponent("outline", "building", "Building", __iconNode$1t);
4264
4264
 
4265
4265
  /**
4266
4266
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4270,8 +4270,8 @@ const IconBuilding = createReactComponent("outline", "building", "Building", __i
4270
4270
  */
4271
4271
 
4272
4272
 
4273
- const __iconNode$1q = [["path", { "d": "M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z", "key": "svg-0" }], ["path", { "d": "M16 3v4", "key": "svg-1" }], ["path", { "d": "M8 3v4", "key": "svg-2" }], ["path", { "d": "M4 11h16", "key": "svg-3" }], ["path", { "d": "M11 15h1", "key": "svg-4" }], ["path", { "d": "M12 15v3", "key": "svg-5" }]];
4274
- const IconCalendar = createReactComponent("outline", "calendar", "Calendar", __iconNode$1q);
4273
+ const __iconNode$1s = [["path", { "d": "M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z", "key": "svg-0" }], ["path", { "d": "M16 3v4", "key": "svg-1" }], ["path", { "d": "M8 3v4", "key": "svg-2" }], ["path", { "d": "M4 11h16", "key": "svg-3" }], ["path", { "d": "M11 15h1", "key": "svg-4" }], ["path", { "d": "M12 15v3", "key": "svg-5" }]];
4274
+ const IconCalendar = createReactComponent("outline", "calendar", "Calendar", __iconNode$1s);
4275
4275
 
4276
4276
  /**
4277
4277
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4281,8 +4281,8 @@ const IconCalendar = createReactComponent("outline", "calendar", "Calendar", __i
4281
4281
  */
4282
4282
 
4283
4283
 
4284
- const __iconNode$1p = [["path", { "d": "M4 4h6v6h-6z", "key": "svg-0" }], ["path", { "d": "M14 4h6v6h-6z", "key": "svg-1" }], ["path", { "d": "M4 14h6v6h-6z", "key": "svg-2" }], ["path", { "d": "M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0", "key": "svg-3" }]];
4285
- const IconCategory = createReactComponent("outline", "category", "Category", __iconNode$1p);
4284
+ const __iconNode$1r = [["path", { "d": "M4 4h6v6h-6z", "key": "svg-0" }], ["path", { "d": "M14 4h6v6h-6z", "key": "svg-1" }], ["path", { "d": "M4 14h6v6h-6z", "key": "svg-2" }], ["path", { "d": "M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0", "key": "svg-3" }]];
4285
+ const IconCategory = createReactComponent("outline", "category", "Category", __iconNode$1r);
4286
4286
 
4287
4287
  /**
4288
4288
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4292,8 +4292,8 @@ const IconCategory = createReactComponent("outline", "category", "Category", __i
4292
4292
  */
4293
4293
 
4294
4294
 
4295
- const __iconNode$1o = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
4296
- const IconCheck = createReactComponent("outline", "check", "Check", __iconNode$1o);
4295
+ const __iconNode$1q = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
4296
+ const IconCheck = createReactComponent("outline", "check", "Check", __iconNode$1q);
4297
4297
 
4298
4298
  /**
4299
4299
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4303,8 +4303,8 @@ const IconCheck = createReactComponent("outline", "check", "Check", __iconNode$1
4303
4303
  */
4304
4304
 
4305
4305
 
4306
- const __iconNode$1n = [["path", { "d": "M7 12l5 5l10 -10", "key": "svg-0" }], ["path", { "d": "M2 12l5 5m5 -5l5 -5", "key": "svg-1" }]];
4307
- const IconChecks = createReactComponent("outline", "checks", "Checks", __iconNode$1n);
4306
+ const __iconNode$1p = [["path", { "d": "M7 12l5 5l10 -10", "key": "svg-0" }], ["path", { "d": "M2 12l5 5m5 -5l5 -5", "key": "svg-1" }]];
4307
+ const IconChecks = createReactComponent("outline", "checks", "Checks", __iconNode$1p);
4308
4308
 
4309
4309
  /**
4310
4310
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4314,8 +4314,8 @@ const IconChecks = createReactComponent("outline", "checks", "Checks", __iconNod
4314
4314
  */
4315
4315
 
4316
4316
 
4317
- const __iconNode$1m = [["path", { "d": "M6 9l6 6l6 -6", "key": "svg-0" }]];
4318
- const IconChevronDown = createReactComponent("outline", "chevron-down", "ChevronDown", __iconNode$1m);
4317
+ const __iconNode$1o = [["path", { "d": "M6 9l6 6l6 -6", "key": "svg-0" }]];
4318
+ const IconChevronDown = createReactComponent("outline", "chevron-down", "ChevronDown", __iconNode$1o);
4319
4319
 
4320
4320
  /**
4321
4321
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4325,8 +4325,8 @@ const IconChevronDown = createReactComponent("outline", "chevron-down", "Chevron
4325
4325
  */
4326
4326
 
4327
4327
 
4328
- const __iconNode$1l = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
4329
- const IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode$1l);
4328
+ const __iconNode$1n = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
4329
+ const IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode$1n);
4330
4330
 
4331
4331
  /**
4332
4332
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4336,8 +4336,8 @@ const IconChevronLeft = createReactComponent("outline", "chevron-left", "Chevron
4336
4336
  */
4337
4337
 
4338
4338
 
4339
- const __iconNode$1k = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
4340
- const IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode$1k);
4339
+ const __iconNode$1m = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
4340
+ const IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode$1m);
4341
4341
 
4342
4342
  /**
4343
4343
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4347,8 +4347,8 @@ const IconChevronRight = createReactComponent("outline", "chevron-right", "Chevr
4347
4347
  */
4348
4348
 
4349
4349
 
4350
- const __iconNode$1j = [["path", { "d": "M6 15l6 -6l6 6", "key": "svg-0" }]];
4351
- const IconChevronUp = createReactComponent("outline", "chevron-up", "ChevronUp", __iconNode$1j);
4350
+ const __iconNode$1l = [["path", { "d": "M6 15l6 -6l6 6", "key": "svg-0" }]];
4351
+ const IconChevronUp = createReactComponent("outline", "chevron-up", "ChevronUp", __iconNode$1l);
4352
4352
 
4353
4353
  /**
4354
4354
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4358,8 +4358,8 @@ const IconChevronUp = createReactComponent("outline", "chevron-up", "ChevronUp",
4358
4358
  */
4359
4359
 
4360
4360
 
4361
- const __iconNode$1i = [["path", { "d": "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", "key": "svg-0" }], ["path", { "d": "M9 12l2 2l4 -4", "key": "svg-1" }]];
4362
- const IconCircleCheck = createReactComponent("outline", "circle-check", "CircleCheck", __iconNode$1i);
4361
+ const __iconNode$1k = [["path", { "d": "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", "key": "svg-0" }], ["path", { "d": "M9 12l2 2l4 -4", "key": "svg-1" }]];
4362
+ const IconCircleCheck = createReactComponent("outline", "circle-check", "CircleCheck", __iconNode$1k);
4363
4363
 
4364
4364
  /**
4365
4365
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4369,8 +4369,8 @@ const IconCircleCheck = createReactComponent("outline", "circle-check", "CircleC
4369
4369
  */
4370
4370
 
4371
4371
 
4372
- const __iconNode$1h = [["path", { "d": "M20.042 16.045a9 9 0 0 0 -12.087 -12.087m-2.318 1.677a9 9 0 1 0 12.725 12.73", "key": "svg-0" }], ["path", { "d": "M3 3l18 18", "key": "svg-1" }]];
4373
- const IconCircleOff = createReactComponent("outline", "circle-off", "CircleOff", __iconNode$1h);
4372
+ const __iconNode$1j = [["path", { "d": "M20.042 16.045a9 9 0 0 0 -12.087 -12.087m-2.318 1.677a9 9 0 1 0 12.725 12.73", "key": "svg-0" }], ["path", { "d": "M3 3l18 18", "key": "svg-1" }]];
4373
+ const IconCircleOff = createReactComponent("outline", "circle-off", "CircleOff", __iconNode$1j);
4374
4374
 
4375
4375
  /**
4376
4376
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4380,8 +4380,8 @@ const IconCircleOff = createReactComponent("outline", "circle-off", "CircleOff",
4380
4380
  */
4381
4381
 
4382
4382
 
4383
- const __iconNode$1g = [["path", { "d": "M8 6h12", "key": "svg-0" }], ["path", { "d": "M6 12h12", "key": "svg-1" }], ["path", { "d": "M4 18h12", "key": "svg-2" }]];
4384
- const IconClearAll = createReactComponent("outline", "clear-all", "ClearAll", __iconNode$1g);
4383
+ const __iconNode$1i = [["path", { "d": "M8 6h12", "key": "svg-0" }], ["path", { "d": "M6 12h12", "key": "svg-1" }], ["path", { "d": "M4 18h12", "key": "svg-2" }]];
4384
+ const IconClearAll = createReactComponent("outline", "clear-all", "ClearAll", __iconNode$1i);
4385
4385
 
4386
4386
  /**
4387
4387
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4391,8 +4391,8 @@ const IconClearAll = createReactComponent("outline", "clear-all", "ClearAll", __
4391
4391
  */
4392
4392
 
4393
4393
 
4394
- const __iconNode$1f = [["path", { "d": "M9.58 5.548c.24 -.11 .492 -.207 .752 -.286c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.913 0 3.464 1.56 3.464 3.486c0 .957 -.383 1.824 -1.003 2.454m-2.997 1.033h-11.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.13 -.582 .37 -1.128 .7 -1.62", "key": "svg-0" }], ["path", { "d": "M3 3l18 18", "key": "svg-1" }]];
4395
- const IconCloudOff = createReactComponent("outline", "cloud-off", "CloudOff", __iconNode$1f);
4394
+ const __iconNode$1h = [["path", { "d": "M9.58 5.548c.24 -.11 .492 -.207 .752 -.286c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.913 0 3.464 1.56 3.464 3.486c0 .957 -.383 1.824 -1.003 2.454m-2.997 1.033h-11.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.13 -.582 .37 -1.128 .7 -1.62", "key": "svg-0" }], ["path", { "d": "M3 3l18 18", "key": "svg-1" }]];
4395
+ const IconCloudOff = createReactComponent("outline", "cloud-off", "CloudOff", __iconNode$1h);
4396
4396
 
4397
4397
  /**
4398
4398
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4402,8 +4402,8 @@ const IconCloudOff = createReactComponent("outline", "cloud-off", "CloudOff", __
4402
4402
  */
4403
4403
 
4404
4404
 
4405
- const __iconNode$1e = [["path", { "d": "M12 13m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M13.45 11.55l2.05 -2.05", "key": "svg-1" }], ["path", { "d": "M6.4 20a9 9 0 1 1 11.2 0z", "key": "svg-2" }]];
4406
- const IconDashboard = createReactComponent("outline", "dashboard", "Dashboard", __iconNode$1e);
4405
+ const __iconNode$1g = [["path", { "d": "M12 13m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M13.45 11.55l2.05 -2.05", "key": "svg-1" }], ["path", { "d": "M6.4 20a9 9 0 1 1 11.2 0z", "key": "svg-2" }]];
4406
+ const IconDashboard = createReactComponent("outline", "dashboard", "Dashboard", __iconNode$1g);
4407
4407
 
4408
4408
  /**
4409
4409
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4413,8 +4413,8 @@ const IconDashboard = createReactComponent("outline", "dashboard", "Dashboard",
4413
4413
  */
4414
4414
 
4415
4415
 
4416
- const __iconNode$1d = [["path", { "d": "M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0", "key": "svg-0" }], ["path", { "d": "M4 6v6a8 3 0 0 0 16 0v-6", "key": "svg-1" }], ["path", { "d": "M4 12v6a8 3 0 0 0 16 0v-6", "key": "svg-2" }]];
4417
- const IconDatabase = createReactComponent("outline", "database", "Database", __iconNode$1d);
4416
+ const __iconNode$1f = [["path", { "d": "M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0", "key": "svg-0" }], ["path", { "d": "M4 6v6a8 3 0 0 0 16 0v-6", "key": "svg-1" }], ["path", { "d": "M4 12v6a8 3 0 0 0 16 0v-6", "key": "svg-2" }]];
4417
+ const IconDatabase = createReactComponent("outline", "database", "Database", __iconNode$1f);
4418
4418
 
4419
4419
  /**
4420
4420
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4424,8 +4424,8 @@ const IconDatabase = createReactComponent("outline", "database", "Database", __i
4424
4424
  */
4425
4425
 
4426
4426
 
4427
- const __iconNode$1c = [["path", { "d": "M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2", "key": "svg-0" }], ["path", { "d": "M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M14 4l0 4l-6 0l0 -4", "key": "svg-2" }]];
4428
- const IconDeviceFloppy = createReactComponent("outline", "device-floppy", "DeviceFloppy", __iconNode$1c);
4427
+ const __iconNode$1e = [["path", { "d": "M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2", "key": "svg-0" }], ["path", { "d": "M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M14 4l0 4l-6 0l0 -4", "key": "svg-2" }]];
4428
+ const IconDeviceFloppy = createReactComponent("outline", "device-floppy", "DeviceFloppy", __iconNode$1e);
4429
4429
 
4430
4430
  /**
4431
4431
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4435,8 +4435,8 @@ const IconDeviceFloppy = createReactComponent("outline", "device-floppy", "Devic
4435
4435
  */
4436
4436
 
4437
4437
 
4438
- const __iconNode$1b = [["path", { "d": "M3 19l18 0", "key": "svg-0" }], ["path", { "d": "M5 6m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z", "key": "svg-1" }]];
4439
- const IconDeviceLaptop = createReactComponent("outline", "device-laptop", "DeviceLaptop", __iconNode$1b);
4438
+ const __iconNode$1d = [["path", { "d": "M3 19l18 0", "key": "svg-0" }], ["path", { "d": "M5 6m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z", "key": "svg-1" }]];
4439
+ const IconDeviceLaptop = createReactComponent("outline", "device-laptop", "DeviceLaptop", __iconNode$1d);
4440
4440
 
4441
4441
  /**
4442
4442
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4446,8 +4446,8 @@ const IconDeviceLaptop = createReactComponent("outline", "device-laptop", "Devic
4446
4446
  */
4447
4447
 
4448
4448
 
4449
- const __iconNode$1a = [["path", { "d": "M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }]];
4450
- const IconDotsVertical = createReactComponent("outline", "dots-vertical", "DotsVertical", __iconNode$1a);
4449
+ const __iconNode$1c = [["path", { "d": "M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }]];
4450
+ const IconDotsVertical = createReactComponent("outline", "dots-vertical", "DotsVertical", __iconNode$1c);
4451
4451
 
4452
4452
  /**
4453
4453
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4457,8 +4457,8 @@ const IconDotsVertical = createReactComponent("outline", "dots-vertical", "DotsV
4457
4457
  */
4458
4458
 
4459
4459
 
4460
- const __iconNode$19 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
4461
- const IconDownload = createReactComponent("outline", "download", "Download", __iconNode$19);
4460
+ const __iconNode$1b = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
4461
+ const IconDownload = createReactComponent("outline", "download", "Download", __iconNode$1b);
4462
4462
 
4463
4463
  /**
4464
4464
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4468,8 +4468,8 @@ const IconDownload = createReactComponent("outline", "download", "Download", __i
4468
4468
  */
4469
4469
 
4470
4470
 
4471
- const __iconNode$18 = [["path", { "d": "M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1", "key": "svg-0" }], ["path", { "d": "M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z", "key": "svg-1" }], ["path", { "d": "M16 5l3 3", "key": "svg-2" }]];
4472
- const IconEdit = createReactComponent("outline", "edit", "Edit", __iconNode$18);
4471
+ const __iconNode$1a = [["path", { "d": "M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1", "key": "svg-0" }], ["path", { "d": "M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z", "key": "svg-1" }], ["path", { "d": "M16 5l3 3", "key": "svg-2" }]];
4472
+ const IconEdit = createReactComponent("outline", "edit", "Edit", __iconNode$1a);
4473
4473
 
4474
4474
  /**
4475
4475
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4479,8 +4479,8 @@ const IconEdit = createReactComponent("outline", "edit", "Edit", __iconNode$18);
4479
4479
  */
4480
4480
 
4481
4481
 
4482
- const __iconNode$17 = [["path", { "d": "M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6", "key": "svg-0" }], ["path", { "d": "M11 13l9 -9", "key": "svg-1" }], ["path", { "d": "M15 4h5v5", "key": "svg-2" }]];
4483
- const IconExternalLink = createReactComponent("outline", "external-link", "ExternalLink", __iconNode$17);
4482
+ const __iconNode$19 = [["path", { "d": "M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6", "key": "svg-0" }], ["path", { "d": "M11 13l9 -9", "key": "svg-1" }], ["path", { "d": "M15 4h5v5", "key": "svg-2" }]];
4483
+ const IconExternalLink = createReactComponent("outline", "external-link", "ExternalLink", __iconNode$19);
4484
4484
 
4485
4485
  /**
4486
4486
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4490,8 +4490,8 @@ const IconExternalLink = createReactComponent("outline", "external-link", "Exter
4490
4490
  */
4491
4491
 
4492
4492
 
4493
- const __iconNode$16 = [["path", { "d": "M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0", "key": "svg-0" }], ["path", { "d": "M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6", "key": "svg-1" }]];
4494
- const IconEye = createReactComponent("outline", "eye", "Eye", __iconNode$16);
4493
+ const __iconNode$18 = [["path", { "d": "M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0", "key": "svg-0" }], ["path", { "d": "M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6", "key": "svg-1" }]];
4494
+ const IconEye = createReactComponent("outline", "eye", "Eye", __iconNode$18);
4495
4495
 
4496
4496
  /**
4497
4497
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4501,8 +4501,8 @@ const IconEye = createReactComponent("outline", "eye", "Eye", __iconNode$16);
4501
4501
  */
4502
4502
 
4503
4503
 
4504
- const __iconNode$15 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z", "key": "svg-1" }], ["path", { "d": "M12 11l0 6", "key": "svg-2" }], ["path", { "d": "M9 14l6 0", "key": "svg-3" }]];
4505
- const IconFilePlus = createReactComponent("outline", "file-plus", "FilePlus", __iconNode$15);
4504
+ const __iconNode$17 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z", "key": "svg-1" }], ["path", { "d": "M12 11l0 6", "key": "svg-2" }], ["path", { "d": "M9 14l6 0", "key": "svg-3" }]];
4505
+ const IconFilePlus = createReactComponent("outline", "file-plus", "FilePlus", __iconNode$17);
4506
4506
 
4507
4507
  /**
4508
4508
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4512,8 +4512,8 @@ const IconFilePlus = createReactComponent("outline", "file-plus", "FilePlus", __
4512
4512
  */
4513
4513
 
4514
4514
 
4515
- const __iconNode$14 = [["path", { "d": "M17 17m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", "key": "svg-0" }], ["path", { "d": "M17 13v4h4", "key": "svg-1" }], ["path", { "d": "M12 3v4a1 1 0 0 0 1 1h4", "key": "svg-2" }], ["path", { "d": "M11.5 21h-6.5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v2m0 3v4", "key": "svg-3" }]];
4516
- const IconFileReport = createReactComponent("outline", "file-report", "FileReport", __iconNode$14);
4515
+ const __iconNode$16 = [["path", { "d": "M17 17m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", "key": "svg-0" }], ["path", { "d": "M17 13v4h4", "key": "svg-1" }], ["path", { "d": "M12 3v4a1 1 0 0 0 1 1h4", "key": "svg-2" }], ["path", { "d": "M11.5 21h-6.5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v2m0 3v4", "key": "svg-3" }]];
4516
+ const IconFileReport = createReactComponent("outline", "file-report", "FileReport", __iconNode$16);
4517
4517
 
4518
4518
  /**
4519
4519
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4523,8 +4523,8 @@ const IconFileReport = createReactComponent("outline", "file-report", "FileRepor
4523
4523
  */
4524
4524
 
4525
4525
 
4526
- const __iconNode$13 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M12 21h-5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v4.5", "key": "svg-1" }], ["path", { "d": "M16.5 17.5m-2.5 0a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0 -5 0", "key": "svg-2" }], ["path", { "d": "M18.5 19.5l2.5 2.5", "key": "svg-3" }]];
4527
- const IconFileSearch = createReactComponent("outline", "file-search", "FileSearch", __iconNode$13);
4526
+ const __iconNode$15 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M12 21h-5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v4.5", "key": "svg-1" }], ["path", { "d": "M16.5 17.5m-2.5 0a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0 -5 0", "key": "svg-2" }], ["path", { "d": "M18.5 19.5l2.5 2.5", "key": "svg-3" }]];
4527
+ const IconFileSearch = createReactComponent("outline", "file-search", "FileSearch", __iconNode$15);
4528
4528
 
4529
4529
  /**
4530
4530
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4534,8 +4534,8 @@ const IconFileSearch = createReactComponent("outline", "file-search", "FileSearc
4534
4534
  */
4535
4535
 
4536
4536
 
4537
- const __iconNode$12 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z", "key": "svg-1" }]];
4538
- const IconFile = createReactComponent("outline", "file", "File", __iconNode$12);
4537
+ const __iconNode$14 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z", "key": "svg-1" }]];
4538
+ const IconFile = createReactComponent("outline", "file", "File", __iconNode$14);
4539
4539
 
4540
4540
  /**
4541
4541
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4545,8 +4545,8 @@ const IconFile = createReactComponent("outline", "file", "File", __iconNode$12);
4545
4545
  */
4546
4546
 
4547
4547
 
4548
- const __iconNode$11 = [["path", { "d": "M12 19h-7a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v3.5", "key": "svg-0" }], ["path", { "d": "M16 19h6", "key": "svg-1" }], ["path", { "d": "M19 16v6", "key": "svg-2" }]];
4549
- const IconFolderPlus = createReactComponent("outline", "folder-plus", "FolderPlus", __iconNode$11);
4548
+ const __iconNode$13 = [["path", { "d": "M12 19h-7a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v3.5", "key": "svg-0" }], ["path", { "d": "M16 19h6", "key": "svg-1" }], ["path", { "d": "M19 16v6", "key": "svg-2" }]];
4549
+ const IconFolderPlus = createReactComponent("outline", "folder-plus", "FolderPlus", __iconNode$13);
4550
4550
 
4551
4551
  /**
4552
4552
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4556,8 +4556,8 @@ const IconFolderPlus = createReactComponent("outline", "folder-plus", "FolderPlu
4556
4556
  */
4557
4557
 
4558
4558
 
4559
- const __iconNode$10 = [["path", { "d": "M12 19h-7a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v3.5", "key": "svg-0" }], ["path", { "d": "M19 22v-6", "key": "svg-1" }], ["path", { "d": "M22 19l-3 -3l-3 3", "key": "svg-2" }]];
4560
- const IconFolderUp = createReactComponent("outline", "folder-up", "FolderUp", __iconNode$10);
4559
+ const __iconNode$12 = [["path", { "d": "M12 19h-7a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v3.5", "key": "svg-0" }], ["path", { "d": "M19 22v-6", "key": "svg-1" }], ["path", { "d": "M22 19l-3 -3l-3 3", "key": "svg-2" }]];
4560
+ const IconFolderUp = createReactComponent("outline", "folder-up", "FolderUp", __iconNode$12);
4561
4561
 
4562
4562
  /**
4563
4563
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4567,8 +4567,8 @@ const IconFolderUp = createReactComponent("outline", "folder-up", "FolderUp", __
4567
4567
  */
4568
4568
 
4569
4569
 
4570
- const __iconNode$$ = [["path", { "d": "M13.5 19h-8.5a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v4", "key": "svg-0" }], ["path", { "d": "M22 22l-5 -5", "key": "svg-1" }], ["path", { "d": "M17 22l5 -5", "key": "svg-2" }]];
4571
- const IconFolderX = createReactComponent("outline", "folder-x", "FolderX", __iconNode$$);
4570
+ const __iconNode$11 = [["path", { "d": "M13.5 19h-8.5a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2h4l3 3h7a2 2 0 0 1 2 2v4", "key": "svg-0" }], ["path", { "d": "M22 22l-5 -5", "key": "svg-1" }], ["path", { "d": "M17 22l5 -5", "key": "svg-2" }]];
4571
+ const IconFolderX = createReactComponent("outline", "folder-x", "FolderX", __iconNode$11);
4572
4572
 
4573
4573
  /**
4574
4574
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4578,8 +4578,8 @@ const IconFolderX = createReactComponent("outline", "folder-x", "FolderX", __ico
4578
4578
  */
4579
4579
 
4580
4580
 
4581
- const __iconNode$_ = [["path", { "d": "M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2", "key": "svg-0" }]];
4582
- const IconFolder = createReactComponent("outline", "folder", "Folder", __iconNode$_);
4581
+ const __iconNode$10 = [["path", { "d": "M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2", "key": "svg-0" }]];
4582
+ const IconFolder = createReactComponent("outline", "folder", "Folder", __iconNode$10);
4583
4583
 
4584
4584
  /**
4585
4585
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4589,8 +4589,8 @@ const IconFolder = createReactComponent("outline", "folder", "Folder", __iconNod
4589
4589
  */
4590
4590
 
4591
4591
 
4592
- const __iconNode$Z = [["path", { "d": "M7 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M17 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-2" }], ["path", { "d": "M7 8l0 8", "key": "svg-3" }], ["path", { "d": "M9 18h6a2 2 0 0 0 2 -2v-5", "key": "svg-4" }], ["path", { "d": "M14 14l3 -3l3 3", "key": "svg-5" }]];
4593
- const IconGitBranch = createReactComponent("outline", "git-branch", "GitBranch", __iconNode$Z);
4592
+ const __iconNode$$ = [["path", { "d": "M7 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M17 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-2" }], ["path", { "d": "M7 8l0 8", "key": "svg-3" }], ["path", { "d": "M9 18h6a2 2 0 0 0 2 -2v-5", "key": "svg-4" }], ["path", { "d": "M14 14l3 -3l3 3", "key": "svg-5" }]];
4593
+ const IconGitBranch = createReactComponent("outline", "git-branch", "GitBranch", __iconNode$$);
4594
4594
 
4595
4595
  /**
4596
4596
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4600,8 +4600,8 @@ const IconGitBranch = createReactComponent("outline", "git-branch", "GitBranch",
4600
4600
  */
4601
4601
 
4602
4602
 
4603
- const __iconNode$Y = [["path", { "d": "M7 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M17 12m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-2" }], ["path", { "d": "M7 8l0 8", "key": "svg-3" }], ["path", { "d": "M7 8a4 4 0 0 0 4 4h4", "key": "svg-4" }]];
4604
- const IconGitMerge = createReactComponent("outline", "git-merge", "GitMerge", __iconNode$Y);
4603
+ const __iconNode$_ = [["path", { "d": "M7 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-0" }], ["path", { "d": "M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M17 12m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-2" }], ["path", { "d": "M7 8l0 8", "key": "svg-3" }], ["path", { "d": "M7 8a4 4 0 0 0 4 4h4", "key": "svg-4" }]];
4604
+ const IconGitMerge = createReactComponent("outline", "git-merge", "GitMerge", __iconNode$_);
4605
4605
 
4606
4606
  /**
4607
4607
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4611,8 +4611,8 @@ const IconGitMerge = createReactComponent("outline", "git-merge", "GitMerge", __
4611
4611
  */
4612
4612
 
4613
4613
 
4614
- const __iconNode$X = [["path", { "d": "M5 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M19 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }], ["path", { "d": "M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-3" }], ["path", { "d": "M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-4" }], ["path", { "d": "M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-5" }], ["path", { "d": "M5 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-6" }], ["path", { "d": "M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-7" }], ["path", { "d": "M19 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-8" }]];
4615
- const IconGridDots = createReactComponent("outline", "grid-dots", "GridDots", __iconNode$X);
4614
+ const __iconNode$Z = [["path", { "d": "M5 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M19 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }], ["path", { "d": "M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-3" }], ["path", { "d": "M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-4" }], ["path", { "d": "M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-5" }], ["path", { "d": "M5 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-6" }], ["path", { "d": "M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-7" }], ["path", { "d": "M19 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-8" }]];
4615
+ const IconGridDots = createReactComponent("outline", "grid-dots", "GridDots", __iconNode$Z);
4616
4616
 
4617
4617
  /**
4618
4618
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4622,8 +4622,8 @@ const IconGridDots = createReactComponent("outline", "grid-dots", "GridDots", __
4622
4622
  */
4623
4623
 
4624
4624
 
4625
- const __iconNode$W = [["path", { "d": "M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }], ["path", { "d": "M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-3" }], ["path", { "d": "M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-4" }], ["path", { "d": "M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-5" }]];
4626
- const IconGripVertical = createReactComponent("outline", "grip-vertical", "GripVertical", __iconNode$W);
4625
+ const __iconNode$Y = [["path", { "d": "M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }], ["path", { "d": "M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-3" }], ["path", { "d": "M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-4" }], ["path", { "d": "M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-5" }]];
4626
+ const IconGripVertical = createReactComponent("outline", "grip-vertical", "GripVertical", __iconNode$Y);
4627
4627
 
4628
4628
  /**
4629
4629
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4633,8 +4633,8 @@ const IconGripVertical = createReactComponent("outline", "grip-vertical", "GripV
4633
4633
  */
4634
4634
 
4635
4635
 
4636
- const __iconNode$V = [["path", { "d": "M19 14a2 2 0 1 0 0 4a2 2 0 0 0 0 -4z", "key": "svg-0" }], ["path", { "d": "M21 12a2 2 0 1 0 -4 0v4", "key": "svg-1" }], ["path", { "d": "M4 6v12", "key": "svg-2" }], ["path", { "d": "M12 6v12", "key": "svg-3" }], ["path", { "d": "M11 18h2", "key": "svg-4" }], ["path", { "d": "M3 18h2", "key": "svg-5" }], ["path", { "d": "M4 12h8", "key": "svg-6" }], ["path", { "d": "M3 6h2", "key": "svg-7" }], ["path", { "d": "M11 6h2", "key": "svg-8" }]];
4637
- const IconH6 = createReactComponent("outline", "h-6", "H6", __iconNode$V);
4636
+ const __iconNode$X = [["path", { "d": "M19 14a2 2 0 1 0 0 4a2 2 0 0 0 0 -4z", "key": "svg-0" }], ["path", { "d": "M21 12a2 2 0 1 0 -4 0v4", "key": "svg-1" }], ["path", { "d": "M4 6v12", "key": "svg-2" }], ["path", { "d": "M12 6v12", "key": "svg-3" }], ["path", { "d": "M11 18h2", "key": "svg-4" }], ["path", { "d": "M3 18h2", "key": "svg-5" }], ["path", { "d": "M4 12h8", "key": "svg-6" }], ["path", { "d": "M3 6h2", "key": "svg-7" }], ["path", { "d": "M11 6h2", "key": "svg-8" }]];
4637
+ const IconH6 = createReactComponent("outline", "h-6", "H6", __iconNode$X);
4638
4638
 
4639
4639
  /**
4640
4640
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4644,8 +4644,8 @@ const IconH6 = createReactComponent("outline", "h-6", "H6", __iconNode$V);
4644
4644
  */
4645
4645
 
4646
4646
 
4647
- const __iconNode$U = [["path", { "d": "M5 12l-2 0l9 -9l9 9l-2 0", "key": "svg-0" }], ["path", { "d": "M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7", "key": "svg-1" }], ["path", { "d": "M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6", "key": "svg-2" }]];
4648
- const IconHome = createReactComponent("outline", "home", "Home", __iconNode$U);
4647
+ const __iconNode$W = [["path", { "d": "M5 12l-2 0l9 -9l9 9l-2 0", "key": "svg-0" }], ["path", { "d": "M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7", "key": "svg-1" }], ["path", { "d": "M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6", "key": "svg-2" }]];
4648
+ const IconHome = createReactComponent("outline", "home", "Home", __iconNode$W);
4649
4649
 
4650
4650
  /**
4651
4651
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4655,8 +4655,8 @@ const IconHome = createReactComponent("outline", "home", "Home", __iconNode$U);
4655
4655
  */
4656
4656
 
4657
4657
 
4658
- const __iconNode$T = [["path", { "d": "M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v10a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z", "key": "svg-0" }], ["path", { "d": "M9 10m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M15 8l2 0", "key": "svg-2" }], ["path", { "d": "M15 12l2 0", "key": "svg-3" }], ["path", { "d": "M7 16l10 0", "key": "svg-4" }]];
4659
- const IconId = createReactComponent("outline", "id", "Id", __iconNode$T);
4658
+ const __iconNode$V = [["path", { "d": "M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v10a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z", "key": "svg-0" }], ["path", { "d": "M9 10m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0", "key": "svg-1" }], ["path", { "d": "M15 8l2 0", "key": "svg-2" }], ["path", { "d": "M15 12l2 0", "key": "svg-3" }], ["path", { "d": "M7 16l10 0", "key": "svg-4" }]];
4659
+ const IconId = createReactComponent("outline", "id", "Id", __iconNode$V);
4660
4660
 
4661
4661
  /**
4662
4662
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4666,8 +4666,8 @@ const IconId = createReactComponent("outline", "id", "Id", __iconNode$T);
4666
4666
  */
4667
4667
 
4668
4668
 
4669
- const __iconNode$S = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 9h.01", "key": "svg-1" }], ["path", { "d": "M11 12h1v4h1", "key": "svg-2" }]];
4670
- const IconInfoCircle = createReactComponent("outline", "info-circle", "InfoCircle", __iconNode$S);
4669
+ const __iconNode$U = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 9h.01", "key": "svg-1" }], ["path", { "d": "M11 12h1v4h1", "key": "svg-2" }]];
4670
+ const IconInfoCircle = createReactComponent("outline", "info-circle", "InfoCircle", __iconNode$U);
4671
4671
 
4672
4672
  /**
4673
4673
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4677,8 +4677,8 @@ const IconInfoCircle = createReactComponent("outline", "info-circle", "InfoCircl
4677
4677
  */
4678
4678
 
4679
4679
 
4680
- const __iconNode$R = [["path", { "d": "M12 9h.01", "key": "svg-0" }], ["path", { "d": "M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14z", "key": "svg-1" }], ["path", { "d": "M11 12h1v4h1", "key": "svg-2" }]];
4681
- const IconInfoSquare = createReactComponent("outline", "info-square", "InfoSquare", __iconNode$R);
4680
+ const __iconNode$T = [["path", { "d": "M12 9h.01", "key": "svg-0" }], ["path", { "d": "M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14z", "key": "svg-1" }], ["path", { "d": "M11 12h1v4h1", "key": "svg-2" }]];
4681
+ const IconInfoSquare = createReactComponent("outline", "info-square", "InfoSquare", __iconNode$T);
4682
4682
 
4683
4683
  /**
4684
4684
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4688,8 +4688,8 @@ const IconInfoSquare = createReactComponent("outline", "info-square", "InfoSquar
4688
4688
  */
4689
4689
 
4690
4690
 
4691
- const __iconNode$Q = [["path", { "d": "M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z", "key": "svg-0" }], ["path", { "d": "M15 9h.01", "key": "svg-1" }]];
4692
- const IconKey = createReactComponent("outline", "key", "Key", __iconNode$Q);
4691
+ const __iconNode$S = [["path", { "d": "M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z", "key": "svg-0" }], ["path", { "d": "M15 9h.01", "key": "svg-1" }]];
4692
+ const IconKey = createReactComponent("outline", "key", "Key", __iconNode$S);
4693
4693
 
4694
4694
  /**
4695
4695
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4699,8 +4699,8 @@ const IconKey = createReactComponent("outline", "key", "Key", __iconNode$Q);
4699
4699
  */
4700
4700
 
4701
4701
 
4702
- const __iconNode$P = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M4 15l16 0", "key": "svg-1" }]];
4703
- const IconLayoutBottombar = createReactComponent("outline", "layout-bottombar", "LayoutBottombar", __iconNode$P);
4702
+ const __iconNode$R = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M4 15l16 0", "key": "svg-1" }]];
4703
+ const IconLayoutBottombar = createReactComponent("outline", "layout-bottombar", "LayoutBottombar", __iconNode$R);
4704
4704
 
4705
4705
  /**
4706
4706
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -4710,8 +4710,30 @@ const IconLayoutBottombar = createReactComponent("outline", "layout-bottombar",
4710
4710
  */
4711
4711
 
4712
4712
 
4713
- const __iconNode$O = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M4 14m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-1" }]];
4714
- const IconLayoutList = createReactComponent("outline", "layout-list", "LayoutList", __iconNode$O);
4713
+ const __iconNode$Q = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M4 14m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-1" }]];
4714
+ const IconLayoutList = createReactComponent("outline", "layout-list", "LayoutList", __iconNode$Q);
4715
+
4716
+ /**
4717
+ * @license @tabler/icons-react v3.36.0 - MIT
4718
+ *
4719
+ * This source code is licensed under the MIT license.
4720
+ * See the LICENSE file in the root directory of this source tree.
4721
+ */
4722
+
4723
+
4724
+ const __iconNode$P = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M9 4v16", "key": "svg-1" }], ["path", { "d": "M15 10l-2 2l2 2", "key": "svg-2" }]];
4725
+ const IconLayoutSidebarLeftCollapse = createReactComponent("outline", "layout-sidebar-left-collapse", "LayoutSidebarLeftCollapse", __iconNode$P);
4726
+
4727
+ /**
4728
+ * @license @tabler/icons-react v3.36.0 - MIT
4729
+ *
4730
+ * This source code is licensed under the MIT license.
4731
+ * See the LICENSE file in the root directory of this source tree.
4732
+ */
4733
+
4734
+
4735
+ const __iconNode$O = [["path", { "d": "M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M9 4v16", "key": "svg-1" }], ["path", { "d": "M14 10l2 2l-2 2", "key": "svg-2" }]];
4736
+ const IconLayoutSidebarLeftExpand = createReactComponent("outline", "layout-sidebar-left-expand", "LayoutSidebarLeftExpand", __iconNode$O);
4715
4737
 
4716
4738
  /**
4717
4739
  * @license @tabler/icons-react v3.36.0 - MIT
@@ -13846,6 +13868,12 @@ function SearchBar(props) {
13846
13868
  const [allGroups, setAllGroups] = useState([]);
13847
13869
  const [showEasterEggModal, setShowEasterEggModal] = useState(false);
13848
13870
  const [activeEasterEgg, setActiveEasterEgg] = useState('');
13871
+ // Il layout "modern" ha la barra superiore bianca: il campo traslucido pensato per
13872
+ // l'app bar colorata del layout classico lì risulterebbe bianco su bianco.
13873
+ // Nel modern lo stile del campo arriva dalla chrome (classe `flxModernSearchSlot`).
13874
+ const {
13875
+ isModernLayout
13876
+ } = useShellLayout();
13849
13877
  const searchType = (_b = (_a = props.shellUi.search) === null || _a === void 0 ? void 0 : _a.searchType) !== null && _b !== void 0 ? _b : ShellUISearchType.Spotlight;
13850
13878
  const searchPosition = (_d = (_c = props.shellUi.search) === null || _c === void 0 ? void 0 : _c.searchPosition) !== null && _d !== void 0 ? _d : ShellUISearchPosition.Left;
13851
13879
  const isCenterPosition = searchPosition === ShellUISearchPosition.Center;
@@ -13999,7 +14027,9 @@ function SearchBar(props) {
13999
14027
  w: isCenterPosition ? '100%' : 280,
14000
14028
  rightSection: rightSection,
14001
14029
  styles: {
14002
- input: {
14030
+ input: isModernLayout ? {
14031
+ cursor: 'pointer'
14032
+ } : {
14003
14033
  cursor: 'pointer',
14004
14034
  borderRadius: isCenterPosition ? 0 : 0,
14005
14035
  backgroundColor: isCenterPosition ? 'rgba(255, 255, 255, 0.95)' : undefined,
@@ -14059,7 +14089,7 @@ function SearchBar(props) {
14059
14089
  w: isCenterPosition ? '100%' : 280,
14060
14090
  rightSection: rightSection,
14061
14091
  styles: {
14062
- input: {
14092
+ input: isModernLayout ? {} : {
14063
14093
  borderRadius: isCenterPosition ? 0 : 0,
14064
14094
  backgroundColor: isCenterPosition ? 'rgba(255, 255, 255, 0.95)' : undefined,
14065
14095
  border: isCenterPosition ? '1px solid rgba(255, 255, 255, 0.2)' : undefined,
@@ -14408,14 +14438,112 @@ function FrontendSwitch(props) {
14408
14438
  });
14409
14439
  }
14410
14440
 
14441
+ /**
14442
+ * Modello di branding della shell.
14443
+ *
14444
+ * Tutto quello che è definito qui è completamente opzionale: se il progetto consumer
14445
+ * non passa nessuna configurazione di branding la shell continua a comportarsi
14446
+ * esattamente come prima (logo e colori arrivano dal backend e sono modificabili
14447
+ * dalla scheda "Brand" dell'amministrazione).
14448
+ */
14449
+ /**
14450
+ * Converte uno {@link ShellSidebarBackground} nel corrispondente valore CSS.
14451
+ */
14452
+ function resolveShellBackground(background) {
14453
+ var _a;
14454
+ if (!background) return undefined;
14455
+ if (typeof background === 'string') return background;
14456
+ return `linear-gradient(${(_a = background.angle) !== null && _a !== void 0 ? _a : 180}deg, ${background.from} 0%, ${background.to} 100%)`;
14457
+ }
14458
+ /**
14459
+ * Colore "pieno" da usare dove un gradiente non è applicabile
14460
+ * (es. la striscia superiore che deve combaciare con la parte alta della sidebar).
14461
+ */
14462
+ function resolveShellBackgroundTopColor(background) {
14463
+ if (!background) return undefined;
14464
+ return typeof background === 'string' ? background : background.from;
14465
+ }
14466
+ /**
14467
+ * Determina se la personalizzazione del brand è permessa in base alla configurazione.
14468
+ */
14469
+ function isBrandCustomizationAllowed(branding) {
14470
+ if ((branding === null || branding === void 0 ? void 0 : branding.allowCustomization) !== undefined) return branding.allowCustomization;
14471
+ return (branding === null || branding === void 0 ? void 0 : branding.fixed) === undefined;
14472
+ }
14473
+
14474
+ const ShellBrandingContext = /*#__PURE__*/createContext({
14475
+ allowCustomization: true
14476
+ });
14477
+ function ShellBrandingProvider({
14478
+ branding,
14479
+ children
14480
+ }) {
14481
+ const value = useMemo$1(() => ({
14482
+ branding,
14483
+ fixed: branding === null || branding === void 0 ? void 0 : branding.fixed,
14484
+ allowCustomization: isBrandCustomizationAllowed(branding)
14485
+ }), [branding]);
14486
+ return jsx(ShellBrandingContext.Provider, {
14487
+ value: value,
14488
+ children: children
14489
+ });
14490
+ }
14491
+ /**
14492
+ * Restituisce la configurazione di branding corrente.
14493
+ * Se il progetto consumer non ha configurato nulla, la personalizzazione è permessa
14494
+ * e non esiste nessun brand fisso (comportamento storico).
14495
+ */
14496
+ function useShellBranding() {
14497
+ return useContext(ShellBrandingContext);
14498
+ }
14499
+ /**
14500
+ * Risolve logo e colori da usare nella chrome della shell:
14501
+ * - se è impostato un brand fisso vince quello (nessuna chiamata al backend);
14502
+ * - altrimenti si usa la configurazione salvata lato server (comportamento storico).
14503
+ */
14504
+ function useShellBrandSurface() {
14505
+ const {
14506
+ fixed
14507
+ } = useShellBranding();
14508
+ const theme = useMantineTheme();
14509
+ const {
14510
+ configuration
14511
+ } = useAppSelector(state => state.layout);
14512
+ return useMemo$1(() => {
14513
+ var _a, _b, _c, _d, _e;
14514
+ const themeBackground = theme.colors['brand'][7];
14515
+ if (!fixed) {
14516
+ const _logoHeight = (_a = configuration === null || configuration === void 0 ? void 0 : configuration.logoHeight) !== null && _a !== void 0 ? _a : 24;
14517
+ return {
14518
+ background: themeBackground,
14519
+ topColor: themeBackground,
14520
+ logo: configuration === null || configuration === void 0 ? void 0 : configuration.logo,
14521
+ logoIcon: configuration === null || configuration === void 0 ? void 0 : configuration.logo,
14522
+ logoHeight: _logoHeight,
14523
+ logoIconHeight: _logoHeight,
14524
+ isFixed: false
14525
+ };
14526
+ }
14527
+ const logoHeight = (_b = fixed.logoHeight) !== null && _b !== void 0 ? _b : 24;
14528
+ return {
14529
+ background: (_c = resolveShellBackground(fixed.sidebarBackground)) !== null && _c !== void 0 ? _c : themeBackground,
14530
+ topColor: (_d = resolveShellBackgroundTopColor(fixed.sidebarBackground)) !== null && _d !== void 0 ? _d : themeBackground,
14531
+ logo: fixed.logoFull,
14532
+ logoIcon: fixed.logoIcon,
14533
+ logoHeight,
14534
+ logoIconHeight: (_e = fixed.logoIconHeight) !== null && _e !== void 0 ? _e : logoHeight,
14535
+ isFixed: true
14536
+ };
14537
+ }, [fixed, theme, configuration === null || configuration === void 0 ? void 0 : configuration.logo, configuration === null || configuration === void 0 ? void 0 : configuration.logoHeight]);
14538
+ }
14539
+
14411
14540
  function AppBar(props) {
14412
14541
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
14413
14542
  const {
14414
14543
  userInfo
14415
14544
  } = useSelector(state => state.user);
14416
14545
  const {
14417
- navbarOpened,
14418
- configuration
14546
+ navbarOpened
14419
14547
  } = useSelector(state => state.layout);
14420
14548
  const [jitApps, setJitApps] = React__default.useState([]);
14421
14549
  const [jitAppsLoaded, setJitAppsLoaded] = React__default.useState(false);
@@ -14423,6 +14551,8 @@ function AppBar(props) {
14423
14551
  const fluxoTheme = useMantineTheme();
14424
14552
  const navigate = useNavigate();
14425
14553
  const location = useLocation();
14554
+ // Logo e colori: brand fisso del progetto consumer se presente, altrimenti configurazione del backend
14555
+ const brandSurface = useShellBrandSurface();
14426
14556
  const [developmentMode, setDevelopmentMode] = React__default.useState(undefined);
14427
14557
  const [lastLocation, setLastLocation] = React__default.useState(undefined);
14428
14558
  const [userPopoverOpened, setUserPopoverOpened] = React__default.useState(false);
@@ -14503,7 +14633,7 @@ function AppBar(props) {
14503
14633
  gap: "md",
14504
14634
  style: {
14505
14635
  height: '48px',
14506
- backgroundColor: (_b = (_a = props.previewMode) === null || _a === void 0 ? void 0 : _a.headerColor) !== null && _b !== void 0 ? _b : fluxoTheme.colors['brand'][7],
14636
+ background: (_b = (_a = props.previewMode) === null || _a === void 0 ? void 0 : _a.headerColor) !== null && _b !== void 0 ? _b : brandSurface.background,
14507
14637
  display: 'flex',
14508
14638
  justifyContent: ((_d = (_c = props.shellUi.search) === null || _c === void 0 ? void 0 : _c.searchPosition) !== null && _d !== void 0 ? _d : ShellUISearchPosition.Left) === ShellUISearchPosition.Center ? 'flex-start' : 'space-between'
14509
14639
  },
@@ -14524,12 +14654,12 @@ function AppBar(props) {
14524
14654
  tabIndex: -1,
14525
14655
  to: props.previewMode ? '' : '/',
14526
14656
  style: {
14527
- maxHeight: (_f = (_e = props.previewMode) === null || _e === void 0 ? void 0 : _e.logoHeight) !== null && _f !== void 0 ? _f : configuration.logoHeight
14657
+ maxHeight: (_f = (_e = props.previewMode) === null || _e === void 0 ? void 0 : _e.logoHeight) !== null && _f !== void 0 ? _f : brandSurface.logoHeight
14528
14658
  },
14529
14659
  children: jsx("img", {
14530
- src: ((_g = props.previewMode) === null || _g === void 0 ? void 0 : _g.logo) ? props.previewMode.logo : configuration.logo,
14660
+ src: ((_g = props.previewMode) === null || _g === void 0 ? void 0 : _g.logo) ? props.previewMode.logo : brandSurface.logo,
14531
14661
  style: {
14532
- maxHeight: (_j = (_h = props.previewMode) === null || _h === void 0 ? void 0 : _h.logoHeight) !== null && _j !== void 0 ? _j : configuration.logoHeight
14662
+ maxHeight: (_j = (_h = props.previewMode) === null || _h === void 0 ? void 0 : _h.logoHeight) !== null && _j !== void 0 ? _j : brandSurface.logoHeight
14533
14663
  }
14534
14664
  })
14535
14665
  })]
@@ -15368,7 +15498,7 @@ const useFocusModeBackButton = isInFocusMode => {
15368
15498
  };
15369
15499
 
15370
15500
  function AppContent(props) {
15371
- var _a, _b, _c;
15501
+ var _a, _b, _c, _d;
15372
15502
  const sessionContext = useContext(ShellSessionContext);
15373
15503
  const currentSessionId = sessionContext.getCurrentSessionId();
15374
15504
  const isMobile = useMediaQuery('(max-width: 992px)');
@@ -15379,6 +15509,11 @@ function AppContent(props) {
15379
15509
  const {
15380
15510
  navbarOpened
15381
15511
  } = useAppSelector(state => state.layout);
15512
+ const theme = useMantineTheme();
15513
+ const isModernTabs = props.tabsVariant === 'modern';
15514
+ // Offset verticale della barra sessioni: esplicito se fornito dal layout,
15515
+ // altrimenti dedotto dal tipo di navigazione come da comportamento storico
15516
+ const chromeHeight = (_b = props.headerHeight) !== null && _b !== void 0 ? _b : props.shellUi.navigation === ShellUINavigation.Sidebar || props.shellUi.navigation === ShellUINavigation.SidebarMinimal || isMobile ? 48 : 88;
15382
15517
  // Hook personalizzati per gestire le diverse responsabilità
15383
15518
  useDocumentTitleManager(props.withMultipleSessions, sessionContext);
15384
15519
  useScrollPositionManager(props.withMultipleSessions, currentSessionId);
@@ -15424,7 +15559,7 @@ function AppContent(props) {
15424
15559
  useFlxNavigate();
15425
15560
  // Determina se la sessione corrente è in focus mode
15426
15561
  const currentSession = sessionContext.sessions().find(s => s.id === currentSessionId);
15427
- const isCurrentSessionInFocusMode = (_b = currentSession === null || currentSession === void 0 ? void 0 : currentSession.focusMode) !== null && _b !== void 0 ? _b : false;
15562
+ const isCurrentSessionInFocusMode = (_c = currentSession === null || currentSession === void 0 ? void 0 : currentSession.focusMode) !== null && _c !== void 0 ? _c : false;
15428
15563
  // Hook per bloccare il pulsante indietro del browser in focus mode
15429
15564
  useFocusModeBackButton(props.withMultipleSessions && isCurrentSessionInFocusMode);
15430
15565
  // Funzione per controllare se gli indicatori devono essere disabilitati
@@ -15484,7 +15619,7 @@ function AppContent(props) {
15484
15619
  }, [currentSessionId, props.withMultipleSessions, scrollToActiveTab]);
15485
15620
  return jsxs("div", {
15486
15621
  style: {
15487
- top: props.shellUi.navigation === ShellUINavigation.Sidebar || isMobile ? 48 : 88
15622
+ top: chromeHeight
15488
15623
  },
15489
15624
  children: [props.withMultipleSessions ? jsxs(Tabs, {
15490
15625
  variant: 'none',
@@ -15494,11 +15629,11 @@ function AppContent(props) {
15494
15629
  children: [jsx(Box, {
15495
15630
  style: {
15496
15631
  position: 'fixed',
15497
- top: props.shellUi.navigation === ShellUINavigation.Sidebar || props.shellUi.navigation === ShellUINavigation.SidebarMinimal || isMobile ? 48 : 88,
15632
+ top: chromeHeight,
15498
15633
  zIndex: 99,
15499
15634
  background: '#ffffff',
15500
- borderBottom: '1px solid #e1e5e9',
15501
- boxShadow: '0 1px 3px rgba(0, 0, 0, 0.05)',
15635
+ borderBottom: isModernTabs ? '1px solid #eef0f4' : '1px solid #e1e5e9',
15636
+ boxShadow: isModernTabs ? 'none' : '0 1px 3px rgba(0, 0, 0, 0.05)',
15502
15637
  width: (() => {
15503
15638
  if (isMobile) return '100%';
15504
15639
  // Sidebar minimale: sempre 80px
@@ -15519,7 +15654,7 @@ function AppContent(props) {
15519
15654
  style: {
15520
15655
  display: 'flex',
15521
15656
  alignItems: 'center',
15522
- padding: '0 16px',
15657
+ padding: isModernTabs ? '0 12px' : '0 16px',
15523
15658
  minHeight: '48px'
15524
15659
  },
15525
15660
  children: [jsx(ActionIcon, {
@@ -15533,7 +15668,7 @@ function AppContent(props) {
15533
15668
  flexShrink: 0,
15534
15669
  opacity: indicatorStates.leftDisabled ? 0.4 : 0.7,
15535
15670
  transition: 'opacity 0.2s ease',
15536
- borderRadius: '0px',
15671
+ borderRadius: isModernTabs ? '6px' : '0px',
15537
15672
  '&:hover': {
15538
15673
  opacity: indicatorStates.leftDisabled ? 0.4 : 1,
15539
15674
  backgroundColor: 'rgba(0, 0, 0, 0.04)'
@@ -15579,7 +15714,24 @@ function AppContent(props) {
15579
15714
  },
15580
15715
  children: sessionContext.sessions().map(session => jsx(Tabs.Tab, {
15581
15716
  value: session.id,
15582
- style: {
15717
+ style: isModernTabs ? {
15718
+ position: 'relative',
15719
+ flexShrink: 0,
15720
+ whiteSpace: 'nowrap',
15721
+ minWidth: 'auto',
15722
+ padding: '0 10px 0 12px',
15723
+ height: '32px',
15724
+ marginRight: '4px',
15725
+ backgroundColor: session.id === currentSessionId ? theme.colors['brand'][0] : 'transparent',
15726
+ borderRadius: '6px',
15727
+ border: '1px solid transparent',
15728
+ color: session.id === currentSessionId ? theme.colors['brand'][7] : '#6b7280',
15729
+ fontSize: '13px',
15730
+ fontWeight: session.id === currentSessionId ? 600 : 500,
15731
+ transition: 'background-color 0.15s ease, color 0.15s ease',
15732
+ cursor: 'pointer',
15733
+ outline: 'none'
15734
+ } : {
15583
15735
  position: 'relative',
15584
15736
  flexShrink: 0,
15585
15737
  whiteSpace: 'nowrap',
@@ -15597,8 +15749,14 @@ function AppContent(props) {
15597
15749
  cursor: 'pointer',
15598
15750
  outline: 'none'
15599
15751
  },
15752
+ onMouseEnter: e => {
15753
+ if (isModernTabs && session.id !== currentSessionId) e.currentTarget.style.backgroundColor = '#f3f4f6';
15754
+ },
15755
+ onMouseLeave: e => {
15756
+ if (isModernTabs && session.id !== currentSessionId) e.currentTarget.style.backgroundColor = 'transparent';
15757
+ },
15600
15758
  children: jsxs(Group, {
15601
- gap: 8,
15759
+ gap: isModernTabs ? 6 : 8,
15602
15760
  wrap: "nowrap",
15603
15761
  style: {
15604
15762
  alignItems: 'center'
@@ -15608,7 +15766,7 @@ function AppContent(props) {
15608
15766
  component: 'span',
15609
15767
  variant: "transparent",
15610
15768
  disabled: session.focusMode,
15611
- color: "blue.6",
15769
+ color: isModernTabs ? 'gray.6' : 'blue.6',
15612
15770
  onClick: event => {
15613
15771
  event.stopPropagation();
15614
15772
  if (!session.focusMode) sessionContext.refreshSession(session.id);
@@ -15677,7 +15835,7 @@ function AppContent(props) {
15677
15835
  marginLeft: 12,
15678
15836
  marginRight: "auto",
15679
15837
  flexShrink: 0,
15680
- borderRadius: '0px',
15838
+ borderRadius: isModernTabs ? '6px' : '0px',
15681
15839
  transition: 'all 0.2s ease'
15682
15840
  },
15683
15841
  children: jsx(IconPlus, {
@@ -15694,7 +15852,7 @@ function AppContent(props) {
15694
15852
  outline: 'none',
15695
15853
  flexShrink: 0,
15696
15854
  marginLeft: 'auto',
15697
- borderRadius: '0px',
15855
+ borderRadius: isModernTabs ? '6px' : '0px',
15698
15856
  transition: 'all 0.2s ease',
15699
15857
  opacity: sessionContext.sessions().length <= 1 ? 0.3 : 1
15700
15858
  },
@@ -15713,7 +15871,7 @@ function AppContent(props) {
15713
15871
  flexShrink: 0,
15714
15872
  opacity: indicatorStates.rightDisabled ? 0.4 : 0.7,
15715
15873
  transition: 'opacity 0.2s ease',
15716
- borderRadius: '0px'
15874
+ borderRadius: isModernTabs ? '6px' : '0px'
15717
15875
  },
15718
15876
  children: jsx(IconChevronRight, {
15719
15877
  size: 18,
@@ -15740,7 +15898,7 @@ function AppContent(props) {
15740
15898
  value: true,
15741
15899
  children: jsx(Outlet, {})
15742
15900
  }), jsx(CloseSessionConfirmationModal, {
15743
- sessionTitle: sessionToClose ? ((_c = sessionContext.getSession(sessionToClose)) === null || _c === void 0 ? void 0 : _c.title) || '' : '',
15901
+ sessionTitle: sessionToClose ? ((_d = sessionContext.getSession(sessionToClose)) === null || _d === void 0 ? void 0 : _d.title) || '' : '',
15744
15902
  sessionId: sessionToClose || '',
15745
15903
  opened: confirmCloseModalOpen,
15746
15904
  onConfirm: confirmCloseTab,
@@ -17343,7 +17501,7 @@ if (DESCRIPTORS$8 && !('size' in URLSearchParamsPrototype)) {
17343
17501
  });
17344
17502
  }
17345
17503
 
17346
- var style$1 = {"control":"navbar-item-module_control__0EMhh","controlActive":"navbar-item-module_controlActive__0vk5y","controlSub":"navbar-item-module_controlSub__U-eSe","link":"navbar-item-module_link__sVkBe","linkActive":"navbar-item-module_linkActive__wxVqH","chevron":"navbar-item-module_chevron__-1UpS"};
17504
+ var style$1 = {"control":"navbar-item-module_control__0EMhh","controlActive":"navbar-item-module_controlActive__0vk5y","controlSub":"navbar-item-module_controlSub__U-eSe","link":"navbar-item-module_link__sVkBe","linkActive":"navbar-item-module_linkActive__wxVqH","chevron":"navbar-item-module_chevron__-1UpS","onColor":"navbar-item-module_onColor__1xLgm"};
17347
17505
 
17348
17506
  function NavBarItem({
17349
17507
  icon: Icon,
@@ -17352,7 +17510,8 @@ function NavBarItem({
17352
17510
  initiallyOpened,
17353
17511
  links,
17354
17512
  level,
17355
- isMinimal
17513
+ isMinimal,
17514
+ variant
17356
17515
  }) {
17357
17516
  const hasLinks = Array.isArray(links);
17358
17517
  const [opened, setOpened] = useState(initiallyOpened || false);
@@ -17365,6 +17524,19 @@ function NavBarItem({
17365
17524
  const colorScheme = useMantineColorScheme();
17366
17525
  const ChevronIcon = IconChevronLeft;
17367
17526
  const isMobile = useMediaQuery('(max-width: 992px)');
17527
+ const isOnColor = variant === 'onColor';
17528
+ /** Colore del testo/icona di una voce attiva */
17529
+ const activeColor = isOnColor ? '#fff' : colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6];
17530
+ /** Sfondo di una voce attiva */
17531
+ const activeBackground = isOnColor ? 'rgba(255, 255, 255, 0.18)' : colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][9] : theme.colors[theme.primaryColor][0];
17532
+ /** Colore del testo/icona di una voce non attiva */
17533
+ const idleColor = isOnColor ? 'rgba(255, 255, 255, 0.88)' : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9];
17534
+ /** Colore del testo dei sotto-elementi non attivi */
17535
+ const subIdleColor = isOnColor ? 'rgba(255, 255, 255, 0.80)' : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[7];
17536
+ /** Colore del bordo verticale dei sotto-elementi */
17537
+ const subBorderColor = isOnColor ? 'rgba(255, 255, 255, 0.25)' : colorScheme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3];
17538
+ /** Classe aggiuntiva per gli stati hover su sfondo colorato */
17539
+ const onColorClass = isOnColor ? style$1["onColor"] : '';
17368
17540
  // Funzione per verificare se un menu item è attivo considerando anche query parameters
17369
17541
  const isActive = itemRouterLink => {
17370
17542
  if (!itemRouterLink) return false;
@@ -17421,17 +17593,18 @@ function NavBarItem({
17421
17593
  routerLink: link.routerLink,
17422
17594
  initiallyOpened: false,
17423
17595
  level: level + 1,
17424
- isMinimal: isMinimal
17596
+ isMinimal: isMinimal,
17597
+ variant: variant
17425
17598
  }, link.label + '_' + i);
17426
17599
  }
17427
17600
  if ((_a = link.routerLink) === null || _a === void 0 ? void 0 : _a.toLowerCase().startsWith('http')) {
17428
17601
  return jsx(Link, {
17429
- className: style$1["link"],
17602
+ className: `${style$1["link"]} ${onColorClass}`,
17430
17603
  style: {
17431
17604
  marginTop: 8,
17432
17605
  paddingLeft: 16,
17433
- color: colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[7],
17434
- borderLeft: `1px solid ${colorScheme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3]}`
17606
+ color: subIdleColor,
17607
+ borderLeft: `1px solid ${subBorderColor}`
17435
17608
  },
17436
17609
  onClick: () => {
17437
17610
  if (isMobile) FluxoStateDispatcher.dispatchCloseNavbar();
@@ -17443,13 +17616,13 @@ function NavBarItem({
17443
17616
  } else {
17444
17617
  const linkIsActive = isActive(link.routerLink);
17445
17618
  return jsx(Link, {
17446
- className: `${style$1["link"]} ${linkIsActive ? style$1["linkActive"] : ""}`,
17619
+ className: `${style$1["link"]} ${linkIsActive ? style$1["linkActive"] : ""} ${onColorClass}`,
17447
17620
  style: {
17448
17621
  marginTop: 8,
17449
17622
  paddingLeft: 16,
17450
- color: linkIsActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[7],
17451
- backgroundColor: linkIsActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][9] : theme.colors[theme.primaryColor][0] : 'transparent',
17452
- borderLeft: `1px solid ${colorScheme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3]}`
17623
+ color: linkIsActive ? activeColor : subIdleColor,
17624
+ backgroundColor: linkIsActive ? activeBackground : 'transparent',
17625
+ borderLeft: `1px solid ${subBorderColor}`
17453
17626
  },
17454
17627
  state: {
17455
17628
  title: link.label
@@ -17568,10 +17741,10 @@ function NavBarItem({
17568
17741
  if (isMobile) FluxoStateDispatcher.dispatchCloseNavbar();
17569
17742
  }
17570
17743
  },
17571
- className: `${level === 0 ? style$1["control"] : style$1["controlSub"]} ${isItemActive ? style$1["controlActive"] : ""}`,
17744
+ className: `${level === 0 ? style$1["control"] : style$1["controlSub"]} ${isItemActive ? style$1["controlActive"] : ""} ${onColorClass}`,
17572
17745
  style: {
17573
- backgroundColor: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][9] : theme.colors[theme.primaryColor][0] : 'transparent',
17574
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9]
17746
+ backgroundColor: isItemActive ? activeBackground : 'transparent',
17747
+ color: isItemActive ? activeColor : idleColor
17575
17748
  },
17576
17749
  children: jsxs(Group, {
17577
17750
  justify: 'space-between',
@@ -17585,7 +17758,7 @@ function NavBarItem({
17585
17758
  variant: "light",
17586
17759
  style: {
17587
17760
  background: 'transparent',
17588
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : 'inherit'
17761
+ color: isItemActive ? activeColor : 'inherit'
17589
17762
  },
17590
17763
  size: 30,
17591
17764
  children: Icon
@@ -17624,7 +17797,7 @@ function NavBarItem({
17624
17797
  children: jsx(UnstyledButton, {
17625
17798
  mt: 2,
17626
17799
  mb: 2,
17627
- className: `${style$1["control"]} ${isItemActive ? style$1["controlActive"] : ""}`,
17800
+ className: `${style$1["control"]} ${isItemActive ? style$1["controlActive"] : ""} ${onColorClass}`,
17628
17801
  style: {
17629
17802
  width: 60,
17630
17803
  height: 48,
@@ -17632,14 +17805,14 @@ function NavBarItem({
17632
17805
  display: 'flex',
17633
17806
  justifyContent: 'center',
17634
17807
  alignItems: 'center',
17635
- backgroundColor: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][9] : theme.colors[theme.primaryColor][0] : 'transparent',
17636
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9]
17808
+ backgroundColor: isItemActive ? activeBackground : 'transparent',
17809
+ color: isItemActive ? activeColor : idleColor
17637
17810
  },
17638
17811
  children: jsx(ThemeIcon, {
17639
17812
  variant: "light",
17640
17813
  style: {
17641
17814
  background: 'transparent',
17642
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : 'inherit'
17815
+ color: isItemActive ? activeColor : 'inherit'
17643
17816
  },
17644
17817
  size: 30,
17645
17818
  children: Icon
@@ -17672,7 +17845,7 @@ function NavBarItem({
17672
17845
  }
17673
17846
  if (isMobile) FluxoStateDispatcher.dispatchCloseNavbar();
17674
17847
  },
17675
- className: `${style$1["control"]} ${isItemActive ? style$1["controlActive"] : ""}`,
17848
+ className: `${style$1["control"]} ${isItemActive ? style$1["controlActive"] : ""} ${onColorClass}`,
17676
17849
  style: {
17677
17850
  width: 60,
17678
17851
  height: 48,
@@ -17680,14 +17853,14 @@ function NavBarItem({
17680
17853
  display: 'flex',
17681
17854
  justifyContent: 'center',
17682
17855
  alignItems: 'center',
17683
- backgroundColor: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][9] : theme.colors[theme.primaryColor][0] : 'transparent',
17684
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : colorScheme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9]
17856
+ backgroundColor: isItemActive ? activeBackground : 'transparent',
17857
+ color: isItemActive ? activeColor : idleColor
17685
17858
  },
17686
17859
  children: jsx(ThemeIcon, {
17687
17860
  variant: "light",
17688
17861
  style: {
17689
17862
  background: 'transparent',
17690
- color: isItemActive ? colorScheme.colorScheme === 'dark' ? theme.colors[theme.primaryColor][4] : theme.colors[theme.primaryColor][6] : 'inherit'
17863
+ color: isItemActive ? activeColor : 'inherit'
17691
17864
  },
17692
17865
  size: 30,
17693
17866
  children: Icon
@@ -17704,8 +17877,9 @@ function Navbar(props) {
17704
17877
  appMenu,
17705
17878
  navbarOpened
17706
17879
  } = useSelector(state => state.layout);
17707
- const fluxoTheme = useMantineTheme();
17708
17880
  useContext(ShellSessionContext);
17881
+ // Sfondo della sidebar: brand fisso del progetto consumer se presente, altrimenti colore del tema
17882
+ const brandSurface = useShellBrandSurface();
17709
17883
  const getPermittedNavBarItems = () => {
17710
17884
  const permittedNavBarItems = appMenu === null || appMenu === void 0 ? void 0 : appMenu.filter(a => {
17711
17885
  var _a;
@@ -17735,7 +17909,7 @@ function Navbar(props) {
17735
17909
  left: 0,
17736
17910
  width: 248,
17737
17911
  height: 'calc(100vh - 40px)',
17738
- background: fluxoTheme.colors['brand'][7],
17912
+ background: brandSurface.background,
17739
17913
  zIndex: 196,
17740
17914
  pointerEvents: 'none'
17741
17915
  }
@@ -17746,7 +17920,7 @@ function Navbar(props) {
17746
17920
  left: 0,
17747
17921
  width: 64,
17748
17922
  height: 'calc(100vh - 40px)',
17749
- background: fluxoTheme.colors['brand'][7],
17923
+ background: brandSurface.background,
17750
17924
  zIndex: 196,
17751
17925
  pointerEvents: 'none'
17752
17926
  }
@@ -18478,6 +18652,1138 @@ function safeParse(s) {
18478
18652
  }
18479
18653
  }
18480
18654
 
18655
+ /**
18656
+ * Wrapper condiviso dai layout della shell: il RavifyProvider viene montato
18657
+ * solo per gli utenti con accesso amministrativo.
18658
+ */
18659
+ const WithRavifyProvider = ({
18660
+ children,
18661
+ hasAdminAccess,
18662
+ fluxoClientConfig
18663
+ }) => {
18664
+ if (hasAdminAccess) {
18665
+ return jsx(RavifyProvider, {
18666
+ fluxoClientConfig: fluxoClientConfig,
18667
+ children: children
18668
+ });
18669
+ }
18670
+ return children;
18671
+ };
18672
+
18673
+ /**
18674
+ * Overlay di blocco applicazione mostrato quando la connessione WebSocket è persa.
18675
+ * Condiviso da tutti i layout della shell.
18676
+ */
18677
+ function DisconnectionOverlay({
18678
+ maxAttemptsReached,
18679
+ reconnectAttempts,
18680
+ isRetrying,
18681
+ onRetry
18682
+ }) {
18683
+ return jsx(Overlay, {
18684
+ opacity: 1,
18685
+ color: "#ffffff",
18686
+ zIndex: 9999,
18687
+ style: {
18688
+ position: 'fixed',
18689
+ top: 0,
18690
+ left: 0,
18691
+ right: 0,
18692
+ bottom: 0
18693
+ },
18694
+ children: jsxs(Stack, {
18695
+ justify: "center",
18696
+ align: "center",
18697
+ gap: "lg",
18698
+ style: {
18699
+ height: '100vh'
18700
+ },
18701
+ children: [jsxs(Stack, {
18702
+ gap: "md",
18703
+ align: "center",
18704
+ children: [jsx(ThemeIcon, {
18705
+ size: 72,
18706
+ radius: "md",
18707
+ variant: "light",
18708
+ color: maxAttemptsReached ? 'red' : 'orange',
18709
+ style: {
18710
+ backgroundColor: maxAttemptsReached ? '#fff5f5' : '#fff4e6',
18711
+ border: maxAttemptsReached ? '1px solid #ffc9c9' : '1px solid #ffe8cc'
18712
+ },
18713
+ children: jsx(IconPlugConnectedX, {
18714
+ size: 36,
18715
+ stroke: 1.8
18716
+ })
18717
+ }), jsxs(Stack, {
18718
+ gap: "xs",
18719
+ align: "center",
18720
+ mt: "xs",
18721
+ children: [jsx(Text, {
18722
+ size: "xl",
18723
+ fw: 600,
18724
+ c: "dark.8",
18725
+ ta: "center",
18726
+ children: maxAttemptsReached ? 'Impossibile riconnettersi' : 'Connessione al server persa'
18727
+ }), jsx(Text, {
18728
+ size: "sm",
18729
+ c: "dimmed",
18730
+ ta: "center",
18731
+ maw: 420,
18732
+ style: {
18733
+ lineHeight: 1.5
18734
+ },
18735
+ children: maxAttemptsReached ? 'Non è stato possibile ristabilire la connessione dopo multipli tentativi. Verifica la tua connessione internet e riprova.' : "La connessione al server è stata interrotta. Per evitare la perdita di dati, l'applicazione è stata bloccata."
18736
+ })]
18737
+ })]
18738
+ }), maxAttemptsReached ? jsxs(Stack, {
18739
+ gap: "md",
18740
+ align: "center",
18741
+ mt: "md",
18742
+ children: [jsx(Button, {
18743
+ size: "lg",
18744
+ variant: "filled",
18745
+ color: "blue",
18746
+ loading: isRetrying,
18747
+ onClick: onRetry,
18748
+ leftSection: !isRetrying && jsx(IconRefresh, {
18749
+ size: 20
18750
+ }),
18751
+ style: {
18752
+ minWidth: 220,
18753
+ height: 50,
18754
+ fontSize: '16px',
18755
+ fontWeight: 600,
18756
+ boxShadow: '0 4px 12px rgba(37, 99, 235, 0.2)',
18757
+ transition: 'all 0.2s ease'
18758
+ },
18759
+ styles: {
18760
+ root: {
18761
+ '&:hover': {
18762
+ transform: 'translateY(-2px)',
18763
+ boxShadow: '0 6px 16px rgba(37, 99, 235, 0.3)'
18764
+ },
18765
+ '&:active': {
18766
+ transform: 'translateY(0)'
18767
+ }
18768
+ }
18769
+ },
18770
+ children: isRetrying ? 'Riconnessione...' : 'Riprova connessione'
18771
+ }), jsx(Text, {
18772
+ size: "xs",
18773
+ c: "dimmed",
18774
+ ta: "center",
18775
+ style: {
18776
+ marginTop: 8
18777
+ },
18778
+ children: "Oppure ricarica la pagina (F5)"
18779
+ })]
18780
+ }) : jsxs(Group, {
18781
+ gap: "sm",
18782
+ mt: "md",
18783
+ px: "md",
18784
+ py: "xs",
18785
+ style: {
18786
+ backgroundColor: '#f8f9fa',
18787
+ borderRadius: '6px',
18788
+ border: '1px solid #e9ecef'
18789
+ },
18790
+ children: [jsx(Loader, {
18791
+ size: "sm"
18792
+ }), jsxs(Stack, {
18793
+ gap: 2,
18794
+ children: [jsx(Text, {
18795
+ size: "sm",
18796
+ c: "dark.6",
18797
+ fw: 500,
18798
+ children: "Riconnessione in corso..."
18799
+ }), jsxs(Text, {
18800
+ size: "xs",
18801
+ c: "dimmed",
18802
+ children: ["Tentativo ", reconnectAttempts, " di", ' ', FluxoClientSys.Instance.sessionHub.maxReconnectAttemptsLimit]
18803
+ })]
18804
+ })]
18805
+ }), jsxs(Group, {
18806
+ gap: 6,
18807
+ mt: "lg",
18808
+ children: [jsx(IconAlertTriangle, {
18809
+ size: 16,
18810
+ stroke: 1.5,
18811
+ color: "#868e96"
18812
+ }), jsx(Text, {
18813
+ size: "xs",
18814
+ c: "dimmed",
18815
+ children: maxAttemptsReached ? 'I tuoi dati non salvati potrebbero andare persi' : 'Non chiudere questa pagina'
18816
+ })]
18817
+ })]
18818
+ })
18819
+ });
18820
+ }
18821
+
18822
+ /**
18823
+ * Costanti geometriche del layout "modern".
18824
+ *
18825
+ * L'altezza complessiva della chrome superiore viene comunicata allo stato della shell
18826
+ * (`dispatchSetAppBarHeight`), così `useShellLayout`, `ShellPage` e `PageHeader`
18827
+ * calcolano gli offset corretti senza valori hardcoded.
18828
+ */
18829
+ /** Striscia superiore, a tutta larghezza, con il colore della sidebar */
18830
+ const MODERN_STRIP_HEIGHT = 8;
18831
+ /** Barra bianca con ricerca e azioni, arrotondata in alto a sinistra */
18832
+ const MODERN_BAR_HEIGHT = 56;
18833
+ /** Altezza totale della chrome superiore */
18834
+ const MODERN_HEADER_HEIGHT = MODERN_STRIP_HEIGHT + MODERN_BAR_HEIGHT;
18835
+ /**
18836
+ * Scala degli arrotondamenti del layout "modern".
18837
+ * Volutamente contenuta: morbido ma non "a pillola".
18838
+ */
18839
+ /** Controlli: bottoni, input, icone, tab, voci di menu */
18840
+ const MODERN_RADIUS_CONTROL = 6;
18841
+ /** Superfici grandi: contenuto, pannelli laterali, card di login */
18842
+ const MODERN_RADIUS_PANEL = 12;
18843
+ /** Raggio dell'angolo in alto a sinistra del contenuto */
18844
+ const MODERN_CONTENT_RADIUS = MODERN_RADIUS_PANEL;
18845
+ const MODERN_SIDEBAR_WIDTH_OPEN = 248;
18846
+ const MODERN_SIDEBAR_WIDTH_CLOSED = 64;
18847
+ const MODERN_ASIDE_WIDTH = 400;
18848
+ /** Larghezza della sidebar in funzione dello stato di apertura */
18849
+ function getModernSidebarWidth(navbarOpened) {
18850
+ return navbarOpened ? MODERN_SIDEBAR_WIDTH_OPEN : MODERN_SIDEBAR_WIDTH_CLOSED;
18851
+ }
18852
+
18853
+ /** Colore comune delle icone della barra: un solo grigio, niente accenti sparsi */
18854
+ const ACTION_ICON_COLOR = '#5b6573';
18855
+ /**
18856
+ * Barra superiore del layout "modern".
18857
+ *
18858
+ * È composta da due parti:
18859
+ * - una striscia del colore della sidebar che prosegue a tutta larghezza in alto;
18860
+ * - una barra bianca arrotondata in alto a sinistra, che apre il contenuto.
18861
+ */
18862
+ function ModernAppBar(props) {
18863
+ var _a, _b, _c, _d, _e, _f;
18864
+ const {
18865
+ userInfo
18866
+ } = useSelector(state => state.user);
18867
+ const {
18868
+ navbarOpened
18869
+ } = useSelector(state => state.layout);
18870
+ const [jitApps, setJitApps] = React__default.useState([]);
18871
+ const [jitAppsLoaded, setJitAppsLoaded] = React__default.useState(false);
18872
+ const [jitAppsDrawerOpened, setJitAppsDrawerOpened] = React__default.useState(false);
18873
+ const [developmentMode, setDevelopmentMode] = React__default.useState(undefined);
18874
+ const [lastLocation, setLastLocation] = React__default.useState(undefined);
18875
+ const [userPopoverOpened, setUserPopoverOpened] = React__default.useState(false);
18876
+ const fluxoTheme = useMantineTheme();
18877
+ const navigate = useNavigate();
18878
+ const location = useLocation();
18879
+ const isMobile = useMediaQuery('(max-width: 992px)');
18880
+ const surface = useShellBrandSurface();
18881
+ const searchPosition = (_b = (_a = props.shellUi.search) === null || _a === void 0 ? void 0 : _a.searchPosition) !== null && _b !== void 0 ? _b : ShellUISearchPosition.Left;
18882
+ const isCenterSearch = searchPosition === ShellUISearchPosition.Center;
18883
+ const appJitManager = new AppJitManager();
18884
+ // Stessa scorciatoia del layout classico per aprire/chiudere la sidebar
18885
+ useHotkeys([['mod + o', () => {
18886
+ if (navbarOpened) FluxoStateDispatcher.dispatchCloseNavbar();else FluxoStateDispatcher.dispatchOpenNavbar();
18887
+ }]]);
18888
+ useEffect(() => {
18889
+ setJitApps(appJitManager.loadAppConfigurations());
18890
+ setJitAppsLoaded(true);
18891
+ }, []);
18892
+ useEffect(() => {
18893
+ if (!jitAppsLoaded) return;
18894
+ const splittedLocation = location.pathname.split('/');
18895
+ if (splittedLocation.length < 2) {
18896
+ setDevelopmentMode(false);
18897
+ return;
18898
+ }
18899
+ const found = jitApps.filter(a => a.developmentRoute === splittedLocation[1]);
18900
+ setDevelopmentMode(found.length > 0);
18901
+ if (lastLocation) {
18902
+ const splittedLastLocation = lastLocation.split('/');
18903
+ const foundInLastLocation = jitApps.filter(a => a.developmentRoute === splittedLastLocation[1]);
18904
+ if (foundInLastLocation.length > 0 && found.length === 0 || foundInLastLocation.length === 0 && found.length > 0) {
18905
+ navigate(0);
18906
+ }
18907
+ }
18908
+ setLastLocation(location.pathname);
18909
+ }, [location, jitApps]);
18910
+ const logout = () => {
18911
+ FluxoClientSys.Instance.auth.logout();
18912
+ };
18913
+ const goToMyProfile = () => {
18914
+ navigate('/me', {
18915
+ state: {
18916
+ title: 'Il mio profilo'
18917
+ }
18918
+ });
18919
+ setUserPopoverOpened(false);
18920
+ };
18921
+ const refreshJitApps = app => {
18922
+ appJitManager.refreshApp(app).then(result => {
18923
+ if (result) {
18924
+ setJitApps(appJitManager.loadAppConfigurations());
18925
+ showNotification({
18926
+ title: 'Applicazione aggiornata',
18927
+ message: `L'applicazione ${app.name} è stata aggiornata correttamente`,
18928
+ color: 'green',
18929
+ icon: jsx(IconRefresh, {})
18930
+ });
18931
+ } else {
18932
+ showNotification({
18933
+ title: 'Errore',
18934
+ message: `L'applicazione ${app.name} non è stata aggiornata. Verifica che la JIT App sia attiva e raggiungibile e che il file di configurazione sia corretto.`,
18935
+ color: 'red',
18936
+ icon: jsx(IconRefresh, {})
18937
+ });
18938
+ }
18939
+ });
18940
+ };
18941
+ return jsx(AppShell.Header, {
18942
+ id: 'fluxo-shell-modern-app-bar',
18943
+ withBorder: false,
18944
+ zIndex: 199,
18945
+ style: {
18946
+ position: 'fixed',
18947
+ top: 0,
18948
+ left: props.sidebarWidth,
18949
+ width: `calc(100% - ${props.sidebarWidth}px)`,
18950
+ height: MODERN_HEADER_HEIGHT,
18951
+ border: 'none',
18952
+ /* la striscia in alto prosegue il colore della sidebar */
18953
+ background: surface.topColor
18954
+ },
18955
+ children: jsxs(Box, {
18956
+ style: {
18957
+ height: MODERN_BAR_HEIGHT,
18958
+ marginTop: MODERN_STRIP_HEIGHT,
18959
+ background: '#fff',
18960
+ borderTopLeftRadius: isMobile ? 0 : MODERN_CONTENT_RADIUS,
18961
+ borderBottom: '1px solid #edf0f5',
18962
+ display: 'flex',
18963
+ alignItems: 'center',
18964
+ gap: 16,
18965
+ paddingLeft: 20,
18966
+ paddingRight: 20,
18967
+ position: 'relative'
18968
+ },
18969
+ children: [jsxs(Group, {
18970
+ gap: 8,
18971
+ wrap: 'nowrap',
18972
+ style: {
18973
+ flexShrink: 0,
18974
+ minWidth: 0
18975
+ },
18976
+ children: [isMobile && jsx(Burger, {
18977
+ tabIndex: -1,
18978
+ size: 'sm',
18979
+ color: ACTION_ICON_COLOR,
18980
+ opened: navbarOpened,
18981
+ title: 'Menu',
18982
+ onClick: () => {
18983
+ if (navbarOpened) FluxoStateDispatcher.dispatchCloseNavbar();else FluxoStateDispatcher.dispatchOpenNavbar();
18984
+ }
18985
+ }), !isCenterSearch && jsx(Box, {
18986
+ className: 'flxModernSearchSlot',
18987
+ children: jsx(SearchBar, {
18988
+ disabled: false,
18989
+ shellUi: props.shellUi
18990
+ })
18991
+ })]
18992
+ }), isCenterSearch && jsx(Box, {
18993
+ className: 'flxModernSearchSlot',
18994
+ style: {
18995
+ position: 'absolute',
18996
+ left: '50%',
18997
+ transform: 'translateX(-50%)',
18998
+ width: 'min(640px, calc(100% - 360px))',
18999
+ display: 'flex',
19000
+ justifyContent: 'center'
19001
+ },
19002
+ children: jsx(SearchBar, {
19003
+ disabled: false,
19004
+ shellUi: props.shellUi
19005
+ })
19006
+ }), jsxs(Group, {
19007
+ gap: 4,
19008
+ wrap: 'nowrap',
19009
+ justify: 'flex-end',
19010
+ style: {
19011
+ flexShrink: 0,
19012
+ marginLeft: 'auto'
19013
+ },
19014
+ children: [developmentMode && jsx(Badge, {
19015
+ tabIndex: -1,
19016
+ color: 'red',
19017
+ mr: 8,
19018
+ children: "Development mode"
19019
+ }), props.isAiEnabled && jsx(Tooltip, {
19020
+ label: props.aiAsideOpened ? 'Chiudi assistente AI' : 'Apri assistente AI',
19021
+ position: 'bottom',
19022
+ children: jsx(ActionIcon, {
19023
+ tabIndex: -1,
19024
+ size: 34,
19025
+ radius: MODERN_RADIUS_CONTROL,
19026
+ variant: props.aiAsideOpened ? 'light' : 'subtle',
19027
+ color: props.aiAsideOpened ? undefined : 'gray',
19028
+ onClick: props.onAiAsideToggle,
19029
+ style: {
19030
+ color: props.aiAsideOpened ? undefined : ACTION_ICON_COLOR
19031
+ },
19032
+ children: jsx(IconSparkles2, {
19033
+ size: 20
19034
+ })
19035
+ })
19036
+ }), jsx(FrontendSwitch, {
19037
+ iconColor: ACTION_ICON_COLOR
19038
+ }), jitApps && jitApps.length > 0 && jsxs(Fragment, {
19039
+ children: [jsx(ActionIcon, {
19040
+ tabIndex: -1,
19041
+ size: 34,
19042
+ radius: MODERN_RADIUS_CONTROL,
19043
+ variant: 'subtle',
19044
+ color: 'gray',
19045
+ onClick: () => setJitAppsDrawerOpened(true),
19046
+ children: jsx(IconApps, {
19047
+ color: ACTION_ICON_COLOR,
19048
+ size: 20
19049
+ })
19050
+ }), jsx(Drawer, {
19051
+ title: 'Navigazione (App JIT)',
19052
+ position: 'right',
19053
+ opened: jitAppsDrawerOpened,
19054
+ onClose: () => setJitAppsDrawerOpened(false),
19055
+ children: jsx("div", {
19056
+ children: jitApps.map((app, index) => jsx(DataCard, {
19057
+ padded: false,
19058
+ title: app.name,
19059
+ actions: [{
19060
+ icon: jsx(IconRefresh, {
19061
+ size: 18
19062
+ }),
19063
+ onClick: () => refreshJitApps(app)
19064
+ }],
19065
+ children: app.menu.map((group, groupIndex) => {
19066
+ var _a, _b;
19067
+ return jsx(React__default.Fragment, {
19068
+ children: jsx(NavLink, {
19069
+ leftSection: jsx(Badge, {
19070
+ size: "xs",
19071
+ variant: "filled",
19072
+ color: fluxoTheme.colors['brand'][7],
19073
+ w: 16,
19074
+ h: 16,
19075
+ p: 0,
19076
+ children: group.items ? (_a = group.items) === null || _a === void 0 ? void 0 : _a.length : 0
19077
+ }),
19078
+ rightSection: jsx(IconChevronRight, {
19079
+ size: 16
19080
+ }),
19081
+ label: group.name,
19082
+ children: (_b = group.items) === null || _b === void 0 ? void 0 : _b.map((feature, featureIndex) => jsx(NavLink, {
19083
+ onClick: () => navigate(`${app.developmentRoute}/${feature.route}`),
19084
+ label: feature.name,
19085
+ leftSection: jsx(IconLink, {
19086
+ size: 16
19087
+ })
19088
+ }, `${feature.name}_${featureIndex}`))
19089
+ })
19090
+ }, `${group.name}_${groupIndex}`);
19091
+ })
19092
+ }, index))
19093
+ })
19094
+ })]
19095
+ }), jsx(Divider, {
19096
+ orientation: 'vertical',
19097
+ my: 14,
19098
+ mx: 8,
19099
+ color: '#edf0f5'
19100
+ }), jsxs(Popover, {
19101
+ onDismiss: () => setUserPopoverOpened(false),
19102
+ opened: userPopoverOpened,
19103
+ position: 'bottom-end',
19104
+ children: [jsx(Popover.Target, {
19105
+ children: jsxs(Avatar, {
19106
+ onClick: () => setUserPopoverOpened(true),
19107
+ tabIndex: -1,
19108
+ style: {
19109
+ cursor: 'pointer'
19110
+ },
19111
+ color: "cyan",
19112
+ radius: "xl",
19113
+ size: 32,
19114
+ children: [(_c = userInfo === null || userInfo === void 0 ? void 0 : userInfo.FirstName) === null || _c === void 0 ? void 0 : _c.substr(0, 1), (_d = userInfo === null || userInfo === void 0 ? void 0 : userInfo.LastName) === null || _d === void 0 ? void 0 : _d.substr(0, 1)]
19115
+ })
19116
+ }), jsx(Popover.Dropdown, {
19117
+ w: 300,
19118
+ children: jsxs(Stack, {
19119
+ gap: 12,
19120
+ children: [jsx(Center, {
19121
+ children: jsxs(Stack, {
19122
+ justify: 'center',
19123
+ align: 'center',
19124
+ children: [jsxs(Avatar, {
19125
+ color: "cyan",
19126
+ radius: "xl",
19127
+ size: 64,
19128
+ children: [(_e = userInfo === null || userInfo === void 0 ? void 0 : userInfo.FirstName) === null || _e === void 0 ? void 0 : _e.substr(0, 1), (_f = userInfo === null || userInfo === void 0 ? void 0 : userInfo.LastName) === null || _f === void 0 ? void 0 : _f.substr(0, 1)]
19129
+ }), jsxs(Text, {
19130
+ children: [userInfo === null || userInfo === void 0 ? void 0 : userInfo.FirstName, " ", userInfo === null || userInfo === void 0 ? void 0 : userInfo.LastName]
19131
+ })]
19132
+ })
19133
+ }), props.shellUi.security.showMyProfile && jsxs(Fragment, {
19134
+ children: [jsx(Button, {
19135
+ variant: 'subtle',
19136
+ onClick: () => goToMyProfile(),
19137
+ children: "Il mio profilo"
19138
+ }), jsx(Divider, {})]
19139
+ }), jsx(Button, {
19140
+ variant: 'subtle',
19141
+ onClick: () => logout(),
19142
+ children: "Esci"
19143
+ }), jsx(Divider, {}), jsxs(Stack, {
19144
+ gap: 8,
19145
+ align: 'center',
19146
+ children: [props.brandElement && jsx(Box, {
19147
+ style: {
19148
+ display: 'flex',
19149
+ alignItems: 'center',
19150
+ maxHeight: 28,
19151
+ overflow: 'hidden'
19152
+ },
19153
+ children: props.brandElement
19154
+ }), jsxs(Text, {
19155
+ c: "dimmed",
19156
+ fz: "xs",
19157
+ children: [props.brandName, " \u00A9", new Date().getFullYear()]
19158
+ })]
19159
+ })]
19160
+ })
19161
+ })]
19162
+ })]
19163
+ })]
19164
+ })
19165
+ });
19166
+ }
19167
+
19168
+ /** Palette del blocco: stessi valori usati dalle voci di menu su sfondo colorato */
19169
+ const ROW_COLOR = 'rgba(255, 255, 255, 0.88)';
19170
+ const MUTED_COLOR = 'rgba(255, 255, 255, 0.50)';
19171
+ const HOVER_BACKGROUND = 'rgba(255, 255, 255, 0.12)';
19172
+ const DIVIDER_COLOR = 'rgba(255, 255, 255, 0.12)';
19173
+ /**
19174
+ * Altezza di ogni riga del blocco, identica a sidebar aperta e compressa:
19175
+ * così l'area in fondo non cambia altezza quando si espande il menu.
19176
+ */
19177
+ const ROW_HEIGHT = 44;
19178
+ /** Larghezza del "binario" delle icone a sidebar compressa (64px di sidebar) */
19179
+ const COLLAPSED_ROW_WIDTH = 60;
19180
+ /** Larghezza dello slot icona: stessa di `NavBarItem`, così le label restano allineate */
19181
+ const ICON_SLOT = 30;
19182
+ /**
19183
+ * Riga del blocco inferiore.
19184
+ * Ricalca esattamente la geometria di `NavBarItem` (icona in un box da 30px + label a 8px)
19185
+ * così etichette e icone restano allineate con le voci di menu sopra.
19186
+ */
19187
+ function SidebarRow({
19188
+ icon,
19189
+ label,
19190
+ collapsed,
19191
+ to,
19192
+ onClick,
19193
+ iconColor
19194
+ }) {
19195
+ const commonHandlers = {
19196
+ onMouseEnter: e => {
19197
+ e.currentTarget.style.backgroundColor = HOVER_BACKGROUND;
19198
+ },
19199
+ onMouseLeave: e => {
19200
+ e.currentTarget.style.backgroundColor = 'transparent';
19201
+ }
19202
+ };
19203
+ const iconSlot = jsx(ThemeIcon, {
19204
+ variant: 'light',
19205
+ size: ICON_SLOT,
19206
+ style: {
19207
+ background: 'transparent',
19208
+ color: iconColor !== null && iconColor !== void 0 ? iconColor : 'inherit'
19209
+ },
19210
+ children: icon
19211
+ });
19212
+ const style = collapsed ? {
19213
+ width: COLLAPSED_ROW_WIDTH,
19214
+ height: ROW_HEIGHT,
19215
+ margin: '0 auto',
19216
+ display: 'flex',
19217
+ alignItems: 'center',
19218
+ justifyContent: 'center',
19219
+ color: ROW_COLOR,
19220
+ backgroundColor: 'transparent',
19221
+ transition: 'background-color 0.15s ease'
19222
+ } : {
19223
+ display: 'flex',
19224
+ alignItems: 'center',
19225
+ width: 'calc(100% - 16px)',
19226
+ height: ROW_HEIGHT,
19227
+ margin: '0 8px',
19228
+ padding: '0 12px',
19229
+ fontSize: 13,
19230
+ fontWeight: 500,
19231
+ textAlign: 'left',
19232
+ color: ROW_COLOR,
19233
+ backgroundColor: 'transparent',
19234
+ transition: 'background-color 0.15s ease'
19235
+ };
19236
+ const children = jsxs(Fragment, {
19237
+ children: [iconSlot, !collapsed && jsx(Box, {
19238
+ ml: '8px',
19239
+ children: label
19240
+ })]
19241
+ });
19242
+ const row = to ? jsx(UnstyledButton, Object.assign({
19243
+ component: Link,
19244
+ to: to,
19245
+ state: {
19246
+ title: label
19247
+ },
19248
+ "aria-label": label,
19249
+ style: style
19250
+ }, commonHandlers, {
19251
+ children: children
19252
+ })) : jsx(UnstyledButton, Object.assign({
19253
+ onClick: onClick,
19254
+ "aria-label": label,
19255
+ style: style
19256
+ }, commonHandlers, {
19257
+ children: children
19258
+ }));
19259
+ if (!collapsed) return row;
19260
+ return jsx(Tooltip, {
19261
+ label: label,
19262
+ position: 'right',
19263
+ offset: 10,
19264
+ withArrow: true,
19265
+ children: row
19266
+ });
19267
+ }
19268
+ /**
19269
+ * Blocco in fondo alla sidebar del layout "modern".
19270
+ *
19271
+ * Il layout "modern" non ha la footer bar: qui vivono le informazioni essenziali che
19272
+ * nel layout classico stanno nel footer (stato della connessione, stato utente,
19273
+ * link all'amministrazione, versione) più il tracciamento dell'attività utente.
19274
+ */
19275
+ function ModernSidebarFooter({
19276
+ appVersion,
19277
+ brandName,
19278
+ collapsed,
19279
+ withCollapseToggle
19280
+ }) {
19281
+ const {
19282
+ userInfo
19283
+ } = useAppSelector(state => state.user);
19284
+ const {
19285
+ userIdle,
19286
+ navbarOpened
19287
+ } = useAppSelector(state => state.layout);
19288
+ const {
19289
+ hasAdminAccess,
19290
+ hasDeveloperAccess,
19291
+ hasDataAnalystAccess
19292
+ } = useAppSelector(state => state.layout);
19293
+ const [wsPopoverOpened, setWsPopoverOpened] = useState(false);
19294
+ const [isWsConnected, setIsWsConnected] = useState(false);
19295
+ const [connectionId, setConnectionId] = useState(null);
19296
+ const [hasBeenConnected, setHasBeenConnected] = useState(false);
19297
+ const {
19298
+ isBeingWatched
19299
+ } = useScreenSharingContext();
19300
+ const idle = useIdle(600000); // 10 minuti
19301
+ const canAccessAdministration = hasAdminAccess || hasDeveloperAccess || hasDataAnalystAccess;
19302
+ // Monitora lo stato della connessione WebSocket
19303
+ useEffect(() => {
19304
+ const checkConnection = () => {
19305
+ const connected = FluxoClientSys.Instance.sessionHub.isConnected;
19306
+ setIsWsConnected(connected);
19307
+ if (connected) {
19308
+ setConnectionId(FluxoClientSys.Instance.sessionHub.connectionId);
19309
+ setHasBeenConnected(true);
19310
+ } else {
19311
+ setConnectionId(null);
19312
+ }
19313
+ };
19314
+ checkConnection();
19315
+ const interval = setInterval(checkConnection, 2000);
19316
+ return () => clearInterval(interval);
19317
+ }, []);
19318
+ useEffect(() => {
19319
+ if (idle) FluxoStateDispatcher.dispatchSetUserIdle();else FluxoStateDispatcher.dispatchUnsetUserIdle();
19320
+ }, [idle]);
19321
+ // Invia l'aggiornamento dell'attività utente al server quando cambia lo stato idle
19322
+ useEffect(() => {
19323
+ if (!isWsConnected) return;
19324
+ FluxoClientSys.Instance.sessionHub.invoke('UpdateUserActivity', !userIdle).catch(error => {
19325
+ console.error('Failed to update user activity:', error);
19326
+ });
19327
+ }, [userIdle, isWsConnected]);
19328
+ const statusColor = isWsConnected ? userIdle ? '#fab005' : '#40c057' : hasBeenConnected ? '#fa5252' : '#fd7e14';
19329
+ /** Etichetta estesa: tooltip e popover */
19330
+ const statusLabel = isWsConnected ? userIdle ? 'Connesso · utente inattivo' : 'Connesso' : hasBeenConnected ? 'Disconnesso' : 'In attesa...';
19331
+ /**
19332
+ * Etichetta in linea: quando è tutto a posto il pallino verde basta, quindi resta
19333
+ * solo la versione. Il testo compare unicamente quando c'è qualcosa da segnalare.
19334
+ */
19335
+ const statusInlineLabel = isWsConnected ? userIdle ? 'Inattivo' : undefined : hasBeenConnected ? 'Disconnesso' : 'Connessione...';
19336
+ const statusDot = jsx("span", {
19337
+ style: {
19338
+ width: 8,
19339
+ height: 8,
19340
+ borderRadius: '50%',
19341
+ backgroundColor: statusColor,
19342
+ flexShrink: 0,
19343
+ boxShadow: `0 0 0 3px ${statusColor}22`
19344
+ }
19345
+ });
19346
+ const statusDetails = jsx(Popover.Dropdown, {
19347
+ children: jsxs(Stack, {
19348
+ gap: 'xs',
19349
+ children: [jsxs(Group, {
19350
+ justify: 'space-between',
19351
+ children: [jsx(Text, {
19352
+ size: 'xs',
19353
+ fw: 600,
19354
+ children: "Stato connessione"
19355
+ }), jsx(Badge, {
19356
+ color: isWsConnected ? userIdle ? 'yellow' : 'green' : hasBeenConnected ? 'red' : 'orange',
19357
+ variant: 'light',
19358
+ size: 'xs',
19359
+ children: statusLabel
19360
+ })]
19361
+ }), jsx(Divider, {}), jsxs("div", {
19362
+ children: [jsx(Text, {
19363
+ size: 'xs',
19364
+ c: 'dimmed',
19365
+ mb: 4,
19366
+ children: "Utente connesso"
19367
+ }), jsxs(Text, {
19368
+ size: 'xs',
19369
+ fw: 500,
19370
+ children: [userInfo === null || userInfo === void 0 ? void 0 : userInfo.FirstName, " ", userInfo === null || userInfo === void 0 ? void 0 : userInfo.LastName]
19371
+ }), jsx(Text, {
19372
+ size: 'xs',
19373
+ c: 'dimmed',
19374
+ ff: 'monospace',
19375
+ children: userInfo === null || userInfo === void 0 ? void 0 : userInfo.UserId
19376
+ })]
19377
+ }), jsxs("div", {
19378
+ children: [jsx(Text, {
19379
+ size: 'xs',
19380
+ c: 'dimmed',
19381
+ mb: 4,
19382
+ children: "ID dispositivo"
19383
+ }), jsx(Text, {
19384
+ size: 'xs',
19385
+ ff: 'monospace',
19386
+ children: DeviceIdManager.getDeviceId().substring(0, 8)
19387
+ })]
19388
+ }), connectionId && jsxs("div", {
19389
+ children: [jsx(Text, {
19390
+ size: 'xs',
19391
+ c: 'dimmed',
19392
+ mb: 4,
19393
+ children: "Connection ID"
19394
+ }), jsx(Text, {
19395
+ size: 'xs',
19396
+ ff: 'monospace',
19397
+ children: connectionId.substring(0, 8)
19398
+ })]
19399
+ }), !isWsConnected && hasBeenConnected && jsx(Text, {
19400
+ size: 'xs',
19401
+ c: 'red',
19402
+ children: "La connessione WebSocket \u00E8 stata persa"
19403
+ }), !isWsConnected && !hasBeenConnected && jsx(Text, {
19404
+ size: 'xs',
19405
+ c: 'orange',
19406
+ children: "Connessione in corso..."
19407
+ }), jsx(Divider, {}), jsxs(Text, {
19408
+ size: 'xs',
19409
+ c: 'dimmed',
19410
+ children: [brandName, " \u00A9", new Date().getFullYear(), " \u00B7 V. ", appVersion]
19411
+ })]
19412
+ })
19413
+ });
19414
+ const toggleRow = withCollapseToggle && jsx(SidebarRow, {
19415
+ collapsed: collapsed,
19416
+ icon: navbarOpened ? jsx(IconLayoutSidebarLeftCollapse, {
19417
+ size: 20,
19418
+ stroke: 1.5
19419
+ }) : jsx(IconLayoutSidebarLeftExpand, {
19420
+ size: 20,
19421
+ stroke: 1.5
19422
+ }),
19423
+ label: navbarOpened ? 'Comprimi menu' : 'Espandi menu',
19424
+ onClick: () => {
19425
+ if (navbarOpened) FluxoStateDispatcher.dispatchCloseNavbar();else FluxoStateDispatcher.dispatchOpenNavbar();
19426
+ }
19427
+ });
19428
+ return jsxs(Box, {
19429
+ pb: 10,
19430
+ children: [isBeingWatched && !collapsed && jsx(Box, {
19431
+ px: 12,
19432
+ pb: 4,
19433
+ children: jsx(ScreenSharingWidget, {
19434
+ size: 'xs'
19435
+ })
19436
+ }), jsx(Divider, {
19437
+ my: 6,
19438
+ mx: collapsed ? 16 : 8,
19439
+ color: DIVIDER_COLOR
19440
+ }), isBeingWatched && collapsed && jsx(SidebarRow, {
19441
+ collapsed: true,
19442
+ icon: jsx(IconEye, {
19443
+ size: 20,
19444
+ stroke: 1.5
19445
+ }),
19446
+ iconColor: '#ff8787',
19447
+ label: 'Schermo sotto osservazione'
19448
+ }), canAccessAdministration && jsx(SidebarRow, {
19449
+ collapsed: collapsed,
19450
+ icon: jsx(IconSettings, {
19451
+ size: 20,
19452
+ stroke: 1.5
19453
+ }),
19454
+ label: 'Amministrazione',
19455
+ to: '/settings'
19456
+ }), toggleRow, jsxs(Group, {
19457
+ gap: 0,
19458
+ wrap: 'nowrap',
19459
+ justify: collapsed ? 'center' : undefined,
19460
+ style: {
19461
+ height: ROW_HEIGHT,
19462
+ margin: collapsed ? '0 auto' : '0 8px',
19463
+ width: collapsed ? COLLAPSED_ROW_WIDTH : 'calc(100% - 16px)'
19464
+ },
19465
+ children: [jsxs(Popover, {
19466
+ width: 280,
19467
+ position: collapsed ? 'right-end' : 'top-start',
19468
+ withArrow: true,
19469
+ shadow: 'md',
19470
+ opened: wsPopoverOpened,
19471
+ onChange: setWsPopoverOpened,
19472
+ children: [jsx(Popover.Target, {
19473
+ children: jsx(Tooltip, {
19474
+ label: statusLabel,
19475
+ position: collapsed ? 'right' : 'top-start',
19476
+ offset: 10,
19477
+ withArrow: true,
19478
+ children: jsxs(UnstyledButton, {
19479
+ "aria-label": statusLabel,
19480
+ onClick: () => setWsPopoverOpened(o => !o),
19481
+ style: {
19482
+ display: 'flex',
19483
+ alignItems: 'center',
19484
+ justifyContent: collapsed ? 'center' : undefined,
19485
+ flex: collapsed ? undefined : 1,
19486
+ minWidth: 0,
19487
+ height: ROW_HEIGHT,
19488
+ width: collapsed ? COLLAPSED_ROW_WIDTH : undefined,
19489
+ padding: collapsed ? 0 : '0 12px',
19490
+ backgroundColor: 'transparent',
19491
+ transition: 'background-color 0.15s ease'
19492
+ },
19493
+ onMouseEnter: e => {
19494
+ e.currentTarget.style.backgroundColor = HOVER_BACKGROUND;
19495
+ },
19496
+ onMouseLeave: e => {
19497
+ e.currentTarget.style.backgroundColor = 'transparent';
19498
+ },
19499
+ children: [jsx("span", {
19500
+ style: {
19501
+ width: collapsed ? 'auto' : ICON_SLOT,
19502
+ display: 'flex',
19503
+ alignItems: 'center',
19504
+ justifyContent: 'center',
19505
+ flexShrink: 0
19506
+ },
19507
+ children: statusDot
19508
+ }), !collapsed && jsxs(Text, {
19509
+ ml: '8px',
19510
+ size: '11px',
19511
+ c: MUTED_COLOR,
19512
+ truncate: 'end',
19513
+ children: [statusInlineLabel ? `${statusInlineLabel} · ` : '', "V. ", appVersion]
19514
+ })]
19515
+ })
19516
+ })
19517
+ }), statusDetails]
19518
+ }), canAccessAdministration && !collapsed && jsx(Box, {
19519
+ pr: 12,
19520
+ style: {
19521
+ flexShrink: 0,
19522
+ display: 'flex',
19523
+ alignItems: 'center'
19524
+ },
19525
+ children: jsx(MinimalStateViewer, {})
19526
+ })]
19527
+ }), canAccessAdministration && collapsed && jsx(Group, {
19528
+ justify: 'center',
19529
+ gap: 0,
19530
+ style: {
19531
+ width: COLLAPSED_ROW_WIDTH,
19532
+ margin: '0 auto'
19533
+ },
19534
+ children: jsx(MinimalStateViewer, {})
19535
+ })]
19536
+ });
19537
+ }
19538
+
19539
+ /**
19540
+ * Sidebar del layout "modern": colorata (colore fisso o gradiente del brand),
19541
+ * a tutta altezza, con logo in alto e toggle di apertura/chiusura in basso.
19542
+ */
19543
+ function ModernNavbar({
19544
+ brandName,
19545
+ appVersion
19546
+ }) {
19547
+ var _a, _b, _c;
19548
+ const {
19549
+ appMenu,
19550
+ navbarOpened
19551
+ } = useSelector(state => state.layout);
19552
+ const surface = useShellBrandSurface();
19553
+ const isMobile = useMediaQuery('(max-width: 992px)');
19554
+ const getPermittedNavBarItems = () => {
19555
+ var _a;
19556
+ const permittedNavBarItems = (_a = appMenu === null || appMenu === void 0 ? void 0 : appMenu.filter(a => {
19557
+ var _a;
19558
+ return !a.hasPermissions || FluxoClientSys.Instance.security.currentUser.hasPermissions((_a = a.permissions) !== null && _a !== void 0 ? _a : []);
19559
+ })) !== null && _a !== void 0 ? _a : [];
19560
+ if (!permittedNavBarItems.find(i => i.routerLink === '')) {
19561
+ permittedNavBarItems.unshift({
19562
+ label: 'Home',
19563
+ icon: 'Home',
19564
+ routerLink: '/',
19565
+ isGroup: false,
19566
+ featureIdentifier: 'sys-home'
19567
+ });
19568
+ }
19569
+ return permittedNavBarItems;
19570
+ };
19571
+ const logoSrc = navbarOpened ? (_a = surface.logo) !== null && _a !== void 0 ? _a : surface.logoIcon : (_b = surface.logoIcon) !== null && _b !== void 0 ? _b : surface.logo;
19572
+ const logoMaxHeight = navbarOpened ? surface.logoHeight : surface.logoIconHeight;
19573
+ return jsxs(AppShell.Navbar, {
19574
+ id: 'fluxo-shell-modern-sidebar',
19575
+ zIndex: 201,
19576
+ withBorder: false,
19577
+ style: {
19578
+ top: 0,
19579
+ height: '100dvh',
19580
+ background: surface.background,
19581
+ border: 'none',
19582
+ overflow: 'visible'
19583
+ },
19584
+ children: [jsx(AppShell.Section, {
19585
+ h: MODERN_HEADER_HEIGHT,
19586
+ pt: MODERN_STRIP_HEIGHT,
19587
+ px: navbarOpened ? 16 : 0,
19588
+ style: {
19589
+ flexShrink: 0
19590
+ },
19591
+ children: jsx(Group, {
19592
+ h: '100%',
19593
+ justify: navbarOpened ? 'flex-start' : 'center',
19594
+ gap: 8,
19595
+ wrap: 'nowrap',
19596
+ children: jsx(Link, {
19597
+ to: '/',
19598
+ tabIndex: -1,
19599
+ style: {
19600
+ display: 'flex',
19601
+ alignItems: 'center',
19602
+ maxHeight: logoMaxHeight
19603
+ },
19604
+ children: logoSrc ? jsx("img", {
19605
+ src: logoSrc,
19606
+ alt: brandName,
19607
+ style: {
19608
+ maxHeight: logoMaxHeight,
19609
+ maxWidth: navbarOpened ? 200 : 40
19610
+ }
19611
+ }) : jsx(Text, {
19612
+ fw: 700,
19613
+ c: '#fff',
19614
+ size: 'sm',
19615
+ children: navbarOpened ? brandName : (_c = brandName === null || brandName === void 0 ? void 0 : brandName.substring(0, 1)) === null || _c === void 0 ? void 0 : _c.toUpperCase()
19616
+ })
19617
+ })
19618
+ })
19619
+ }), jsx(AppShell.Section, {
19620
+ grow: true,
19621
+ my: 8,
19622
+ component: ScrollArea,
19623
+ className: 'custom-scrollbar',
19624
+ children: jsx(Stack, {
19625
+ justify: 'center',
19626
+ align: 'center',
19627
+ gap: 0,
19628
+ children: getPermittedNavBarItems().map((e, i) => {
19629
+ const IconComponent = e.icon ? IconFactory.getIcon(e.icon) : IconFactory.getIcon('Dashboard');
19630
+ return jsx(NavBarItem, {
19631
+ level: 0,
19632
+ routerLink: e.routerLink,
19633
+ icon: IconComponent,
19634
+ label: e.label,
19635
+ links: e.children && e.children.length > 0 ? e.children : undefined,
19636
+ isMinimal: !navbarOpened,
19637
+ variant: 'onColor'
19638
+ }, i);
19639
+ })
19640
+ })
19641
+ }), jsx(AppShell.Section, {
19642
+ style: {
19643
+ flexShrink: 0
19644
+ },
19645
+ children: jsx(ModernSidebarFooter, {
19646
+ appVersion: appVersion,
19647
+ brandName: brandName,
19648
+ collapsed: !navbarOpened,
19649
+ withCollapseToggle: !isMobile
19650
+ })
19651
+ })]
19652
+ });
19653
+ }
19654
+
19655
+ /**
19656
+ * Layout "modern": sidebar laterale colorata a tutta altezza, striscia dello stesso
19657
+ * colore che prosegue in alto a tutta larghezza e contenuto arrotondato in alto a sinistra.
19658
+ *
19659
+ * L'altezza complessiva della chrome superiore è identica a quella del layout classico
19660
+ * (48px), così tutti i componenti di pagina condivisi continuano a funzionare senza modifiche.
19661
+ */
19662
+ const ModernShellLayout = ({
19663
+ appVersion,
19664
+ brandName,
19665
+ brandElement,
19666
+ currentShellUI,
19667
+ navbarOpened,
19668
+ isMobile,
19669
+ hasAdminAccess,
19670
+ fluxoClientConfig,
19671
+ showDisconnectionOverlay,
19672
+ maxAttemptsReached,
19673
+ reconnectAttempts,
19674
+ isRetrying,
19675
+ handleManualRetry,
19676
+ isAiEnabled,
19677
+ aiAsideOpened,
19678
+ onAiAsideToggle
19679
+ }) => {
19680
+ var _a;
19681
+ const {
19682
+ isCurrentSessionInFocusMode
19683
+ } = useContext(ShellSessionContext);
19684
+ const sidebarWidth = getModernSidebarWidth(navbarOpened);
19685
+ const headerOffset = isMobile ? 0 : sidebarWidth;
19686
+ const chromeOverlayStyle = {
19687
+ position: 'fixed',
19688
+ pointerEvents: 'auto',
19689
+ cursor: 'not-allowed',
19690
+ userSelect: 'none',
19691
+ zIndex: 202,
19692
+ background: 'rgba(255, 255, 255, 0.12)',
19693
+ transition: 'opacity 180ms ease, backdrop-filter 180ms ease',
19694
+ backdropFilter: 'blur(2px) saturate(0.92)',
19695
+ WebkitBackdropFilter: 'blur(2px) saturate(0.92)'
19696
+ };
19697
+ return jsx(WithRavifyProvider, {
19698
+ hasAdminAccess: hasAdminAccess,
19699
+ fluxoClientConfig: fluxoClientConfig,
19700
+ children: jsx(AgentProvider, {
19701
+ children: jsxs(AppShell, {
19702
+ padding: 0,
19703
+ className: 'flxShellAppShellModern',
19704
+ layout: 'alt',
19705
+ header: {
19706
+ height: MODERN_HEADER_HEIGHT
19707
+ },
19708
+ navbar: {
19709
+ width: sidebarWidth,
19710
+ breakpoint: 'sm',
19711
+ collapsed: {
19712
+ mobile: !navbarOpened,
19713
+ desktop: false
19714
+ }
19715
+ },
19716
+ aside: {
19717
+ width: MODERN_ASIDE_WIDTH,
19718
+ breakpoint: 'sm',
19719
+ collapsed: {
19720
+ mobile: !isAiEnabled || !aiAsideOpened,
19721
+ desktop: !isAiEnabled || !aiAsideOpened
19722
+ }
19723
+ },
19724
+ transitionDuration: 0,
19725
+ styles: {
19726
+ main: {
19727
+ backgroundColor: '#fafbff'
19728
+ },
19729
+ aside: {
19730
+ zIndex: 200
19731
+ }
19732
+ },
19733
+ children: [jsx(ModernAppBar, {
19734
+ brandName: brandName,
19735
+ brandElement: brandElement,
19736
+ shellUi: currentShellUI,
19737
+ sidebarWidth: headerOffset,
19738
+ isAiEnabled: isAiEnabled,
19739
+ aiAsideOpened: aiAsideOpened,
19740
+ onAiAsideToggle: onAiAsideToggle
19741
+ }), jsx(ModernNavbar, {
19742
+ brandName: brandName,
19743
+ appVersion: appVersion
19744
+ }), isCurrentSessionInFocusMode && jsxs(Fragment, {
19745
+ children: [jsx("div", {
19746
+ "aria-hidden": true,
19747
+ style: Object.assign(Object.assign({}, chromeOverlayStyle), {
19748
+ top: MODERN_STRIP_HEIGHT,
19749
+ left: headerOffset,
19750
+ right: 0,
19751
+ height: MODERN_BAR_HEIGHT
19752
+ })
19753
+ }), !isMobile && jsx("div", {
19754
+ "aria-hidden": true,
19755
+ style: Object.assign(Object.assign({}, chromeOverlayStyle), {
19756
+ top: 0,
19757
+ left: 0,
19758
+ width: sidebarWidth,
19759
+ height: '100dvh',
19760
+ borderRight: '1px solid rgba(15, 23, 42, 0.08)'
19761
+ })
19762
+ })]
19763
+ }), jsx(AppShell.Main, {
19764
+ children: jsx(Suspense, {
19765
+ fallback: jsx(Loader, {}),
19766
+ children: jsx(AppContent, {
19767
+ shellUi: currentShellUI,
19768
+ withMultipleSessions: (_a = currentShellUI.withMultipleSessions) !== null && _a !== void 0 ? _a : false,
19769
+ asideWidth: isAiEnabled && aiAsideOpened ? MODERN_ASIDE_WIDTH : 0,
19770
+ headerHeight: MODERN_HEADER_HEIGHT,
19771
+ tabsVariant: 'modern'
19772
+ })
19773
+ })
19774
+ }), isAiEnabled && jsx(AppShell.Aside, {
19775
+ children: jsx(AiAgentAside, {})
19776
+ }), showDisconnectionOverlay && jsx(DisconnectionOverlay, {
19777
+ maxAttemptsReached: maxAttemptsReached,
19778
+ reconnectAttempts: reconnectAttempts,
19779
+ isRetrying: isRetrying,
19780
+ onRetry: handleManualRetry
19781
+ })]
19782
+ })
19783
+ })
19784
+ });
19785
+ };
19786
+
18481
19787
  // Context per evitare props drilling
18482
19788
  const ShellUIContext = /*#__PURE__*/createContext(null);
18483
19789
  const WithShellSessionProvider = ({
@@ -18500,19 +19806,21 @@ const WithShellSessionProvider = ({
18500
19806
  })
18501
19807
  });
18502
19808
  };
18503
- const WithRavifyProvider = ({
18504
- children,
18505
- hasAdminAccess,
18506
- fluxoClientConfig
18507
- }) => {
18508
- if (hasAdminAccess) {
18509
- return jsx(RavifyProvider, {
18510
- fluxoClientConfig: fluxoClientConfig,
18511
- children: children
18512
- });
18513
- }
18514
- return children;
18515
- };
19809
+ /**
19810
+ * Normalizza la configurazione `ui` risolta per il frontend corrente.
19811
+ *
19812
+ * Il layout "modern" usa sempre la geometria della sidebar minimale (64px chiusa /
19813
+ * 248px aperta), così tutti i componenti condivisi (ShellPage, PageHeader, AppContent)
19814
+ * calcolano correttamente offset e larghezze senza modifiche.
19815
+ */
19816
+ function normalizeShellUI(shellUi) {
19817
+ var _a;
19818
+ if (((_a = shellUi.layout) !== null && _a !== void 0 ? _a : ShellLayoutVariant.Classic) !== ShellLayoutVariant.Modern) return shellUi;
19819
+ if (shellUi.navigation === ShellUINavigation.SidebarMinimal) return shellUi;
19820
+ return Object.assign(Object.assign({}, shellUi), {
19821
+ navigation: ShellUINavigation.SidebarMinimal
19822
+ });
19823
+ }
18516
19824
  const FocusAwareShellLayout = ({
18517
19825
  appVersion,
18518
19826
  brandName,
@@ -18688,142 +19996,11 @@ const FocusAwareShellLayout = ({
18688
19996
  "aria-hidden": true,
18689
19997
  style: getShellChromeOverlayStyle('footer')
18690
19998
  })
18691
- }), showDisconnectionOverlay && jsx(Overlay, {
18692
- opacity: 1,
18693
- color: "#ffffff",
18694
- zIndex: 9999,
18695
- style: {
18696
- position: 'fixed',
18697
- top: 0,
18698
- left: 0,
18699
- right: 0,
18700
- bottom: 0
18701
- },
18702
- children: jsxs(Stack, {
18703
- justify: "center",
18704
- align: "center",
18705
- gap: "lg",
18706
- style: {
18707
- height: '100vh'
18708
- },
18709
- children: [jsxs(Stack, {
18710
- gap: "md",
18711
- align: "center",
18712
- children: [jsx(ThemeIcon, {
18713
- size: 72,
18714
- radius: "md",
18715
- variant: "light",
18716
- color: maxAttemptsReached ? 'red' : 'orange',
18717
- style: {
18718
- backgroundColor: maxAttemptsReached ? '#fff5f5' : '#fff4e6',
18719
- border: maxAttemptsReached ? '1px solid #ffc9c9' : '1px solid #ffe8cc'
18720
- },
18721
- children: jsx(IconPlugConnectedX, {
18722
- size: 36,
18723
- stroke: 1.8
18724
- })
18725
- }), jsxs(Stack, {
18726
- gap: "xs",
18727
- align: "center",
18728
- mt: "xs",
18729
- children: [jsx(Text, {
18730
- size: "xl",
18731
- fw: 600,
18732
- c: "dark.8",
18733
- ta: "center",
18734
- children: maxAttemptsReached ? 'Impossibile riconnettersi' : 'Connessione al server persa'
18735
- }), jsx(Text, {
18736
- size: "sm",
18737
- c: "dimmed",
18738
- ta: "center",
18739
- maw: 420,
18740
- style: {
18741
- lineHeight: 1.5
18742
- },
18743
- children: maxAttemptsReached ? 'Non è stato possibile ristabilire la connessione dopo multipli tentativi. Verifica la tua connessione internet e riprova.' : "La connessione al server è stata interrotta. Per evitare la perdita di dati, l'applicazione è stata bloccata."
18744
- })]
18745
- })]
18746
- }), maxAttemptsReached ? jsxs(Stack, {
18747
- gap: "md",
18748
- align: "center",
18749
- mt: "md",
18750
- children: [jsx(Button, {
18751
- size: "lg",
18752
- variant: "filled",
18753
- color: "blue",
18754
- loading: isRetrying,
18755
- onClick: handleManualRetry,
18756
- leftSection: !isRetrying && jsx(IconRefresh, {
18757
- size: 20
18758
- }),
18759
- style: {
18760
- minWidth: 220,
18761
- height: 50,
18762
- fontSize: '16px',
18763
- fontWeight: 600,
18764
- boxShadow: '0 4px 12px rgba(37, 99, 235, 0.2)',
18765
- transition: 'all 0.2s ease'
18766
- },
18767
- styles: {
18768
- root: {
18769
- '&:hover': {
18770
- transform: 'translateY(-2px)',
18771
- boxShadow: '0 6px 16px rgba(37, 99, 235, 0.3)'
18772
- },
18773
- '&:active': {
18774
- transform: 'translateY(0)'
18775
- }
18776
- }
18777
- },
18778
- children: isRetrying ? 'Riconnessione...' : 'Riprova connessione'
18779
- }), jsx(Text, {
18780
- size: "xs",
18781
- c: "dimmed",
18782
- ta: "center",
18783
- style: {
18784
- marginTop: 8
18785
- },
18786
- children: "Oppure ricarica la pagina (F5)"
18787
- })]
18788
- }) : jsxs(Group, {
18789
- gap: "sm",
18790
- mt: "md",
18791
- px: "md",
18792
- py: "xs",
18793
- style: {
18794
- backgroundColor: '#f8f9fa',
18795
- borderRadius: '6px',
18796
- border: '1px solid #e9ecef'
18797
- },
18798
- children: [jsx(Loader, {
18799
- size: "sm"
18800
- }), jsxs(Stack, {
18801
- gap: 2,
18802
- children: [jsx(Text, {
18803
- size: "sm",
18804
- c: "dark.6",
18805
- fw: 500,
18806
- children: "Riconnessione in corso..."
18807
- }), jsxs(Text, {
18808
- size: "xs",
18809
- c: "dimmed",
18810
- children: ["Tentativo ", reconnectAttempts, " di", ' ', FluxoClientSys.Instance.sessionHub.maxReconnectAttemptsLimit]
18811
- })]
18812
- })]
18813
- }), jsxs(Group, {
18814
- gap: 6,
18815
- mt: "lg",
18816
- children: [jsx(IconAlertTriangle, {
18817
- size: 16,
18818
- stroke: 1.5,
18819
- color: "#868e96"
18820
- }), jsx(Text, {
18821
- size: "xs",
18822
- c: "dimmed",
18823
- children: maxAttemptsReached ? 'I tuoi dati non salvati potrebbero andare persi' : 'Non chiudere questa pagina'
18824
- })]
18825
- })]
18826
- })
19999
+ }), showDisconnectionOverlay && jsx(DisconnectionOverlay, {
20000
+ maxAttemptsReached: maxAttemptsReached,
20001
+ reconnectAttempts: reconnectAttempts,
20002
+ isRetrying: isRetrying,
20003
+ onRetry: handleManualRetry
18827
20004
  })]
18828
20005
  })
18829
20006
  })
@@ -18836,7 +20013,7 @@ function AppLayout({
18836
20013
  frontends,
18837
20014
  brandElement
18838
20015
  }) {
18839
- var _a, _b;
20016
+ var _a, _b, _c;
18840
20017
  // Cattura l'URL iniziale PRIMA che i provider React possano modificarlo
18841
20018
  // Questo garantisce che quando passiamo da un frontend all'altro,
18842
20019
  // il nuovo provider riceva l'URL corretto e non venga reindirizzato a "/"
@@ -18852,7 +20029,7 @@ function AppLayout({
18852
20029
  const aiAsideOpened = useAppSelector(state => state.layout.aiAsideOpened);
18853
20030
  const currentFrontendId = useAppSelector(state => state.layout.currentFrontend);
18854
20031
  const currentFrontend = frontends.find(f => f.id === currentFrontendId);
18855
- const [currentShellUI, setCurrentShellUI] = useState(ui);
20032
+ const [currentShellUI, setCurrentShellUI] = useState(() => normalizeShellUI(ui));
18856
20033
  const isMobile = useMediaQuery('(max-width: 992px)');
18857
20034
  // Stato aside AI (da Redux)
18858
20035
  // Monitora lo stato della connessione WebSocket
@@ -18917,59 +20094,131 @@ function AppLayout({
18917
20094
  }
18918
20095
  }, []);
18919
20096
  useEffect(() => {
18920
- var _a, _b;
20097
+ var _a, _b, _c;
18921
20098
  if (currentFrontend) {
18922
20099
  // Merge frontend UI con UI di default per evitare proprietà undefined
18923
20100
  const frontendUI = (_a = currentFrontend.adminLayoutProps) === null || _a === void 0 ? void 0 : _a.ui;
18924
20101
  if (frontendUI) {
18925
- setCurrentShellUI(Object.assign(Object.assign(Object.assign({}, ui), frontendUI), {
20102
+ setCurrentShellUI(normalizeShellUI(Object.assign(Object.assign(Object.assign({}, ui), frontendUI), {
18926
20103
  // Assicuriamoci che le proprietà booleane non siano undefined
18927
- withMultipleSessions: (_b = frontendUI.withMultipleSessions) !== null && _b !== void 0 ? _b : ui.withMultipleSessions
18928
- }));
20104
+ withMultipleSessions: (_b = frontendUI.withMultipleSessions) !== null && _b !== void 0 ? _b : ui.withMultipleSessions,
20105
+ // Il layout può essere scelto per singolo frontend, con fallback su quello globale
20106
+ layout: (_c = frontendUI.layout) !== null && _c !== void 0 ? _c : ui.layout
20107
+ })));
18929
20108
  } else {
18930
- setCurrentShellUI(ui);
20109
+ setCurrentShellUI(normalizeShellUI(ui));
18931
20110
  }
18932
20111
  }
18933
20112
  }, [currentFrontend, ui]);
18934
20113
  useEffect(() => {
20114
+ var _a;
20115
+ const isModernLayout = ((_a = currentShellUI.layout) !== null && _a !== void 0 ? _a : ShellLayoutVariant.Classic) === ShellLayoutVariant.Modern;
20116
+ // Il layout "modern" non ha footer bar (le informazioni essenziali stanno in fondo
20117
+ // alla sidebar) e ha una chrome superiore più alta.
20118
+ FluxoStateDispatcher.dispatchSetFooterHeight(isModernLayout ? 0 : 40);
20119
+ FluxoStateDispatcher.dispatchSetAppBarHeight(isModernLayout ? MODERN_HEADER_HEIGHT : 48);
20120
+ FluxoStateDispatcher.dispatchSetLayoutVariant(isModernLayout ? 'modern' : 'classic');
18935
20121
  if (currentShellUI.withMultipleSessions) FluxoStateDispatcher.dispatchSetSessionMode('multi-session');else FluxoStateDispatcher.dispatchSetSessionMode('single-session');
18936
20122
  if (currentShellUI.navigation === ShellUINavigation.Sidebar) FluxoStateDispatcher.dispatchSetNavigationMode('sidebar');else if (currentShellUI.navigation === ShellUINavigation.SidebarMinimal) FluxoStateDispatcher.dispatchSetNavigationMode('sidebar-minimal');else if (currentShellUI.navigation === ShellUINavigation.Topbar) FluxoStateDispatcher.dispatchSetNavigationMode('topmenu');else {
18937
20123
  FluxoStateDispatcher.dispatchSetNavigationMode('none');
18938
20124
  FluxoStateDispatcher.dispatchCloseNavbar();
18939
20125
  }
18940
20126
  }, [currentShellUI]);
20127
+ // Il layout è scelto dal progetto consumer: se non specificato resta quello classico
20128
+ const layoutVariant = (_a = currentShellUI.layout) !== null && _a !== void 0 ? _a : ShellLayoutVariant.Classic;
20129
+ const shellLayoutProps = {
20130
+ appVersion,
20131
+ brandName,
20132
+ brandElement,
20133
+ currentShellUI,
20134
+ navbarOpened,
20135
+ isMobile,
20136
+ hasAdminAccess,
20137
+ fluxoClientConfig,
20138
+ showDisconnectionOverlay,
20139
+ maxAttemptsReached,
20140
+ reconnectAttempts,
20141
+ isRetrying,
20142
+ handleManualRetry,
20143
+ isAiEnabled: isAIEnabled !== null && isAIEnabled !== void 0 ? isAIEnabled : false,
20144
+ aiAsideOpened,
20145
+ onAiAsideToggle: () => FluxoStateDispatcher.dispatchToggleAiAside()
20146
+ };
18941
20147
  return jsx(ShellUIContext.Provider, {
18942
20148
  value: currentShellUI,
18943
20149
  children: jsx(ScreenSharingProvider, {
18944
20150
  sessionHub: FluxoClientSys.Instance.sessionHub,
18945
20151
  children: jsxs(WithShellSessionProvider, {
18946
- withMultipleSessions: (_a = currentShellUI.withMultipleSessions) !== null && _a !== void 0 ? _a : false,
20152
+ withMultipleSessions: (_b = currentShellUI.withMultipleSessions) !== null && _b !== void 0 ? _b : false,
18947
20153
  initialUrl: initialUrlRef.current,
18948
- children: [jsx(FocusAwareShellLayout, {
18949
- appVersion: appVersion,
18950
- brandName: brandName,
18951
- brandElement: brandElement,
18952
- currentShellUI: currentShellUI,
18953
- navbarOpened: navbarOpened,
18954
- isMobile: isMobile,
18955
- hasAdminAccess: hasAdminAccess,
18956
- fluxoClientConfig: fluxoClientConfig,
18957
- showDisconnectionOverlay: showDisconnectionOverlay,
18958
- maxAttemptsReached: maxAttemptsReached,
18959
- reconnectAttempts: reconnectAttempts,
18960
- isRetrying: isRetrying,
18961
- handleManualRetry: handleManualRetry,
18962
- isAiEnabled: isAIEnabled !== null && isAIEnabled !== void 0 ? isAIEnabled : false,
18963
- aiAsideOpened: aiAsideOpened,
18964
- onAiAsideToggle: () => FluxoStateDispatcher.dispatchToggleAiAside()
18965
- }), jsx(ShellSpotlight, {})]
18966
- }, `session-provider-${(_b = currentShellUI.withMultipleSessions) !== null && _b !== void 0 ? _b : false}`)
20154
+ children: [layoutVariant === ShellLayoutVariant.Modern ? jsx(ModernShellLayout, Object.assign({}, shellLayoutProps)) : jsx(FocusAwareShellLayout, Object.assign({}, shellLayoutProps)), jsx(ShellSpotlight, {})]
20155
+ }, `session-provider-${(_c = currentShellUI.withMultipleSessions) !== null && _c !== void 0 ? _c : false}`)
20156
+ })
20157
+ });
20158
+ }
20159
+
20160
+ /**
20161
+ * Cornice delle pagine di autenticazione nel layout "modern": card centrata su
20162
+ * sfondo scuro derivato dal brand.
20163
+ *
20164
+ * Il logo sta fuori dalla card di proposito: quello del brand è pensato per la
20165
+ * sidebar colorata (tipicamente chiaro) e su fondo bianco rischierebbe di sparire.
20166
+ */
20167
+ function ModernAuthShell({
20168
+ brandName,
20169
+ children
20170
+ }) {
20171
+ const brandSurface = useShellBrandSurface();
20172
+ const isMobile = useMediaQuery('(max-width: 992px)');
20173
+ return jsx(Box, {
20174
+ className: 'flxLogin',
20175
+ style: {
20176
+ minHeight: '100vh',
20177
+ width: '100%',
20178
+ display: 'flex',
20179
+ alignItems: 'center',
20180
+ justifyContent: 'center',
20181
+ padding: 24,
20182
+ /* Sfondo del brand (colore fisso o gradiente) con due aloni molto tenui:
20183
+ danno profondità senza dipendere da operazioni sul colore. */
20184
+ background: `radial-gradient(900px 620px at 12% 6%, rgba(255, 255, 255, 0.10), transparent 62%),
20185
+ radial-gradient(760px 520px at 88% 96%, rgba(255, 255, 255, 0.06), transparent 62%),
20186
+ ${brandSurface.background}`
20187
+ },
20188
+ children: jsxs(Stack, {
20189
+ align: 'center',
20190
+ gap: 24,
20191
+ w: '100%',
20192
+ maw: 460,
20193
+ children: [brandSurface.logo && jsx("img", {
20194
+ className: 'logoImg',
20195
+ src: brandSurface.logo,
20196
+ alt: brandName + ' logo',
20197
+ style: {
20198
+ maxHeight: brandSurface.logoHeight * 1.6,
20199
+ width: 'auto'
20200
+ }
20201
+ }), jsx(Paper, {
20202
+ w: '100%',
20203
+ radius: 12,
20204
+ p: isMobile ? 24 : 40,
20205
+ style: {
20206
+ background: '#fff',
20207
+ boxShadow: '0 24px 64px -24px rgba(8, 15, 30, 0.55)'
20208
+ },
20209
+ children: children
20210
+ }), jsxs(Text, {
20211
+ size: 'xs',
20212
+ c: 'rgba(255, 255, 255, 0.55)',
20213
+ ta: 'center',
20214
+ children: [brandName, " \u00A9", new Date().getFullYear()]
20215
+ })]
18967
20216
  })
18968
20217
  });
18969
20218
  }
18970
20219
 
18971
20220
  function LoginPage(props) {
18972
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
20221
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9;
18973
20222
  const {
18974
20223
  error
18975
20224
  } = useSelector(state => state.user);
@@ -18982,6 +20231,7 @@ function LoginPage(props) {
18982
20231
  const isMobile = useMediaQuery('(max-width: 992px)');
18983
20232
  const [is2FaRequired, set2FaRequired] = useState(false);
18984
20233
  const [userId, setUserId] = useState(null);
20234
+ const isModernLayout = props.layout === ShellLayoutVariant.Modern;
18985
20235
  useDocumentTitle('Login - ' + props.brandName);
18986
20236
  const form = useForm({
18987
20237
  initialValues: {
@@ -19033,6 +20283,88 @@ function LoginPage(props) {
19033
20283
  setUserId(null);
19034
20284
  form.reset();
19035
20285
  };
20286
+ if (isModernLayout) {
20287
+ return jsx(ModernAuthShell, {
20288
+ brandName: props.brandName,
20289
+ children: jsxs(Stack, {
20290
+ gap: 20,
20291
+ children: [jsx(Text, {
20292
+ ta: 'center',
20293
+ size: 'lg',
20294
+ fw: 600,
20295
+ children: !is2FaRequired ? (_c = (_b = (_a = props.loginConfig) === null || _a === void 0 ? void 0 : _a.labels) === null || _b === void 0 ? void 0 : _b.loginToYourAccountLabel) !== null && _c !== void 0 ? _c : 'Accedi al tuo account' : 'Verifica autenticazione a due fattori'
20296
+ }), error && jsx(Alert, {
20297
+ color: 'red',
20298
+ variant: 'light',
20299
+ p: 'xs',
20300
+ children: jsx(Text, {
20301
+ size: 'sm',
20302
+ children: "Errore durante il login. Username o password errati."
20303
+ })
20304
+ }), !is2FaRequired ? jsx("form", {
20305
+ onSubmit: form.onSubmit(values => loginHandler(values)),
20306
+ children: jsxs(Stack, {
20307
+ gap: 12,
20308
+ children: [jsx(TextInput, Object.assign({
20309
+ withAsterisk: true,
20310
+ size: 'md',
20311
+ placeholder: (_f = (_e = (_d = props.loginConfig) === null || _d === void 0 ? void 0 : _d.labels) === null || _e === void 0 ? void 0 : _e.loginUsernamePlaceholder) !== null && _f !== void 0 ? _f : 'Email / Nome utente'
20312
+ }, form.getInputProps('username'))), jsx(PasswordInput, Object.assign({
20313
+ withAsterisk: true,
20314
+ size: 'md',
20315
+ placeholder: (_j = (_h = (_g = props.loginConfig) === null || _g === void 0 ? void 0 : _g.labels) === null || _h === void 0 ? void 0 : _h.loginPasswordPlaceholder) !== null && _j !== void 0 ? _j : 'Password'
20316
+ }, form.getInputProps('password'))), ((_l = (_k = props.loginConfig) === null || _k === void 0 ? void 0 : _k.features) === null || _l === void 0 ? void 0 : _l.showForgotPassword) && jsx(Group, {
20317
+ justify: 'center',
20318
+ children: jsx(Anchor, {
20319
+ component: 'button',
20320
+ type: 'button',
20321
+ size: 'xs',
20322
+ onClick: () => navigateTo('/auth/forgot-password'),
20323
+ children: (_p = (_o = (_m = props.loginConfig) === null || _m === void 0 ? void 0 : _m.labels) === null || _o === void 0 ? void 0 : _o.forgotPasswordButton) !== null && _p !== void 0 ? _p : 'Password dimenticata?'
20324
+ })
20325
+ }), jsx(Button, {
20326
+ loading: onLogin,
20327
+ type: 'submit',
20328
+ size: 'md',
20329
+ fullWidth: true,
20330
+ mt: 4,
20331
+ children: (_s = (_r = (_q = props.loginConfig) === null || _q === void 0 ? void 0 : _q.labels) === null || _r === void 0 ? void 0 : _r.loginSubmitButton) !== null && _s !== void 0 ? _s : 'Accedi'
20332
+ })]
20333
+ })
20334
+ }) : jsx("form", {
20335
+ onSubmit: otpForm.onSubmit(values => verify2FAHandler(values)),
20336
+ children: jsxs(Stack, {
20337
+ gap: 12,
20338
+ children: [jsx(Text, {
20339
+ size: 'sm',
20340
+ c: 'dimmed',
20341
+ ta: 'center',
20342
+ children: "Inserisci il codice di verifica generato dalla tua app di autenticazione"
20343
+ }), jsx(TextInput, Object.assign({
20344
+ withAsterisk: true,
20345
+ size: 'md',
20346
+ placeholder: 'Codice OTP (es. 123456)',
20347
+ maxLength: 32
20348
+ }, otpForm.getInputProps('otp'))), jsx(Button, {
20349
+ loading: onLogin,
20350
+ type: 'submit',
20351
+ size: 'md',
20352
+ fullWidth: true,
20353
+ mt: 4,
20354
+ children: "Verifica OTP"
20355
+ }), jsx(Anchor, {
20356
+ component: 'button',
20357
+ type: 'button',
20358
+ size: 'xs',
20359
+ ta: 'center',
20360
+ onClick: backToLoginHandler,
20361
+ children: "\u2190 Torna al login"
20362
+ })]
20363
+ })
20364
+ })]
20365
+ })
20366
+ });
20367
+ }
19036
20368
  return jsxs(Grid, {
19037
20369
  className: 'flxLogin',
19038
20370
  h: '100vh',
@@ -19111,7 +20443,7 @@ function LoginPage(props) {
19111
20443
  },
19112
20444
  size: 'lg',
19113
20445
  mt: 0,
19114
- children: !is2FaRequired ? (_c = (_b = (_a = props.loginConfig) === null || _a === void 0 ? void 0 : _a.labels) === null || _b === void 0 ? void 0 : _b.loginToYourAccountLabel) !== null && _c !== void 0 ? _c : 'Accedi al tuo account' : 'Verifica autenticazione a due fattori'
20446
+ children: !is2FaRequired ? (_v = (_u = (_t = props.loginConfig) === null || _t === void 0 ? void 0 : _t.labels) === null || _u === void 0 ? void 0 : _u.loginToYourAccountLabel) !== null && _v !== void 0 ? _v : 'Accedi al tuo account' : 'Verifica autenticazione a due fattori'
19115
20447
  }), !is2FaRequired ? jsxs("form", {
19116
20448
  onSubmit: form.onSubmit(values => {
19117
20449
  loginHandler(values);
@@ -19120,16 +20452,16 @@ function LoginPage(props) {
19120
20452
  children: [jsx(TextInput, Object.assign({
19121
20453
  withAsterisk: true,
19122
20454
  size: "sm",
19123
- placeholder: (_f = (_e = (_d = props.loginConfig) === null || _d === void 0 ? void 0 : _d.labels) === null || _e === void 0 ? void 0 : _e.loginUsernamePlaceholder) !== null && _f !== void 0 ? _f : "Email / Nome utente"
20455
+ placeholder: (_y = (_x = (_w = props.loginConfig) === null || _w === void 0 ? void 0 : _w.labels) === null || _x === void 0 ? void 0 : _x.loginUsernamePlaceholder) !== null && _y !== void 0 ? _y : "Email / Nome utente"
19124
20456
  }, form.getInputProps('username'))), jsx(PasswordInput, Object.assign({
19125
20457
  size: 'sm',
19126
20458
  withAsterisk: true,
19127
- placeholder: (_j = (_h = (_g = props.loginConfig) === null || _g === void 0 ? void 0 : _g.labels) === null || _h === void 0 ? void 0 : _h.loginPasswordPlaceholder) !== null && _j !== void 0 ? _j : "Password"
20459
+ placeholder: (_1 = (_0 = (_z = props.loginConfig) === null || _z === void 0 ? void 0 : _z.labels) === null || _0 === void 0 ? void 0 : _0.loginPasswordPlaceholder) !== null && _1 !== void 0 ? _1 : "Password"
19128
20460
  }, form.getInputProps('password')))]
19129
20461
  }), jsxs(Stack, {
19130
20462
  gap: 5,
19131
20463
  mt: "md",
19132
- children: [((_l = (_k = props.loginConfig) === null || _k === void 0 ? void 0 : _k.features) === null || _l === void 0 ? void 0 : _l.showForgotPassword) && jsx(Stack, {
20464
+ children: [((_3 = (_2 = props.loginConfig) === null || _2 === void 0 ? void 0 : _2.features) === null || _3 === void 0 ? void 0 : _3.showForgotPassword) && jsx(Stack, {
19133
20465
  align: "center",
19134
20466
  children: jsx(Button, {
19135
20467
  style: {
@@ -19138,7 +20470,7 @@ function LoginPage(props) {
19138
20470
  size: "compact-XXX",
19139
20471
  variant: "transparent",
19140
20472
  onClick: () => navigateTo('/auth/forgot-password'),
19141
- children: (_p = (_o = (_m = props.loginConfig) === null || _m === void 0 ? void 0 : _m.labels) === null || _o === void 0 ? void 0 : _o.forgotPasswordButton) !== null && _p !== void 0 ? _p : 'Password dimenticata?'
20473
+ children: (_6 = (_5 = (_4 = props.loginConfig) === null || _4 === void 0 ? void 0 : _4.labels) === null || _5 === void 0 ? void 0 : _5.forgotPasswordButton) !== null && _6 !== void 0 ? _6 : 'Password dimenticata?'
19142
20474
  })
19143
20475
  }), jsx(Button, {
19144
20476
  loading: onLogin,
@@ -19146,7 +20478,7 @@ function LoginPage(props) {
19146
20478
  boxShadow: isMobile ? '4px 5px 1px -2px #000' : 'inherit'
19147
20479
  },
19148
20480
  type: "submit",
19149
- children: (_s = (_r = (_q = props.loginConfig) === null || _q === void 0 ? void 0 : _q.labels) === null || _r === void 0 ? void 0 : _r.loginSubmitButton) !== null && _s !== void 0 ? _s : 'Accedi'
20481
+ children: (_9 = (_8 = (_7 = props.loginConfig) === null || _7 === void 0 ? void 0 : _7.labels) === null || _8 === void 0 ? void 0 : _8.loginSubmitButton) !== null && _9 !== void 0 ? _9 : 'Accedi'
19150
20482
  }), jsxs(Text, {
19151
20483
  c: "dimmed",
19152
20484
  fz: "xs",
@@ -38438,241 +39770,223 @@ function MenuDesigner(props) {
38438
39770
  });
38439
39771
  return groups;
38440
39772
  };
38441
- return jsxs(Stack, {
38442
- children: [jsx(DataCard, {
38443
- title: 'Gestione Menu',
38444
- children: jsxs(Group, {
38445
- gap: 2,
38446
- align: 'center',
38447
- children: [jsx(Select, {
38448
- allowDeselect: false,
38449
- style: {
38450
- flex: 1
38451
- },
38452
- value: currentWebMenu === null || currentWebMenu === void 0 ? void 0 : currentWebMenu.id.toString(),
38453
- data: menuList,
38454
- onChange: v => {
38455
- const tmp = webMenu === null || webMenu === void 0 ? void 0 : webMenu.filter(a => a.id.toString() === v)[0];
38456
- setCurrentWebMenu(tmp);
38457
- }
38458
- }), jsxs(Menu, {
38459
- shadow: "md",
38460
- width: 200,
38461
- children: [jsx(Menu.Target, {
38462
- children: jsx(ActionIcon, {
38463
- variant: "subtle",
38464
- color: "gray",
38465
- size: "lg",
38466
- children: jsx(IconSettings, {
38467
- size: 20
38468
- })
38469
- })
38470
- }), jsxs(Menu.Dropdown, {
38471
- children: [jsx(Menu.Item, {
38472
- leftSection: jsx(IconPlus, {
38473
- size: 16
38474
- }),
38475
- onClick: () => setShowMenuCreateForm(true),
38476
- children: "Crea nuovo menu"
38477
- }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
38478
- leftSection: jsx(IconEdit, {
38479
- size: 16
38480
- }),
38481
- onClick: () => setShowMenuEditForm(true),
38482
- children: "Modifica menu"
38483
- }), jsx(Menu.Item, {
38484
- leftSection: jsx(IconDownload, {
38485
- size: 16
38486
- }),
38487
- onClick: exportMenuHandler,
38488
- children: "Esporta menu"
38489
- }), jsx(Menu.Item, {
38490
- leftSection: jsx(IconUpload, {
38491
- size: 16
38492
- }),
38493
- onClick: importMenuHandler,
38494
- children: "Importa menu"
38495
- }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
38496
- leftSection: jsx(IconTrash, {
38497
- size: 16
38498
- }),
38499
- color: "red",
38500
- onClick: () => setShowMenuDeleteConfirmation(true),
38501
- children: "Elimina menu"
38502
- })]
38503
- })]
38504
- })]
38505
- })
38506
- }), !currentWebMenuLoaded && jsx(Center, {
38507
- children: jsx(Loader, {
38508
- size: 32
38509
- })
38510
- }), currentWebMenu && currentWebMenuLoaded && jsxs(Fragment, {
38511
- children: [jsx(Center, {
38512
- children: jsx(IconArrowDown, {
38513
- size: 48,
38514
- color: 'gray'
39773
+ /** Selettore del menu, stato di salvataggio e azioni: vivono nell'header della card */
39774
+ const menuHeaderControls = jsxs(Group, {
39775
+ gap: 8,
39776
+ align: 'center',
39777
+ wrap: 'nowrap',
39778
+ children: [currentWebMenu && currentWebMenuLoaded && jsx(Badge, {
39779
+ size: 'sm',
39780
+ variant: 'light',
39781
+ color: currentAppMenuItemsAreChanged ? 'yellow' : 'green',
39782
+ leftSection: jsx(IconDeviceFloppy, {
39783
+ style: {
39784
+ width: rem(12),
39785
+ height: rem(12)
39786
+ }
39787
+ }),
39788
+ children: currentAppMenuItemsAreChanged ? 'Modifiche non salvate' : 'Salvato'
39789
+ }), jsx(Select, {
39790
+ allowDeselect: false,
39791
+ w: 240,
39792
+ value: currentWebMenu === null || currentWebMenu === void 0 ? void 0 : currentWebMenu.id.toString(),
39793
+ data: menuList,
39794
+ onChange: v => {
39795
+ const tmp = webMenu === null || webMenu === void 0 ? void 0 : webMenu.filter(a => a.id.toString() === v)[0];
39796
+ setCurrentWebMenu(tmp);
39797
+ }
39798
+ }), jsxs(Menu, {
39799
+ shadow: "md",
39800
+ width: 200,
39801
+ position: 'bottom-end',
39802
+ children: [jsx(Menu.Target, {
39803
+ children: jsx(ActionIcon, {
39804
+ variant: "subtle",
39805
+ color: "gray",
39806
+ size: "lg",
39807
+ "aria-label": 'Azioni sul menu',
39808
+ children: jsx(IconSettings, {
39809
+ size: 20
39810
+ })
38515
39811
  })
38516
- }), jsx(DataCard, {
38517
- title: `Menu designer - ${currentWebMenu.name}`,
38518
- elements: [jsx(Chip, {
38519
- icon: jsx(IconDeviceFloppy, {
38520
- style: {
38521
- width: rem(14),
38522
- height: rem(14)
38523
- }
39812
+ }), jsxs(Menu.Dropdown, {
39813
+ children: [jsx(Menu.Item, {
39814
+ leftSection: jsx(IconPlus, {
39815
+ size: 16
38524
39816
  }),
38525
- color: currentAppMenuItemsAreChanged ? 'yellow' : 'green',
38526
- variant: "filled",
38527
- size: 'xs',
38528
- checked: true,
38529
- children: currentAppMenuItemsAreChanged ? 'Modifiche non salvate' : 'Salvato'
38530
- })],
38531
- children: jsxs(Stack, {
38532
- children: [jsxs(Grid, {
38533
- gutter: 16,
38534
- align: 'flex-start',
38535
- children: [jsx(LoadingOverlay, {
38536
- visible: loadData
38537
- }), jsx(Grid.Col, {
38538
- span: {
38539
- lg: 3
39817
+ onClick: () => setShowMenuCreateForm(true),
39818
+ children: "Crea nuovo menu"
39819
+ }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
39820
+ leftSection: jsx(IconEdit, {
39821
+ size: 16
39822
+ }),
39823
+ onClick: () => setShowMenuEditForm(true),
39824
+ children: "Modifica menu"
39825
+ }), jsx(Menu.Item, {
39826
+ leftSection: jsx(IconDownload, {
39827
+ size: 16
39828
+ }),
39829
+ onClick: exportMenuHandler,
39830
+ children: "Esporta menu"
39831
+ }), jsx(Menu.Item, {
39832
+ leftSection: jsx(IconUpload, {
39833
+ size: 16
39834
+ }),
39835
+ onClick: importMenuHandler,
39836
+ children: "Importa menu"
39837
+ }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
39838
+ leftSection: jsx(IconTrash, {
39839
+ size: 16
39840
+ }),
39841
+ color: "red",
39842
+ onClick: () => setShowMenuDeleteConfirmation(true),
39843
+ children: "Elimina menu"
39844
+ })]
39845
+ })]
39846
+ })]
39847
+ });
39848
+ return jsxs(Stack, {
39849
+ children: [jsxs(DataCard, {
39850
+ title: 'Menu designer',
39851
+ elements: [menuHeaderControls],
39852
+ children: [!currentWebMenuLoaded && jsx(Center, {
39853
+ py: 32,
39854
+ children: jsx(Loader, {
39855
+ size: 32
39856
+ })
39857
+ }), currentWebMenu && currentWebMenuLoaded && jsxs(Stack, {
39858
+ children: [jsxs(Box, {
39859
+ pos: 'relative',
39860
+ children: [jsx(LoadingOverlay, {
39861
+ visible: loadData
39862
+ }), jsxs(Group, {
39863
+ align: 'end',
39864
+ gap: 12,
39865
+ wrap: 'wrap',
39866
+ children: [sysFeatures && jsx(Select, {
39867
+ placeholder: "Seleziona un modulo",
39868
+ style: {
39869
+ flex: '1 1 220px',
39870
+ minWidth: 200
38540
39871
  },
38541
- children: sysFeatures && jsx(Select, {
38542
- placeholder: "Seleziona un modulo",
38543
- onChange: module => {
38544
- setCurrentSelectedFeatures(sysFeatures === null || sysFeatures === void 0 ? void 0 : sysFeatures.features.filter(a => a.moduleKey === module));
38545
- setCurrentSelectedFeatureId(null);
38546
- setFeatureSearchValue(undefined);
38547
- },
38548
- leftSection: jsx(IconBoxModel, {}),
38549
- data: moduleToGroupedComboboxItems(sysFeatures === null || sysFeatures === void 0 ? void 0 : sysFeatures.modules)
38550
- })
38551
- }), jsx(Grid.Col, {
38552
- span: {
38553
- lg: 9
39872
+ onChange: module => {
39873
+ setCurrentSelectedFeatures(sysFeatures === null || sysFeatures === void 0 ? void 0 : sysFeatures.features.filter(a => a.moduleKey === module));
39874
+ setCurrentSelectedFeatureId(null);
39875
+ setFeatureSearchValue(undefined);
38554
39876
  },
38555
- children: jsxs(Group, {
38556
- align: 'end',
38557
- children: [jsx("div", {
38558
- style: {
38559
- width: 'calc(100% - 336px)'
38560
- },
38561
- children: jsx(Select, {
38562
- disabled: !currentSelectedFeatures,
38563
- placeholder: "Seleziona una feature",
38564
- searchable: true,
38565
- leftSection: jsx(IconApps, {}),
38566
- value: currentSelectedFeatureId,
38567
- onChange: v => {
38568
- setCurrentSelectedFeatureId(v);
38569
- },
38570
- onSearchChange: v => setFeatureSearchValue(v),
38571
- searchValue: featureSearchValue,
38572
- clearable: true,
38573
- data: featuresToGroupedComboboxItems(currentSelectedFeatures !== null && currentSelectedFeatures !== void 0 ? currentSelectedFeatures : [])
38574
- })
38575
- }), jsx("div", {
38576
- style: {
38577
- width: 150
38578
- },
38579
- children: jsx(Button, {
38580
- onClick: () => addFeatureToMenuHandler(),
38581
- disabled: !currentSelectedFeatureId,
38582
- fullWidth: true,
38583
- leftSection: jsx(IconPlus, {
38584
- size: 18
38585
- }),
38586
- children: "Voce"
38587
- })
38588
- }), jsx("div", {
38589
- style: {
38590
- width: 150
38591
- },
38592
- children: jsx(Button, {
38593
- onClick: () => addGroupToMenuHandler(),
38594
- fullWidth: true,
38595
- leftSection: jsx(IconFolderPlus, {
38596
- size: 18
38597
- }),
38598
- children: "Gruppo"
38599
- })
38600
- })]
38601
- })
38602
- })]
38603
- }), jsx(DndProvider, {
38604
- backend: MultiFactory,
38605
- options: getBackendOptions(),
38606
- children: jsx(Tree, {
38607
- listComponent: 'div',
38608
- listItemComponent: 'div',
38609
- placeholderComponent: 'div',
38610
- tree: treeData !== null && treeData !== void 0 ? treeData : [],
38611
- rootId: 'root',
38612
- sort: false,
38613
- onDrop: handleDrop,
38614
- dropTargetOffset: 10,
38615
- canDrop: (tree, {
38616
- dragSource,
38617
- dropTargetId,
38618
- dropTarget
38619
- }) => {
38620
- var _a;
38621
- return ((_a = dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.data) === null || _a === void 0 ? void 0 : _a.isGroup) || dropTarget === undefined;
39877
+ leftSection: jsx(IconBoxModel, {}),
39878
+ data: moduleToGroupedComboboxItems(sysFeatures === null || sysFeatures === void 0 ? void 0 : sysFeatures.modules)
39879
+ }), jsx(Select, {
39880
+ disabled: !currentSelectedFeatures,
39881
+ placeholder: "Seleziona una feature",
39882
+ style: {
39883
+ flex: '2 1 280px',
39884
+ minWidth: 220
38622
39885
  },
38623
- classes: {
38624
- root: styles["treeRoot"],
38625
- draggingSource: styles["draggingSource"],
38626
- placeholder: styles["placeholderContainer"]
39886
+ searchable: true,
39887
+ leftSection: jsx(IconApps, {}),
39888
+ value: currentSelectedFeatureId,
39889
+ onChange: v => {
39890
+ setCurrentSelectedFeatureId(v);
38627
39891
  },
38628
- placeholderRender: (node, {
38629
- depth
38630
- }) => jsx(Placeholder$2, {
38631
- node: node,
38632
- depth: depth
39892
+ onSearchChange: v => setFeatureSearchValue(v),
39893
+ searchValue: featureSearchValue,
39894
+ clearable: true,
39895
+ data: featuresToGroupedComboboxItems(currentSelectedFeatures !== null && currentSelectedFeatures !== void 0 ? currentSelectedFeatures : [])
39896
+ }), jsx(Button, {
39897
+ onClick: () => addFeatureToMenuHandler(),
39898
+ disabled: !currentSelectedFeatureId,
39899
+ w: 132,
39900
+ leftSection: jsx(IconPlus, {
39901
+ size: 18
38633
39902
  }),
38634
- render: (node, {
38635
- depth,
38636
- isOpen,
38637
- onToggle
38638
- }) => jsx(CustomNode, {
38639
- nodes: treeData !== null && treeData !== void 0 ? treeData : [],
38640
- node: node,
38641
- depth: depth,
38642
- isOpen: isOpen,
38643
- onToggle: onToggle,
38644
- onDeleteButtonClick: nodeId => deleteAppMenuItem(nodeId),
38645
- onEditButtonClick: i => {
38646
- setEditMenuItem(i);
38647
- setEditNodeId(node.id);
38648
- setEditMenuItemModalOpened(true);
38649
- }
38650
- })
38651
- })
38652
- }), editMenuItem && editNodeId && jsx(Modal, {
38653
- title: 'Modifica voce di menu',
38654
- closeOnEscape: false,
38655
- closeOnClickOutside: false,
38656
- centered: true,
38657
- opened: editMenuItemModalOpened,
38658
- onClose: () => setEditMenuItemModalOpened(false),
38659
- children: jsx(MenuItemEdit, {
38660
- nodeId: editNodeId,
38661
- menuItem: editMenuItem,
38662
- onCancelClick: () => {
38663
- setEditMenuItemModalOpened(false);
38664
- setEditMenuItem(undefined);
38665
- },
38666
- onSaveClick: (nodeId, i) => updateAppMenuItem(nodeId, i)
38667
- })
38668
- }), jsx(Divider, {}), jsx(Group, {
38669
- justify: 'end',
38670
- children: jsx(Button, {
38671
- onClick: () => saveButtonHandler(),
38672
- children: "Salva"
38673
- })
39903
+ children: "Voce"
39904
+ }), jsx(Button, {
39905
+ onClick: () => addGroupToMenuHandler(),
39906
+ variant: 'light',
39907
+ w: 132,
39908
+ leftSection: jsx(IconFolderPlus, {
39909
+ size: 18
39910
+ }),
39911
+ children: "Gruppo"
39912
+ })]
38674
39913
  })]
38675
- })
39914
+ }), jsx(DndProvider, {
39915
+ backend: MultiFactory,
39916
+ options: getBackendOptions(),
39917
+ children: jsx(Tree, {
39918
+ listComponent: 'div',
39919
+ listItemComponent: 'div',
39920
+ placeholderComponent: 'div',
39921
+ tree: treeData !== null && treeData !== void 0 ? treeData : [],
39922
+ rootId: 'root',
39923
+ sort: false,
39924
+ onDrop: handleDrop,
39925
+ dropTargetOffset: 10,
39926
+ canDrop: (tree, {
39927
+ dragSource,
39928
+ dropTargetId,
39929
+ dropTarget
39930
+ }) => {
39931
+ var _a;
39932
+ return ((_a = dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.data) === null || _a === void 0 ? void 0 : _a.isGroup) || dropTarget === undefined;
39933
+ },
39934
+ classes: {
39935
+ root: styles["treeRoot"],
39936
+ draggingSource: styles["draggingSource"],
39937
+ placeholder: styles["placeholderContainer"]
39938
+ },
39939
+ placeholderRender: (node, {
39940
+ depth
39941
+ }) => jsx(Placeholder$2, {
39942
+ node: node,
39943
+ depth: depth
39944
+ }),
39945
+ render: (node, {
39946
+ depth,
39947
+ isOpen,
39948
+ onToggle
39949
+ }) => jsx(CustomNode, {
39950
+ nodes: treeData !== null && treeData !== void 0 ? treeData : [],
39951
+ node: node,
39952
+ depth: depth,
39953
+ isOpen: isOpen,
39954
+ onToggle: onToggle,
39955
+ onDeleteButtonClick: nodeId => deleteAppMenuItem(nodeId),
39956
+ onEditButtonClick: i => {
39957
+ setEditMenuItem(i);
39958
+ setEditNodeId(node.id);
39959
+ setEditMenuItemModalOpened(true);
39960
+ }
39961
+ })
39962
+ })
39963
+ }), editMenuItem && editNodeId && jsx(Modal, {
39964
+ title: 'Modifica voce di menu',
39965
+ closeOnEscape: false,
39966
+ closeOnClickOutside: false,
39967
+ centered: true,
39968
+ opened: editMenuItemModalOpened,
39969
+ onClose: () => setEditMenuItemModalOpened(false),
39970
+ children: jsx(MenuItemEdit, {
39971
+ nodeId: editNodeId,
39972
+ menuItem: editMenuItem,
39973
+ onCancelClick: () => {
39974
+ setEditMenuItemModalOpened(false);
39975
+ setEditMenuItem(undefined);
39976
+ },
39977
+ onSaveClick: (nodeId, i) => updateAppMenuItem(nodeId, i)
39978
+ })
39979
+ }), jsx(Divider, {}), jsx(Group, {
39980
+ justify: 'end',
39981
+ children: jsx(Button, {
39982
+ onClick: () => saveButtonHandler(),
39983
+ disabled: !currentAppMenuItemsAreChanged,
39984
+ leftSection: jsx(IconDeviceFloppy, {
39985
+ size: 18
39986
+ }),
39987
+ children: "Salva"
39988
+ })
39989
+ })]
38676
39990
  })]
38677
39991
  }), currentWebMenu && jsx(ConfirmModal, {
38678
39992
  title: 'Eliminazione menu',
@@ -69119,7 +70433,14 @@ function ModuleVariablesGrid() {
69119
70433
  }
69120
70434
 
69121
70435
  function Settings(props) {
69122
- const [currentTab, setCurrentTab] = useState('ui');
70436
+ /**
70437
+ * Se il progetto consumer ha impostato un brand fisso (o ha esplicitamente disabilitato
70438
+ * la personalizzazione) la scheda "Brand" non è visibile né raggiungibile.
70439
+ */
70440
+ const {
70441
+ allowCustomization: allowBrandCustomization
70442
+ } = useShellBranding();
70443
+ const [currentTab, setCurrentTab] = useState(allowBrandCustomization ? 'ui' : 'menu');
69123
70444
  const [apiRestDoc, setApiRestDoc] = useState();
69124
70445
  useFlxNavigate();
69125
70446
  const {
@@ -69143,6 +70464,8 @@ function Settings(props) {
69143
70464
  useEffect(() => {
69144
70465
  const hash = window.location.hash.slice(1);
69145
70466
  if (hash) {
70467
+ // La scheda "Brand" non è raggiungibile nemmeno via hash quando il brand è fisso
70468
+ if (hash === 'ui' && !allowBrandCustomization) return;
69146
70469
  setCurrentTab(hash);
69147
70470
  }
69148
70471
  }, []);
@@ -69240,7 +70563,7 @@ function Settings(props) {
69240
70563
  name: 'Generali',
69241
70564
  hide: !hasAdminAccess,
69242
70565
  collapsible: false,
69243
- items: [{
70566
+ items: [...(allowBrandCustomization ? [{
69244
70567
  key: 'ui',
69245
70568
  title: jsx(Text, {
69246
70569
  children: "Brand"
@@ -69254,7 +70577,7 @@ function Settings(props) {
69254
70577
  size: 18
69255
70578
  }),
69256
70579
  description: 'Gestisci colori logo e altri impostazioni di interfaccia'
69257
- }, {
70580
+ }] : []), {
69258
70581
  key: 'menu',
69259
70582
  title: jsx(Text, {
69260
70583
  children: "Menu e ricerca"
@@ -69738,7 +71061,7 @@ function Settings(props) {
69738
71061
  const renderCurrentSection = tab => {
69739
71062
  switch (tab) {
69740
71063
  case 'ui':
69741
- return hasAdminAccess ? jsx(Box, {
71064
+ return hasAdminAccess && allowBrandCustomization ? jsx(Box, {
69742
71065
  maw: 1280,
69743
71066
  mx: 'auto',
69744
71067
  children: jsx(Ui, {})
@@ -70009,7 +71332,7 @@ function generateMainRoutes(props, hasAdminAccess, hasDeveloperAccess, hasDataAn
70009
71332
  }
70010
71333
 
70011
71334
  function ForgotPassword(props) {
70012
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
71335
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
70013
71336
  const [email, setEmail] = useState();
70014
71337
  const [errorMessage, setErrorMessage] = useState();
70015
71338
  const [successMessage, setSuccessMessage] = useState();
@@ -70025,6 +71348,63 @@ function ForgotPassword(props) {
70025
71348
  userService.forgotPassword(email).then(_res => setSuccessMessage('Richiesta inviata correttamente. Apri la tua casella e-mail.')).catch(_err => setErrorMessage('Errore durante il login'));
70026
71349
  }
70027
71350
  };
71351
+ const isModernLayout = props.layout === ShellLayoutVariant.Modern;
71352
+ if (isModernLayout) {
71353
+ return jsx(ModernAuthShell, {
71354
+ brandName: (_a = props.brandName) !== null && _a !== void 0 ? _a : 'Fluxo',
71355
+ children: !successMessage ? jsxs(Stack, {
71356
+ gap: 20,
71357
+ children: [jsx(Text, {
71358
+ ta: 'center',
71359
+ size: 'lg',
71360
+ fw: 600,
71361
+ children: (_d = (_c = (_b = props.loginConfig) === null || _b === void 0 ? void 0 : _b.labels) === null || _c === void 0 ? void 0 : _c.haveYouForgottenYourPasswordLabel) !== null && _d !== void 0 ? _d : 'Hai dimenticato la password?'
71362
+ }), errorMessage && jsx(Alert, {
71363
+ color: 'red',
71364
+ variant: 'light',
71365
+ p: 'xs',
71366
+ children: jsx(Text, {
71367
+ size: 'sm',
71368
+ children: errorMessage
71369
+ })
71370
+ }), jsxs(Stack, {
71371
+ gap: 12,
71372
+ children: [jsx(TextInput, {
71373
+ size: 'md',
71374
+ onChange: e => setEmail(e.target.value),
71375
+ placeholder: (_g = (_f = (_e = props.loginConfig) === null || _e === void 0 ? void 0 : _e.labels) === null || _f === void 0 ? void 0 : _f.forgotPasswordEmailPlaceholder) !== null && _g !== void 0 ? _g : 'Inserisci il tuo indirizzo e-mail'
71376
+ }), jsx(Button, {
71377
+ onClick: onFormSubmitClickHandler,
71378
+ disabled: !email,
71379
+ size: 'md',
71380
+ fullWidth: true,
71381
+ mt: 4,
71382
+ children: (_k = (_j = (_h = props.loginConfig) === null || _h === void 0 ? void 0 : _h.labels) === null || _j === void 0 ? void 0 : _j.forgotPasswordSubmitButton) !== null && _k !== void 0 ? _k : 'Recupera password'
71383
+ }), jsx(Anchor, {
71384
+ component: 'button',
71385
+ type: 'button',
71386
+ size: 'xs',
71387
+ ta: 'center',
71388
+ onClick: () => navigateTo('/auth/login'),
71389
+ children: "\u2190 Torna al login"
71390
+ })]
71391
+ })]
71392
+ }) : jsxs(Stack, {
71393
+ gap: 20,
71394
+ children: [jsx(Text, {
71395
+ ta: 'center',
71396
+ size: 'sm',
71397
+ children: successMessage
71398
+ }), jsx(Anchor, {
71399
+ component: Link,
71400
+ to: '/auth/login',
71401
+ size: 'sm',
71402
+ ta: 'center',
71403
+ children: "Effettua il login"
71404
+ })]
71405
+ })
71406
+ });
71407
+ }
70028
71408
  return jsxs(Grid, {
70029
71409
  className: 'flxLogin',
70030
71410
  h: '100vh',
@@ -70104,10 +71484,10 @@ function ForgotPassword(props) {
70104
71484
  size: 'lg',
70105
71485
  mt: 0,
70106
71486
  fw: 500,
70107
- children: (_c = (_b = (_a = props.loginConfig) === null || _a === void 0 ? void 0 : _a.labels) === null || _b === void 0 ? void 0 : _b.haveYouForgottenYourPasswordLabel) !== null && _c !== void 0 ? _c : 'Hai dimenticato la password?'
71487
+ children: (_o = (_m = (_l = props.loginConfig) === null || _l === void 0 ? void 0 : _l.labels) === null || _m === void 0 ? void 0 : _m.haveYouForgottenYourPasswordLabel) !== null && _o !== void 0 ? _o : 'Hai dimenticato la password?'
70108
71488
  }), jsx(TextInput, {
70109
71489
  onChange: e => setEmail(e.target.value),
70110
- placeholder: (_f = (_e = (_d = props.loginConfig) === null || _d === void 0 ? void 0 : _d.labels) === null || _e === void 0 ? void 0 : _e.forgotPasswordEmailPlaceholder) !== null && _f !== void 0 ? _f : 'Inserisci il tuo indirizzo e-mail'
71490
+ placeholder: (_r = (_q = (_p = props.loginConfig) === null || _p === void 0 ? void 0 : _p.labels) === null || _q === void 0 ? void 0 : _q.forgotPasswordEmailPlaceholder) !== null && _r !== void 0 ? _r : 'Inserisci il tuo indirizzo e-mail'
70111
71491
  }), jsx(Button, {
70112
71492
  onClick: onFormSubmitClickHandler,
70113
71493
  disabled: !email,
@@ -70117,7 +71497,7 @@ function ForgotPassword(props) {
70117
71497
  fontWeight: 600,
70118
71498
  border: 'none'
70119
71499
  } : undefined,
70120
- children: (_j = (_h = (_g = props.loginConfig) === null || _g === void 0 ? void 0 : _g.labels) === null || _h === void 0 ? void 0 : _h.forgotPasswordSubmitButton) !== null && _j !== void 0 ? _j : 'Recupera password'
71500
+ children: (_u = (_t = (_s = props.loginConfig) === null || _s === void 0 ? void 0 : _s.labels) === null || _t === void 0 ? void 0 : _t.forgotPasswordSubmitButton) !== null && _u !== void 0 ? _u : 'Recupera password'
70121
71501
  }), jsx(Button, {
70122
71502
  style: {
70123
71503
  color: isMobile ? '#fff' : 'inherit'
@@ -70177,7 +71557,8 @@ function ForgotPassword(props) {
70177
71557
  });
70178
71558
  }
70179
71559
 
70180
- function ResetPassword() {
71560
+ function ResetPassword(props = {}) {
71561
+ var _a;
70181
71562
  const [email, setEmail] = useState();
70182
71563
  const [token, setToken] = useState();
70183
71564
  const [linkIsValid, setLinkIsValid] = useState(true);
@@ -70217,6 +71598,98 @@ function ResetPassword() {
70217
71598
  }));
70218
71599
  }
70219
71600
  };
71601
+ const isModernLayout = props.layout === ShellLayoutVariant.Modern;
71602
+ if (isModernLayout) {
71603
+ return jsx(ModernAuthShell, {
71604
+ brandName: (_a = props.brandName) !== null && _a !== void 0 ? _a : 'Fluxo',
71605
+ children: !linkIsValid ? jsxs(Stack, {
71606
+ gap: 20,
71607
+ children: [jsx(Text, {
71608
+ ta: 'center',
71609
+ size: 'lg',
71610
+ fw: 600,
71611
+ children: "Link non valido"
71612
+ }), jsx(Text, {
71613
+ ta: 'center',
71614
+ size: 'sm',
71615
+ c: 'dimmed',
71616
+ children: "Il link di recupero password non \u00E8 pi\u00F9 valido. Richiedine uno nuovo."
71617
+ }), jsx(Anchor, {
71618
+ component: Link,
71619
+ to: '/auth/login',
71620
+ size: 'sm',
71621
+ ta: 'center',
71622
+ children: "Torna al login"
71623
+ })]
71624
+ }) : (recoveryResult === null || recoveryResult === void 0 ? void 0 : recoveryResult.success) ? jsxs(Stack, {
71625
+ gap: 20,
71626
+ children: [jsx(Text, {
71627
+ ta: 'center',
71628
+ size: 'lg',
71629
+ fw: 600,
71630
+ children: "Reset effettuato con successo"
71631
+ }), jsx(Anchor, {
71632
+ component: Link,
71633
+ to: '/auth/login',
71634
+ size: 'sm',
71635
+ ta: 'center',
71636
+ children: "Effettua il login"
71637
+ })]
71638
+ }) : jsxs(Stack, {
71639
+ gap: 20,
71640
+ children: [jsxs(Stack, {
71641
+ gap: 4,
71642
+ children: [jsx(Text, {
71643
+ ta: 'center',
71644
+ size: 'lg',
71645
+ fw: 600,
71646
+ children: "Reset password"
71647
+ }), email && jsx(Text, {
71648
+ ta: 'center',
71649
+ size: 'sm',
71650
+ c: 'dimmed',
71651
+ children: email
71652
+ })]
71653
+ }), recoveryResult && !recoveryResult.success && recoveryResult.errors.length > 0 && jsx(Alert, {
71654
+ color: 'red',
71655
+ variant: 'light',
71656
+ p: 'xs',
71657
+ children: jsx(Stack, {
71658
+ gap: 2,
71659
+ children: recoveryResult.errors.map((err, index) => jsx(Text, {
71660
+ size: 'sm',
71661
+ children: err.description
71662
+ }, index))
71663
+ })
71664
+ }), jsxs(Stack, {
71665
+ gap: 12,
71666
+ children: [jsx(PasswordInput, {
71667
+ size: 'md',
71668
+ label: 'Nuova password',
71669
+ onChange: e => setNewPassword(e.target.value)
71670
+ }), jsx(PasswordInput, {
71671
+ size: 'md',
71672
+ label: 'Conferma nuova password',
71673
+ error: confirmNewPassword && newPassword !== confirmNewPassword ? 'Le password non coincidono' : undefined,
71674
+ onChange: e => setConfirmNewPassword(e.target.value)
71675
+ }), jsx(Button, {
71676
+ onClick: onFormSubmitClickHandler,
71677
+ disabled: !(newPassword && newPassword === confirmNewPassword),
71678
+ size: 'md',
71679
+ fullWidth: true,
71680
+ mt: 4,
71681
+ children: "Effettua il reset"
71682
+ }), jsx(Anchor, {
71683
+ component: Link,
71684
+ to: '/auth/login',
71685
+ size: 'xs',
71686
+ ta: 'center',
71687
+ children: "Non vuoi effettuare il reset? Effettua il login"
71688
+ })]
71689
+ })]
71690
+ })
71691
+ });
71692
+ }
70220
71693
  return jsx(Grid, {
70221
71694
  justify: "center",
70222
71695
  children: jsxs(Grid.Col, {
@@ -82166,6 +83639,18 @@ const MessageReceiverModal = () => {
82166
83639
  });
82167
83640
  };
82168
83641
 
83642
+ /**
83643
+ * Layout disponibili per il frontend "admin".
83644
+ *
83645
+ * - `Classic`: layout storico (app bar colorata a tutta larghezza + sidebar chiara).
83646
+ * - `Modern`: sidebar laterale colorata a tutta altezza, striscia dello stesso colore
83647
+ * che prosegue in alto a tutta larghezza e contenuto arrotondato in alto a sinistra.
83648
+ */
83649
+ var ShellLayoutVariant;
83650
+ (function (ShellLayoutVariant) {
83651
+ ShellLayoutVariant["Classic"] = "classic";
83652
+ ShellLayoutVariant["Modern"] = "modern";
83653
+ })(ShellLayoutVariant || (ShellLayoutVariant = {}));
82169
83654
  var ShellUINavigation;
82170
83655
  (function (ShellUINavigation) {
82171
83656
  ShellUINavigation[ShellUINavigation["Sidebar"] = 1] = "Sidebar";
@@ -82189,11 +83674,21 @@ const culture = "it";
82189
83674
  ResourceManager.setLocalizationMessages(Object.assign(Object.assign(Object.assign({}, dxDashboardIt), dxReportingIt), dxAnalyticsCoreIt));
82190
83675
  locale(culture);
82191
83676
  function FluxoShell(props) {
82192
- var _a;
83677
+ var _a, _b, _c, _d;
82193
83678
  const [initialOperationsFinished, setInitialOperationsFinished] = useState(false);
82194
83679
  const [router, setRouter] = useState();
82195
- const [brandColors, setBrandColors] = useState(["#e9f4ff", "#c2d8ef", "#9bbae1", "#749ad6", "#4d7aca", "#355db2", "#29458a", "#1d2e63", "#101b3d", "#030a18"]);
83680
+ /**
83681
+ * Palette forzata dal brand fisso del progetto consumer (se presente):
83682
+ * in quel caso i colori restituiti dal backend vengono ignorati.
83683
+ */
83684
+ const fixedBrandColors = (_b = (_a = props.branding) === null || _a === void 0 ? void 0 : _a.fixed) === null || _b === void 0 ? void 0 : _b.colors;
83685
+ const [brandColors, setBrandColors] = useState(fixedBrandColors !== null && fixedBrandColors !== void 0 ? fixedBrandColors : ["#e9f4ff", "#c2d8ef", "#9bbae1", "#749ad6", "#4d7aca", "#355db2", "#29458a", "#1d2e63", "#101b3d", "#030a18"]);
82196
83686
  const [isFluxoClientReady, setIsFluxoClientReady] = useState(false);
83687
+ /**
83688
+ * Layout effettivo del frontend visualizzato: serve al tema Mantine, che vive
83689
+ * sopra al router. Il layout "modern" usa forme più morbide (raggi, ombre).
83690
+ */
83691
+ const [layoutVariant, setLayoutVariant] = useState((_c = props.ui.layout) !== null && _c !== void 0 ? _c : ShellLayoutVariant.Classic);
82197
83692
  const [initializationError, setInitializationError] = useState(null);
82198
83693
  const generateFluxoAppPrefix = useCallback$1(() => {
82199
83694
  var _a, _b;
@@ -82205,7 +83700,7 @@ function FluxoShell(props) {
82205
83700
  }
82206
83701
  if (window.location.pathname === '/' && prefix !== '/') window.location.replace(prefix);
82207
83702
  return prefix;
82208
- }, [(_a = props.routing) === null || _a === void 0 ? void 0 : _a.basename]);
83703
+ }, [(_d = props.routing) === null || _d === void 0 ? void 0 : _d.basename]);
82209
83704
  const generateRoutesFromEmbeddedModules = (frontend, routeType) => {
82210
83705
  const embeddedModules = [...frontend.modules, biModule];
82211
83706
  const rObjs = [];
@@ -82296,8 +83791,8 @@ function FluxoShell(props) {
82296
83791
  });
82297
83792
  return rObjs;
82298
83793
  };
82299
- const generateAuthRoutes = () => {
82300
- var _a;
83794
+ const generateAuthRoutes = layout => {
83795
+ var _a, _b, _c;
82301
83796
  return {
82302
83797
  path: "/auth",
82303
83798
  element: jsx(OnlyNotLoggedRoute, {
@@ -82308,16 +83803,22 @@ function FluxoShell(props) {
82308
83803
  path: "login",
82309
83804
  element: jsx(LoginPage, {
82310
83805
  loginConfig: props.loginConfig,
82311
- brandName: (_a = props.brandName) !== null && _a !== void 0 ? _a : 'Fluxo'
83806
+ brandName: (_a = props.brandName) !== null && _a !== void 0 ? _a : 'Fluxo',
83807
+ layout: layout
82312
83808
  })
82313
83809
  }, {
82314
83810
  path: "forgot-password",
82315
83811
  element: jsx(ForgotPassword, {
82316
- loginConfig: props.loginConfig
83812
+ loginConfig: props.loginConfig,
83813
+ brandName: (_b = props.brandName) !== null && _b !== void 0 ? _b : 'Fluxo',
83814
+ layout: layout
82317
83815
  })
82318
83816
  }, {
82319
83817
  path: "reset-password",
82320
- element: jsx(ResetPassword, {})
83818
+ element: jsx(ResetPassword, {
83819
+ brandName: (_c = props.brandName) !== null && _c !== void 0 ? _c : 'Fluxo',
83820
+ layout: layout
83821
+ })
82321
83822
  }, {
82322
83823
  path: "account-confirmation",
82323
83824
  element: jsx(AccountConfirmation, {})
@@ -82366,6 +83867,7 @@ function FluxoShell(props) {
82366
83867
  });
82367
83868
  FluxoClientSys.Instance.configuration.getInitialConfiguration().then(res => {
82368
83869
  // ...existing code...
83870
+ var _a, _b, _c, _d;
82369
83871
  //setIsUserLogged(res.isUserLogged);
82370
83872
  // If the user allowedFrontends is empty and user is logged, return a router with an error page (unauthorized)
82371
83873
  if (res.frontends.length === 0 && res.isUserLogged) {
@@ -82405,7 +83907,7 @@ function FluxoShell(props) {
82405
83907
  }], {
82406
83908
  basename: generateFluxoAppPrefix()
82407
83909
  }));
82408
- setBrandColors(res.ui.colors);
83910
+ setBrandColors(fixedBrandColors !== null && fixedBrandColors !== void 0 ? fixedBrandColors : res.ui.colors);
82409
83911
  return;
82410
83912
  }
82411
83913
  // Get the frontend to render
@@ -82428,6 +83930,11 @@ function FluxoShell(props) {
82428
83930
  };
82429
83931
  // Set the frontend to render
82430
83932
  const flxFrontend = frontendByRender;
83933
+ // Il layout può essere scelto per singolo frontend, con fallback su quello globale.
83934
+ // Serve come valore locale perché lo usano anche le route di autenticazione,
83935
+ // costruite in questa stessa closure (lo stato non è ancora aggiornato qui).
83936
+ const resolvedLayoutVariant = (_d = (_c = (_b = (_a = frontendByRender === null || frontendByRender === void 0 ? void 0 : frontendByRender.adminLayoutProps) === null || _a === void 0 ? void 0 : _a.ui) === null || _b === void 0 ? void 0 : _b.layout) !== null && _c !== void 0 ? _c : props.ui.layout) !== null && _d !== void 0 ? _d : ShellLayoutVariant.Classic;
83937
+ setLayoutVariant(resolvedLayoutVariant);
82431
83938
  // Write the initial configuration to the state
82432
83939
  FluxoStateDispatcher.dispatchSetConfiguration(res.ui);
82433
83940
  FluxoStateDispatcher.dispatchSetSystemSettings(res.systemSettings);
@@ -82444,7 +83951,7 @@ function FluxoShell(props) {
82444
83951
  FluxoStateDispatcher.dispatchSetCurrentFrontend(res.currentFrontend);
82445
83952
  FluxoStateDispatcher.dispatchAllowedFrontends(res.frontends);
82446
83953
  FluxoStateDispatcher.dispatchSysRoleAccess(res.hasAdminAccess, res.hasDeveloperAccess, res.hasDataAnalystAccess, res.userId);
82447
- const rObjs = [generateAuthRoutes(), {
83954
+ const rObjs = [generateAuthRoutes(resolvedLayoutVariant), {
82448
83955
  path: 'frontend-switcher',
82449
83956
  element: jsx(ProtectedRoute, {
82450
83957
  children: jsx(FrontendSwitcher, {
@@ -82485,7 +83992,7 @@ function FluxoShell(props) {
82485
83992
  basename: generateFluxoAppPrefix()
82486
83993
  });
82487
83994
  setRouter(router1);
82488
- setBrandColors(res.ui.colors);
83995
+ setBrandColors(fixedBrandColors !== null && fixedBrandColors !== void 0 ? fixedBrandColors : res.ui.colors);
82489
83996
  }).catch(error => {
82490
83997
  console.error('Failed to get initial configuration:', error);
82491
83998
  setInitializationError(error);
@@ -82498,9 +84005,11 @@ function FluxoShell(props) {
82498
84005
  setInitialOperationsFinished(true);
82499
84006
  });
82500
84007
  }, []);
84008
+ /** Nel layout "modern" i componenti hanno forme più morbide */
84009
+ const isModernLayout = layoutVariant === ShellLayoutVariant.Modern;
82501
84010
  return jsx(MantineProvider, {
82502
84011
  theme: {
82503
- defaultRadius: 0,
84012
+ defaultRadius: isModernLayout ? MODERN_RADIUS_CONTROL : 0,
82504
84013
  components: {
82505
84014
  ActionIcon: {
82506
84015
  defaultProps: {
@@ -82596,7 +84105,8 @@ function FluxoShell(props) {
82596
84105
  },
82597
84106
  Modal: {
82598
84107
  defaultProps: {
82599
- shadow: '0 0 200px rgba(16,16,16,.4)',
84108
+ shadow: isModernLayout ? '0 24px 48px -12px rgba(16,24,40,.18)' : '0 0 200px rgba(16,16,16,.4)',
84109
+ radius: isModernLayout ? MODERN_RADIUS_CONTROL : 0,
82600
84110
  styles: {
82601
84111
  close: {
82602
84112
  color: 'black'
@@ -82606,7 +84116,12 @@ function FluxoShell(props) {
82606
84116
  padding: 8,
82607
84117
  marginBottom: 16,
82608
84118
  color: 'black',
82609
- boxShadow: 'rgba(33, 33, 33, 0.1) 2px 1px 1px'
84119
+ boxShadow: isModernLayout ? 'none' : 'rgba(33, 33, 33, 0.1) 2px 1px 1px',
84120
+ borderBottom: isModernLayout ? '1px solid #eef0f4' : undefined,
84121
+ // Stesso motivo della DataCard: l'header ha sfondo pieno e senza
84122
+ // raggio coprirebbe gli angoli arrotondati della modale
84123
+ borderTopLeftRadius: isModernLayout ? MODERN_RADIUS_CONTROL : undefined,
84124
+ borderTopRightRadius: isModernLayout ? MODERN_RADIUS_CONTROL : undefined
82610
84125
  }
82611
84126
  },
82612
84127
  overlayProps: {
@@ -82619,7 +84134,7 @@ function FluxoShell(props) {
82619
84134
  Pagination: {
82620
84135
  styles: {
82621
84136
  root: {
82622
- borderRadius: 0
84137
+ borderRadius: isModernLayout ? MODERN_RADIUS_CONTROL : 0
82623
84138
  }
82624
84139
  }
82625
84140
  },
@@ -82639,7 +84154,8 @@ function FluxoShell(props) {
82639
84154
  fontFamily: 'Roboto',
82640
84155
  primaryColor: 'brand'
82641
84156
  },
82642
- children: jsx(React__default.Fragment, {
84157
+ children: jsx(ShellBrandingProvider, {
84158
+ branding: props.branding,
82643
84159
  children: initializationError ? jsx(Center, {
82644
84160
  w: '100%',
82645
84161
  h: '100vh',
@@ -83035,4 +84551,4 @@ function LockedResource({
83035
84551
  });
83036
84552
  }
83037
84553
 
83038
- export { FluxoShell, FrontendSwitch, LockedResource, MessageReceiverModal, ScreenSharingProvider, ScreenSharingWidget, ShellUINavigation, ShellUISearchPosition, ShellUISearchType, useScreenSharingContext, useSessionHub };
84554
+ export { FluxoShell, FrontendSwitch, LockedResource, MessageReceiverModal, ScreenSharingProvider, ScreenSharingWidget, ShellBrandingProvider, ShellLayoutVariant, ShellUINavigation, ShellUISearchPosition, ShellUISearchType, isBrandCustomizationAllowed, resolveShellBackground, resolveShellBackgroundTopColor, useScreenSharingContext, useSessionHub, useShellBrandSurface, useShellBranding };