@fluxo-dev/shell 0.0.24 → 0.0.26

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
@@ -2,13 +2,13 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { useState, Suspense, forwardRef, createElement as createElement$2, useEffect, createContext, useContext, useLayoutEffect, useRef, useCallback, useMemo, memo, isValidElement, cloneElement, useImperativeHandle, lazy } from 'react';
4
4
  import { useSelector, Provider } from 'react-redux';
5
- import { useLocation, Navigate, matchPath, Outlet, useNavigate, Link, Route, useSearchParams, createBrowserRouter, RouterProvider } from 'react-router-dom';
6
- import { FluxoClientSys, AppType, AppState, FluxoStateDispatcher, UserService, AppMenuContextType, ApiKeyService, DomainRoleService } from '@fluxo-dev/api-client-base';
7
- import { AccessDenied, DataCard, NoData, ConfirmModal, ShellPage, ErrorPage as ErrorPage$1, WaitData, FlxRoutes } from '@fluxo-dev/ui-components';
5
+ import { useLocation, Navigate, Outlet, useNavigate, Link, Route, useSearchParams, createBrowserRouter, RouterProvider } from 'react-router-dom';
6
+ import { DataCard, NoData, ConfirmModal, ShellPage, ErrorPage as ErrorPage$1, WaitData, FlxRoutes } from '@fluxo-dev/ui-components';
8
7
  import { ModuleLoader } from '@fluxo-dev/shell-mfe';
9
- import { Text, TextInput, ActionIcon, useMantineTheme, AppShell, Stack, Group, Burger, Badge, Drawer, NavLink, Avatar, Anchor, Tooltip, Divider, Space, useMantineColorScheme, UnstyledButton, Box, ThemeIcon, Collapse, ScrollArea, rem, Loader, Grid, Center, PasswordInput, Button, ColorSwatch, FileButton, NumberInput, Alert, ColorInput, Checkbox, Modal, Switch, Select, Chip, LoadingOverlay, Image as Image$1, Menu, Textarea, Table, MultiSelect, MantineProvider } from '@mantine/core';
8
+ import { Text, TextInput, ActionIcon, useMantineTheme, AppShell, Stack, Group, Burger, Badge, Drawer, NavLink, Popover, Avatar, Center, Divider, Button, Anchor, Tooltip, Space, useMantineColorScheme, UnstyledButton, Box, ThemeIcon, Collapse, ScrollArea, rem, Loader, Grid, PasswordInput, ColorSwatch, FileButton, NumberInput, Alert, ColorInput, Checkbox, Modal, Switch, Select, Chip, LoadingOverlay, Image as Image$1, Menu, Textarea, Table, MultiSelect, Card, MantineProvider } from '@mantine/core';
10
9
  import { openSpotlight, Spotlight } from '@mantine/spotlight';
11
10
  import { useOs, useHotkeys, useIdle } from '@mantine/hooks';
11
+ import { AppType, AppState, FluxoStateDispatcher, FluxoClientSys, UserService, AppMenuContextType, ApiKeyService, DomainRoleService, EmailServerProviderType } from '@fluxo-dev/api-client-base';
12
12
  import { showNotification, Notifications } from '@mantine/notifications';
13
13
  import { useAppSelector, store as store$4 } from '@fluxo-dev/state';
14
14
  import { useForm } from '@mantine/form';
@@ -2214,36 +2214,13 @@ function ProtectedRoute(_a) {
2214
2214
  const {
2215
2215
  loggedIn
2216
2216
  } = useSelector(state => state.user);
2217
- const {
2218
- routeRules
2219
- } = useSelector(state => state.routeRules);
2220
- const navigation = useLocation();
2217
+ useLocation();
2221
2218
  if (!loggedIn) {
2222
2219
  return jsx(Navigate, {
2223
2220
  to: "/auth/login",
2224
2221
  replace: true
2225
2222
  });
2226
2223
  }
2227
- let accessDenied = false;
2228
- let requiredPermissions = [];
2229
- routeRules.forEach(routeRule => {
2230
- const match = matchPath(`${routeRule.route}`, navigation.pathname);
2231
- if (match) {
2232
- if (routeRule.permissions.length === 0) {
2233
- return;
2234
- } else {
2235
- const res = FluxoClientSys.Instance.security.currentUser.hasPermissions(routeRule.permissions);
2236
- if (!res) {
2237
- accessDenied = true;
2238
- requiredPermissions = routeRule.permissions;
2239
- return;
2240
- }
2241
- }
2242
- }
2243
- });
2244
- if (accessDenied) return jsx(AccessDenied, {
2245
- requiredPermissions: requiredPermissions
2246
- });
2247
2224
  return children;
2248
2225
  }
2249
2226
 
@@ -3985,6 +3962,21 @@ var IconLock = createReactComponent("lock", "IconLock", [
3985
3962
  ["path", { d: "M8 11v-4a4 4 0 1 1 8 0v4", key: "svg-2" }]
3986
3963
  ]);
3987
3964
 
3965
+ /**
3966
+ * @tabler/icons-react v2.42.0 - MIT
3967
+ */
3968
+
3969
+ var IconMail = createReactComponent("mail", "IconMail", [
3970
+ [
3971
+ "path",
3972
+ {
3973
+ d: "M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z",
3974
+ key: "svg-0"
3975
+ }
3976
+ ],
3977
+ ["path", { d: "M3 7l9 6l9 -6", key: "svg-1" }]
3978
+ ]);
3979
+
3988
3980
  /**
3989
3981
  * @tabler/icons-react v2.42.0 - MIT
3990
3982
  */
@@ -4063,22 +4055,6 @@ var IconReportSearch = createReactComponent("report-search", "IconReportSearch",
4063
4055
  ["path", { d: "M18.5 19.5l2.5 2.5", key: "svg-6" }]
4064
4056
  ]);
4065
4057
 
4066
- /**
4067
- * @tabler/icons-react v2.42.0 - MIT
4068
- */
4069
-
4070
- var IconRoute = createReactComponent("route", "IconRoute", [
4071
- ["path", { d: "M3 19a2 2 0 1 0 4 0a2 2 0 0 0 -4 0", key: "svg-0" }],
4072
- ["path", { d: "M19 7a2 2 0 1 0 0 -4a2 2 0 0 0 0 4z", key: "svg-1" }],
4073
- [
4074
- "path",
4075
- {
4076
- d: "M11 19h5.5a3.5 3.5 0 0 0 0 -7h-8a3.5 3.5 0 0 1 0 -7h4.5",
4077
- key: "svg-2"
4078
- }
4079
- ]
4080
- ]);
4081
-
4082
4058
  /**
4083
4059
  * @tabler/icons-react v2.42.0 - MIT
4084
4060
  */
@@ -4412,6 +4388,7 @@ function AppBar(props) {
4412
4388
  },
4413
4389
  children: [jsxs(Group, {
4414
4390
  children: [jsx(Burger, {
4391
+ tabIndex: -1,
4415
4392
  disabled: props.previewMode !== undefined,
4416
4393
  color: '#fff',
4417
4394
  opened: navbarOpened,
@@ -4420,6 +4397,7 @@ function AppBar(props) {
4420
4397
  if (navbarOpened) FluxoStateDispatcher.dispatchCloseNavbar();else FluxoStateDispatcher.dispatchOpenNavbar();
4421
4398
  }
4422
4399
  }), jsx(Link, {
4400
+ tabIndex: -1,
4423
4401
  to: props.previewMode ? '' : '/',
4424
4402
  style: {
4425
4403
  maxHeight: (_d = (_c = props.previewMode) === null || _c === void 0 ? void 0 : _c.logoHeight) !== null && _d !== void 0 ? _d : configuration.logoHeight
@@ -4434,10 +4412,12 @@ function AppBar(props) {
4434
4412
  }), jsxs(Group, {
4435
4413
  wrap: "nowrap",
4436
4414
  children: [developmentMode && jsx(Badge, {
4415
+ tabIndex: -1,
4437
4416
  color: 'red',
4438
4417
  children: "Development mode"
4439
4418
  }), jsx(FrontendSwitch, {}), jitApps && jitApps.length > 0 && jsxs(Fragment, {
4440
4419
  children: [jsx(ActionIcon, {
4420
+ tabIndex: -1,
4441
4421
  variant: 'transparent',
4442
4422
  onClick: () => setJitAppsDrawerOpened(true),
4443
4423
  children: jsx(IconApps, {
@@ -4495,12 +4475,49 @@ function AppBar(props) {
4495
4475
  })]
4496
4476
  }), jsx(SearchBar, {
4497
4477
  disabled: props.previewMode !== undefined
4498
- }), jsxs(Avatar, {
4499
- onClick: () => props.previewMode ? undefined : logout(),
4500
- color: "cyan",
4501
- radius: "xl",
4502
- size: 32,
4503
- children: [userInfo.FirstName.substr(0, 1), userInfo.LastName.substr(0, 1)]
4478
+ }), jsxs(Popover, {
4479
+ disabled: props.previewMode !== undefined,
4480
+ children: [jsx(Popover.Target, {
4481
+ children: jsxs(Avatar, {
4482
+ tabIndex: -1,
4483
+ style: {
4484
+ cursor: 'pointer'
4485
+ },
4486
+ color: "cyan",
4487
+ radius: "xl",
4488
+ size: 32,
4489
+ children: [userInfo.FirstName.substr(0, 1), userInfo.LastName.substr(0, 1)]
4490
+ })
4491
+ }), jsx(Popover.Dropdown, {
4492
+ w: 300,
4493
+ children: jsxs(Stack, {
4494
+ gap: 12,
4495
+ children: [jsx(Center, {
4496
+ children: jsxs(Stack, {
4497
+ justify: 'center',
4498
+ align: 'center',
4499
+ children: [jsxs(Avatar, {
4500
+ color: "cyan",
4501
+ radius: "xl",
4502
+ size: 64,
4503
+ children: [userInfo.FirstName.substr(0, 1), userInfo.LastName.substr(0, 1)]
4504
+ }), jsxs(Text, {
4505
+ children: [userInfo.FirstName, " ", userInfo.LastName]
4506
+ })]
4507
+ })
4508
+ }), jsx(Divider, {}), jsx(Button, {
4509
+ variant: 'subtle',
4510
+ onClick: () => logout(),
4511
+ children: "Esci"
4512
+ }), jsx(Divider, {}), jsx(Center, {
4513
+ children: jsxs(Text, {
4514
+ c: "dimmed",
4515
+ fz: "xs",
4516
+ children: [props.brandName, " \u00A9", new Date().getFullYear()]
4517
+ })
4518
+ })]
4519
+ })
4520
+ })]
4504
4521
  })]
4505
4522
  })]
4506
4523
  })
@@ -4519,6 +4536,9 @@ function FooterBar(props) {
4519
4536
  const {
4520
4537
  userIdle
4521
4538
  } = useAppSelector(state => state.layout);
4539
+ const {
4540
+ hasAdminAccess
4541
+ } = useAppSelector(state => state.layout);
4522
4542
  const idle = useIdle(5000);
4523
4543
  useEffect(() => {
4524
4544
  if (idle) FluxoStateDispatcher.dispatchSetUserIdle();else FluxoStateDispatcher.dispatchUnsetUserIdle();
@@ -4584,18 +4604,20 @@ function FooterBar(props) {
4584
4604
  }), jsx(Space, {
4585
4605
  h: 'md'
4586
4606
  }), jsxs(Group, {
4587
- children: [jsx(Link, {
4588
- to: '/settings',
4589
- style: {
4590
- textDecoration: 'none'
4591
- },
4592
- children: jsx(Text, {
4593
- c: "dimmed",
4594
- fz: "xs",
4595
- children: "Amministrazione"
4596
- })
4597
- }), jsx(Divider, {
4598
- orientation: 'vertical'
4607
+ children: [hasAdminAccess && jsxs(Fragment, {
4608
+ children: [jsx(Link, {
4609
+ to: '/settings',
4610
+ style: {
4611
+ textDecoration: 'none'
4612
+ },
4613
+ children: jsx(Text, {
4614
+ c: "dimmed",
4615
+ fz: "xs",
4616
+ children: "Amministrazione"
4617
+ })
4618
+ }), jsx(Divider, {
4619
+ orientation: 'vertical'
4620
+ })]
4599
4621
  }), jsxs(Text, {
4600
4622
  c: "dimmed",
4601
4623
  fz: "xs",
@@ -4974,7 +4996,9 @@ function AppLayout(props) {
4974
4996
  },
4975
4997
  transitionDuration: 0,
4976
4998
  layout: 'default',
4977
- children: [jsx(AppBar, {}), jsx(Navbar, {}), jsx(AppShell.Main, {
4999
+ children: [jsx(AppBar, {
5000
+ brandName: props.brandName
5001
+ }), jsx(Navbar, {}), jsx(AppShell.Main, {
4978
5002
  children: jsx(Suspense, {
4979
5003
  fallback: jsx(Loader, {}),
4980
5004
  children: jsx(AppContent, {})
@@ -5085,6 +5109,7 @@ function LoginPage(props) {
5085
5109
  size: "sm",
5086
5110
  placeholder: "Email / Nome utente"
5087
5111
  }, form.getInputProps('username'))), jsx(PasswordInput, Object.assign({
5112
+ size: 'sm',
5088
5113
  withAsterisk: true,
5089
5114
  placeholder: "Password"
5090
5115
  }, form.getInputProps('password')))]
@@ -5398,7 +5423,8 @@ function Ui() {
5398
5423
  logo: newLogoBase64,
5399
5424
  logoHeight: newLogoHeight,
5400
5425
  headerColor: newBrandColors[6]
5401
- }
5426
+ },
5427
+ brandName: ''
5402
5428
  })
5403
5429
  })
5404
5430
  })
@@ -20209,11 +20235,6 @@ function PermissionNavigator(props) {
20209
20235
  setDomainRolePermissions(res);
20210
20236
  setDomainRolePermissionLoaded(true);
20211
20237
  });
20212
- } else {
20213
- FluxoClientSys.Instance.security.routeRule.getPermissions(props.context.id).then(res => {
20214
- setDomainRolePermissions(res);
20215
- setDomainRolePermissionLoaded(true);
20216
- });
20217
20238
  }
20218
20239
  }, []);
20219
20240
  useEffect(() => {
@@ -20227,41 +20248,6 @@ function PermissionNavigator(props) {
20227
20248
  addOrRemovePermissionForDomainRole(permissionId);
20228
20249
  } else if (props.context.type === 'menu') {
20229
20250
  addOrRemovePermissionForMenu(permissionId);
20230
- } else if (props.context.type === 'route-rule') {
20231
- addOrRemovePermissionForRouteRule(permissionId);
20232
- }
20233
- };
20234
- const addOrRemovePermissionForRouteRule = menuItemId => {
20235
- if (selectedPermissionsIds.includes(menuItemId)) {
20236
- FluxoClientSys.Instance.security.routeRule.removePermission(+props.context.id, menuItemId).then(res => {
20237
- setSelectedPermissionsIds(selectedPermissionsIds.filter(p => p !== menuItemId));
20238
- showNotification({
20239
- title: "Permesso rimosso",
20240
- message: "Il permesso è stato rimosso correttamente",
20241
- color: "green"
20242
- });
20243
- }).catch(err => {
20244
- showNotification({
20245
- title: "Errore",
20246
- message: "Si è verificato un errore durante la rimozione del permesso",
20247
- color: "red"
20248
- });
20249
- });
20250
- } else {
20251
- FluxoClientSys.Instance.security.routeRule.addPermission(+props.context.id, menuItemId).then(res => {
20252
- setSelectedPermissionsIds([...selectedPermissionsIds, menuItemId]);
20253
- showNotification({
20254
- title: "Permesso aggiunto",
20255
- message: "Il permesso è stato aggiunto correttamente",
20256
- color: "green"
20257
- });
20258
- }).catch(err => {
20259
- showNotification({
20260
- title: "Errore",
20261
- message: "Si è verificato un errore durante l'aggiunta del permesso",
20262
- color: "red"
20263
- });
20264
- });
20265
20251
  }
20266
20252
  };
20267
20253
  const addOrRemovePermissionForMenu = menuItemId => {
@@ -28557,14 +28543,123 @@ function DomainRoleForm(props) {
28557
28543
  });
28558
28544
  }
28559
28545
 
28546
+ function FrontendDomainRole(props) {
28547
+ const {
28548
+ frontends
28549
+ } = useAppSelector(state => state.layout);
28550
+ const [frontendDomainRole, setFrontendDomainRole] = useState();
28551
+ useEffect(() => {
28552
+ if (!frontends) return;
28553
+ FluxoClientSys.Instance.configuration.getFrontendByDomainRole(props.domainRoleId).then(a => {
28554
+ setFrontendDomainRole(frontends.map(b => {
28555
+ return {
28556
+ id: b.id,
28557
+ name: b.name,
28558
+ active: a.includes(b.id)
28559
+ };
28560
+ }));
28561
+ }).catch(e => {
28562
+ showNotification({
28563
+ title: 'Errore',
28564
+ message: e.message,
28565
+ color: 'red'
28566
+ });
28567
+ });
28568
+ }, [props.domainRoleId, frontends]);
28569
+ const updateFrontendDomainRole = () => {
28570
+ if (!frontendDomainRole) return;
28571
+ FluxoClientSys.Instance.configuration.updateFrontendDomainRole(props.domainRoleId, frontendDomainRole.filter(a => a.active).map(a => a.id)).then(() => {
28572
+ showNotification({
28573
+ title: 'Salvato',
28574
+ message: 'Ruoli frontend aggiornati',
28575
+ color: 'green'
28576
+ });
28577
+ props.onClosed();
28578
+ }).catch(e => {
28579
+ showNotification({
28580
+ title: 'Errore',
28581
+ message: e.message,
28582
+ color: 'red'
28583
+ });
28584
+ });
28585
+ };
28586
+ const isAllInactive = frontendDomainRole === null || frontendDomainRole === void 0 ? void 0 : frontendDomainRole.every(a => !a.active);
28587
+ return jsxs(Stack, {
28588
+ children: [isAllInactive && jsx(Alert, {
28589
+ color: 'yellow',
28590
+ title: 'Attenzione',
28591
+ children: "Se non selezioni alcuna area, gli utenti legati a questo ruolo non potranno accedere a nessuna area funzionale."
28592
+ }), jsxs(Table, {
28593
+ children: [jsx(Table.Thead, {
28594
+ children: jsxs(Table.Tr, {
28595
+ children: [jsx(Table.Th, {
28596
+ children: "Area"
28597
+ }), jsx(Table.Th, {
28598
+ w: 50,
28599
+ children: "Attivo"
28600
+ })]
28601
+ })
28602
+ }), jsx(Table.Tbody, {
28603
+ children: frontendDomainRole === null || frontendDomainRole === void 0 ? void 0 : frontendDomainRole.map(a => {
28604
+ return jsxs(Table.Tr, {
28605
+ children: [jsx(Table.Td, {
28606
+ children: a.name
28607
+ }), jsx(Table.Td, {
28608
+ w: 50,
28609
+ children: jsx(Switch, {
28610
+ checked: a.active,
28611
+ onChange: e => {
28612
+ setFrontendDomainRole(frontendDomainRole === null || frontendDomainRole === void 0 ? void 0 : frontendDomainRole.map(b => {
28613
+ if (b.id === a.id) b.active = e.target.checked;
28614
+ return b;
28615
+ }));
28616
+ }
28617
+ })
28618
+ })]
28619
+ });
28620
+ })
28621
+ })]
28622
+ }), jsx(Divider, {}), jsx(Group, {
28623
+ justify: 'right',
28624
+ children: jsx(Button, {
28625
+ onClick: updateFrontendDomainRole,
28626
+ children: "Salva"
28627
+ })
28628
+ })]
28629
+ });
28630
+ }
28631
+
28560
28632
  function DomainRoleGrid() {
28561
28633
  const [domainRoles, setDomainRoles] = useState([]);
28562
28634
  const [currentDomainRole, setCurrentDomainRole] = useState();
28563
28635
  const [domainRoleModalOpen, setDomainRoleModalOpen] = useState(false);
28636
+ const [updateDomainFrontendsModal, setUpdateDomainFrontendsModal] = useState(false);
28564
28637
  const [updateDomainRolePermissionsModal, setUpdateDomainRolePermissionsModal] = useState(false);
28638
+ const [allDomainRolesFrontends, setAllDomainRolesFrontends] = useState();
28639
+ const [loading, setLoading] = useState(true);
28565
28640
  useEffect(() => {
28566
- getAllDomainRoles();
28641
+ refreshDomainRoles();
28567
28642
  }, []);
28643
+ const refreshDomainRoles = () => {
28644
+ setLoading(true);
28645
+ Promise.all([getAllDomainRoles(), getAllDomainRoleFrontends()]).finally(() => setLoading(false));
28646
+ };
28647
+ const getAllDomainRoleFrontends = () => {
28648
+ FluxoClientSys.Instance.configuration.getAllDomainRoleFrontends().then(a => {
28649
+ setAllDomainRolesFrontends(a.map(b => {
28650
+ return {
28651
+ domainRoleId: b.domainRoleId,
28652
+ frontends: b.frontends
28653
+ };
28654
+ }));
28655
+ }).catch(e => {
28656
+ showNotification({
28657
+ title: 'Errore',
28658
+ message: e.message,
28659
+ color: 'red'
28660
+ });
28661
+ });
28662
+ };
28568
28663
  const getAllDomainRoles = () => {
28569
28664
  FluxoClientSys.Instance.security.domainRole.find(9999, 0, undefined, "DomainRolePermissions,DomainRolePermissions.Permission").then(res => {
28570
28665
  setDomainRoles(res.results);
@@ -28587,6 +28682,9 @@ function DomainRoleGrid() {
28587
28682
  });
28588
28683
  });
28589
28684
  };
28685
+ const checkIfExistDomainRoleWithoutFrontend = () => {
28686
+ return (allDomainRolesFrontends === null || allDomainRolesFrontends === void 0 ? void 0 : allDomainRolesFrontends.some(a => a.frontends.length === 0)) || false;
28687
+ };
28590
28688
  return jsxs(DataCard, {
28591
28689
  title: 'Ruoli utente',
28592
28690
  actions: [{
@@ -28594,89 +28692,133 @@ function DomainRoleGrid() {
28594
28692
  size: 18
28595
28693
  }),
28596
28694
  label: 'Nuovo ruolo',
28695
+ disabled: loading,
28597
28696
  onClick: () => {
28598
28697
  setCurrentDomainRole(undefined);
28599
28698
  setDomainRoleModalOpen(true);
28600
28699
  }
28601
28700
  }],
28602
- children: [jsxs(Table, {
28603
- highlightOnHover: true,
28604
- children: [jsx(Table.Thead, {
28605
- children: jsxs(Table.Tr, {
28606
- children: [jsx(Table.Th, {
28607
- w: 80,
28608
- children: "Id"
28609
- }), jsx(Table.Th, {
28610
- children: "Identificatore"
28611
- }), jsx(Table.Th, {
28612
- children: "Nome"
28613
- }), jsx(Table.Th, {
28614
- children: "Descrizione"
28615
- }), jsx(Table.Th, {
28616
- w: 100,
28617
- children: "Permessi"
28618
- }), jsx(Table.Th, {
28619
- w: 100
28620
- })]
28621
- })
28622
- }), jsx(Table.Tbody, {
28623
- children: domainRoles.map((element, i) => jsxs(Table.Tr, {
28624
- children: [jsx(Table.Td, {
28625
- w: 80,
28626
- children: element.id
28627
- }), jsx(Table.Td, {
28628
- children: element.identifier
28629
- }), jsx(Table.Td, {
28630
- children: element.name
28631
- }), jsx(Table.Td, {
28632
- children: element.description
28633
- }), jsx(Table.Td, {
28634
- w: 100,
28635
- children: element.permissionCount
28636
- }), jsx(Table.Td, {
28637
- w: 100,
28638
- align: "right",
28639
- children: jsxs(Menu, {
28640
- shadow: "md",
28641
- width: 200,
28642
- children: [jsx(Menu.Target, {
28643
- children: jsx(ActionIcon, {
28644
- children: jsx(IconDotsVertical, {
28645
- size: 18
28701
+ children: [jsxs(Box, {
28702
+ pos: "relative",
28703
+ children: [jsx(LoadingOverlay, {
28704
+ visible: loading,
28705
+ zIndex: 1000,
28706
+ overlayProps: {
28707
+ radius: "sm",
28708
+ blur: 2
28709
+ }
28710
+ }), jsxs(Stack, {
28711
+ children: [checkIfExistDomainRoleWithoutFrontend() && jsx(Alert, {
28712
+ color: 'yellow',
28713
+ title: 'Attenzione',
28714
+ children: "Esistono ruoli utente senza aree funzionali assegnate"
28715
+ }), jsxs(Table, {
28716
+ highlightOnHover: true,
28717
+ children: [jsx(Table.Thead, {
28718
+ children: jsxs(Table.Tr, {
28719
+ children: [jsx(Table.Th, {
28720
+ w: 50,
28721
+ children: "Id"
28722
+ }), jsx(Table.Th, {
28723
+ w: 150,
28724
+ children: "Identificatore"
28725
+ }), jsx(Table.Th, {
28726
+ w: 150,
28727
+ children: "Nome"
28728
+ }), jsx(Table.Th, {
28729
+ children: "Descrizione"
28730
+ }), jsx(Table.Th, {
28731
+ w: 100,
28732
+ children: "Permessi"
28733
+ }), jsx(Table.Th, {
28734
+ w: 100,
28735
+ children: "Aree"
28736
+ }), jsx(Table.Th, {
28737
+ w: 100
28738
+ })]
28739
+ })
28740
+ }), jsx(Table.Tbody, {
28741
+ children: domainRoles.map((element, i) => {
28742
+ var _a;
28743
+ return jsxs(Table.Tr, {
28744
+ children: [jsx(Table.Td, {
28745
+ w: 50,
28746
+ children: element.id
28747
+ }), jsx(Table.Td, {
28748
+ w: 150,
28749
+ children: element.identifier
28750
+ }), jsx(Table.Td, {
28751
+ w: 150,
28752
+ children: element.name
28753
+ }), jsx(Table.Td, {
28754
+ children: element.description
28755
+ }), jsx(Table.Td, {
28756
+ w: 100,
28757
+ children: element.permissionCount
28758
+ }), jsx(Table.Td, {
28759
+ w: 100,
28760
+ children: (_a = allDomainRolesFrontends === null || allDomainRolesFrontends === void 0 ? void 0 : allDomainRolesFrontends.find(a => a.domainRoleId === element.id)) === null || _a === void 0 ? void 0 : _a.frontends.map(f => {
28761
+ return jsx(Badge, {
28762
+ color: 'blue',
28763
+ children: f
28764
+ });
28765
+ })
28766
+ }), jsx(Table.Td, {
28767
+ w: 100,
28768
+ align: "right",
28769
+ children: jsxs(Menu, {
28770
+ shadow: "md",
28771
+ width: 200,
28772
+ children: [jsx(Menu.Target, {
28773
+ children: jsx(ActionIcon, {
28774
+ children: jsx(IconDotsVertical, {
28775
+ size: 18
28776
+ })
28777
+ })
28778
+ }), jsxs(Menu.Dropdown, {
28779
+ children: [jsx(Menu.Item, {
28780
+ leftSection: jsx(IconGridDots, {
28781
+ size: 14
28782
+ }),
28783
+ onClick: () => {
28784
+ setCurrentDomainRole(element);
28785
+ setUpdateDomainFrontendsModal(true);
28786
+ },
28787
+ children: "Aree funzionali"
28788
+ }), jsx(Menu.Item, {
28789
+ leftSection: jsx(IconLock, {
28790
+ size: 14
28791
+ }),
28792
+ onClick: () => {
28793
+ setCurrentDomainRole(element);
28794
+ setUpdateDomainRolePermissionsModal(true);
28795
+ },
28796
+ children: "Permessi"
28797
+ }), jsx(Menu.Item, {
28798
+ onClick: () => {
28799
+ setCurrentDomainRole(element);
28800
+ setDomainRoleModalOpen(true);
28801
+ },
28802
+ leftSection: jsx(IconEdit, {
28803
+ size: 14
28804
+ }),
28805
+ children: "Modifica"
28806
+ }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
28807
+ color: 'red',
28808
+ onClick: () => deleteDomainRole(element.id),
28809
+ leftSection: jsx(IconTrash, {
28810
+ color: 'red',
28811
+ size: 14
28812
+ }),
28813
+ children: "Elimina"
28814
+ })]
28815
+ })]
28646
28816
  })
28647
- })
28648
- }), jsxs(Menu.Dropdown, {
28649
- children: [jsx(Menu.Item, {
28650
- leftSection: jsx(IconLock, {
28651
- size: 14
28652
- }),
28653
- onClick: () => {
28654
- setCurrentDomainRole(element);
28655
- setUpdateDomainRolePermissionsModal(true);
28656
- },
28657
- children: "Permessi"
28658
- }), jsx(Menu.Item, {
28659
- onClick: () => {
28660
- setCurrentDomainRole(element);
28661
- setDomainRoleModalOpen(true);
28662
- },
28663
- leftSection: jsx(IconEdit, {
28664
- size: 14
28665
- }),
28666
- children: "Modifica"
28667
- }), jsx(Menu.Divider, {}), jsx(Menu.Item, {
28668
- color: 'red',
28669
- onClick: () => deleteDomainRole(element.id),
28670
- leftSection: jsx(IconTrash, {
28671
- color: 'red',
28672
- size: 14
28673
- }),
28674
- children: "Elimina"
28675
28817
  })]
28676
- })]
28818
+ }, i);
28677
28819
  })
28678
28820
  })]
28679
- }, i))
28821
+ })]
28680
28822
  })]
28681
28823
  }), jsx(Modal, {
28682
28824
  centered: true,
@@ -28694,23 +28836,40 @@ function DomainRoleGrid() {
28694
28836
  },
28695
28837
  domainRole: currentDomainRole
28696
28838
  })
28697
- }), currentDomainRole && jsx(Modal, {
28698
- size: '60%',
28699
- centered: true,
28700
- opened: updateDomainRolePermissionsModal,
28701
- onClose: () => {
28702
- setUpdateDomainRolePermissionsModal(false);
28703
- setCurrentDomainRole(undefined);
28704
- getAllDomainRoles();
28705
- },
28706
- title: `Gestione permessi ${currentDomainRole.name}`,
28707
- children: jsx(PermissionNavigator, {
28708
- context: {
28709
- type: 'domainRole',
28710
- id: currentDomainRole.id.toString()
28839
+ }), currentDomainRole && jsxs(Fragment, {
28840
+ children: [jsx(Modal, {
28841
+ size: '60%',
28842
+ centered: true,
28843
+ opened: updateDomainRolePermissionsModal,
28844
+ onClose: () => {
28845
+ setUpdateDomainRolePermissionsModal(false);
28846
+ setCurrentDomainRole(undefined);
28847
+ getAllDomainRoles();
28711
28848
  },
28712
- onUpdate: () => {}
28713
- })
28849
+ title: `Gestione permessi ${currentDomainRole.name}`,
28850
+ children: jsx(PermissionNavigator, {
28851
+ context: {
28852
+ type: 'domainRole',
28853
+ id: currentDomainRole.id.toString()
28854
+ },
28855
+ onUpdate: () => {}
28856
+ })
28857
+ }), jsx(Modal, {
28858
+ size: '40%',
28859
+ opened: updateDomainFrontendsModal,
28860
+ onClose: () => {
28861
+ setUpdateDomainFrontendsModal(false);
28862
+ },
28863
+ centered: true,
28864
+ title: `Gestione aree funzionali ${currentDomainRole.name}`,
28865
+ children: jsx(FrontendDomainRole, {
28866
+ domainRoleId: currentDomainRole.id,
28867
+ onClosed: () => {
28868
+ setUpdateDomainFrontendsModal(false);
28869
+ refreshDomainRoles();
28870
+ }
28871
+ })
28872
+ })]
28714
28873
  })]
28715
28874
  });
28716
28875
  }
@@ -29022,278 +29181,282 @@ function UsersGrid() {
29022
29181
  });
29023
29182
  }
29024
29183
 
29025
- function RouteRuleCreateForm(props) {
29026
- const [identifier, setIdentifier] = useState('');
29027
- const createRouteRule = () => {
29028
- if (!identifier) return;
29029
- const command = {
29030
- scope: props.scope,
29031
- packageName: props.packageName,
29032
- route: identifier
29033
- };
29034
- FluxoClientSys.Instance.security.routeRule.create(command).then(() => {
29184
+ function EmailServerConfiguration() {
29185
+ var _a, _b;
29186
+ const [configExists, setConfigExists] = useState(false);
29187
+ const [loading, setLoading] = useState(true);
29188
+ const [testEmailAddress, setTestEmailAddress] = useState('');
29189
+ const [testEmailSending, setTestEmailSending] = useState(false);
29190
+ const directForm = useForm({
29191
+ initialValues: {
29192
+ type: undefined,
29193
+ directServer: '',
29194
+ directPort: 0,
29195
+ directUser: '',
29196
+ directPassword: '',
29197
+ directUseSsl: true,
29198
+ mailgunDomain: '',
29199
+ mailgunApiKey: '',
29200
+ mailgunBaseUrl: ''
29201
+ },
29202
+ validate: values => {
29203
+ const errors = {};
29204
+ if (!values.fromName) {
29205
+ errors.fromName = 'Il nome del mittente è obbligatorio';
29206
+ }
29207
+ if (!values.fromAddress) {
29208
+ errors.fromAddress = 'L\'indirizzo email del mittente è obbligatorio';
29209
+ }
29210
+ if (values.type === EmailServerProviderType.Direct.toString()) {
29211
+ if (!values.directServer) {
29212
+ errors.directServer = 'Il server è obbligatorio';
29213
+ }
29214
+ if (!values.directPort) {
29215
+ errors.directPort = 'La porta è obbligatoria';
29216
+ }
29217
+ if (!values.directUser) {
29218
+ errors.directUser = 'L\'utente è obbligatorio';
29219
+ }
29220
+ if (!values.directPassword) {
29221
+ errors.directPassword = 'La password è obbligatoria';
29222
+ }
29223
+ } else {
29224
+ if (!values.mailgunDomain) {
29225
+ errors.mailgunDomain = 'Il dominio è obbligatorio';
29226
+ }
29227
+ if (!values.mailgunApiKey) {
29228
+ errors.mailgunApiKey = 'L\'API Key è obbligatoria';
29229
+ }
29230
+ if (!values.mailgunBaseUrl) {
29231
+ errors.mailgunBaseUrl = 'La base URL è obbligatoria';
29232
+ }
29233
+ }
29234
+ return errors;
29235
+ },
29236
+ transformValues: values => {
29237
+ return Object.assign(Object.assign({}, values), {
29238
+ type: +values.type,
29239
+ directPort: values.directPort ? +values.directPort : undefined
29240
+ });
29241
+ }
29242
+ });
29243
+ useEffect(() => {
29244
+ FluxoClientSys.Instance.communication.mailServer.getConfiguration().then(c => {
29245
+ if (c) {
29246
+ setConfigExists(true);
29247
+ directForm.setFieldValue('fromName', c.fromName);
29248
+ directForm.setFieldValue('fromAddress', c.fromAddress);
29249
+ directForm.setFieldValue('type', c.type.toString());
29250
+ directForm.setFieldValue('directServer', c.directServer);
29251
+ directForm.setFieldValue('directPort', c.directPort);
29252
+ directForm.setFieldValue('directUser', c.directUser);
29253
+ directForm.setFieldValue('directPassword', c.directPassword);
29254
+ directForm.setFieldValue('directUseSsl', c.directUseSsl);
29255
+ directForm.setFieldValue('mailgunDomain', c.mailgunDomain);
29256
+ directForm.setFieldValue('mailgunApiKey', c.mailgunApiKey);
29257
+ directForm.setFieldValue('mailgunBaseUrl', c.mailgunBaseUrl);
29258
+ } else {
29259
+ setConfigExists(false);
29260
+ }
29261
+ }).catch(() => {
29262
+ setConfigExists(false);
29263
+ }).finally(() => {
29264
+ setLoading(false);
29265
+ });
29266
+ }, []);
29267
+ const saveConfig = values => {
29268
+ setLoading(true);
29269
+ FluxoClientSys.Instance.communication.mailServer.saveConfiguration({
29270
+ fromAddress: values.fromAddress,
29271
+ fromName: values.fromName,
29272
+ directServer: values.directServer,
29273
+ directPort: values.directPort,
29274
+ directUser: values.directUser,
29275
+ directPassword: values.directPassword,
29276
+ directUseSsl: values.directUseSsl,
29277
+ mailgunDomain: values.mailgunDomain,
29278
+ mailgunApiKey: values.mailgunApiKey,
29279
+ mailgunBaseUrl: values.mailgunBaseUrl,
29280
+ type: +values.type
29281
+ }).then(() => {
29035
29282
  showNotification({
29036
- title: 'Regola creata',
29037
- message: `La regola ${props.scope}.${props.packageName}.${identifier} è stato creata con successo.`,
29283
+ title: 'Configurazione salvata',
29284
+ message: 'La configurazione è stata salvata con successo',
29038
29285
  color: 'green'
29039
29286
  });
29040
- props.onCreated();
29041
29287
  }).catch(() => {
29042
29288
  showNotification({
29043
29289
  title: 'Errore',
29044
- message: `Si è verificato un errore durante la creazione della regola ${props.scope}.${props.packageName}.${identifier}.`,
29290
+ message: 'Si è verificato un errore durante il salvataggio della configurazione',
29045
29291
  color: 'red'
29046
29292
  });
29293
+ }).finally(() => {
29294
+ setLoading(false);
29047
29295
  });
29048
29296
  };
29049
- return jsxs(Stack, {
29050
- children: [jsx(TextInput, {
29051
- label: "Identificatore",
29052
- placeholder: 'Es: create',
29053
- required: true,
29054
- onChange: v => setIdentifier(v.target.value)
29055
- }), jsxs("p", {
29056
- children: ["Rotta: ", `${props.scope}/${props.packageName}/${identifier}`]
29057
- }), jsx(Divider, {}), jsxs(Group, {
29058
- justify: 'right',
29059
- children: [jsx(Button, {
29060
- variant: 'subtle',
29061
- onClick: props.onCanceled,
29062
- children: "Annulla"
29063
- }), jsx(Button, {
29064
- disabled: !identifier,
29065
- onClick: createRouteRule,
29066
- children: "Salva"
29067
- })]
29068
- })]
29069
- });
29070
- }
29071
-
29072
- function RouteRuleGrid() {
29073
- const [permissionScopes, setPermissionScopes] = useState([]);
29074
- const [permissionScopesLoaded, setPermissionScopesLoaded] = useState(false);
29075
- const [currentScope, setCurrentScope] = useState(null);
29076
- const [currentPackageName, setCurrentPackageName] = useState(null);
29077
- const [routeRules, setRouteRules] = useState([]);
29078
- const [permissionLoading, setPermissionLoading] = useState(false);
29079
- const [currentRouteRule, setCurrentRouteRule] = useState();
29080
- const [managePermissionModalOpened, setManagePermissionModalOpened] = useState(false);
29081
- const [createRouteRuleModalOpened, setCreateRouteRuleModalOpened] = useState(false);
29082
- useEffect(() => {
29083
- loadPermissionScopes();
29084
- }, []);
29085
- useEffect(() => {
29086
- if (currentScope && currentPackageName) getRouteRulesForScope();else setRouteRules([]);
29087
- }, [currentScope, currentPackageName]);
29088
- const getRouteRulesForScope = () => {
29089
- if (!currentScope || !currentPackageName) {
29090
- return;
29091
- }
29092
- setPermissionLoading(true);
29093
- FluxoClientSys.Instance.security.routeRule.getRouteRulesForScope(currentScope, currentPackageName).then(res => {
29094
- setRouteRules(res);
29095
- setPermissionLoading(false);
29096
- });
29097
- };
29098
- const loadPermissionScopes = () => {
29099
- FluxoClientSys.Instance.security.permission.getPermissionScopes().then(res => {
29100
- setPermissionScopes(res);
29101
- setPermissionScopesLoaded(true);
29102
- });
29103
- };
29104
- const deleteRouteRule = routeRule => {
29105
- FluxoClientSys.Instance.security.routeRule.delete(routeRule.id.toString()).then(() => {
29297
+ const testSendEmail = () => {
29298
+ setTestEmailSending(true);
29299
+ FluxoClientSys.Instance.communication.mailServer.sendTestEmail({
29300
+ emailAddress: testEmailAddress
29301
+ }).then(() => {
29106
29302
  showNotification({
29107
- title: 'Regola eliminata',
29108
- message: `La regola ${routeRule.scope}.${routeRule.packageName}.${routeRule.route} è stato eliminata con successo.`,
29303
+ title: 'Email inviata',
29304
+ message: 'L\'email è stata inviata con successo',
29109
29305
  color: 'green'
29110
29306
  });
29111
- getRouteRulesForScope();
29112
29307
  }).catch(() => {
29113
29308
  showNotification({
29114
29309
  title: 'Errore',
29115
- message: `Si è verificato un errore durante l'eliminazione della regola ${routeRule.scope}.${routeRule.packageName}.${routeRule.route}.`,
29310
+ message: 'Si è verificato un errore durante l\'invio dell\'email',
29116
29311
  color: 'red'
29117
29312
  });
29313
+ }).finally(() => {
29314
+ setTestEmailSending(false);
29118
29315
  });
29119
29316
  };
29120
- const getScopes = () => {
29121
- if (permissionScopes === undefined) return [];
29122
- return [...new Set(permissionScopes.map(a => a.scope))];
29123
- };
29124
- const getPackageNames = scope => {
29125
- if (permissionScopes === undefined || !scope) return [];
29126
- return [...new Set(permissionScopes.filter(a => a.scope === scope).map(a => a.packageName))];
29127
- };
29128
- return jsxs(DataCard, {
29129
- title: 'Regole sulle rotte',
29130
- children: [jsxs(Stack, {
29131
- children: [jsxs(Grid, {
29132
- children: [jsx(Grid.Col, {
29133
- span: 6,
29134
- children: jsx(Select, {
29135
- data: getScopes(),
29136
- searchable: true,
29137
- placeholder: 'Seleziona uno scope',
29138
- value: currentScope,
29139
- label: 'Scope',
29140
- onChange: v => {
29141
- setCurrentScope(v);
29142
- setCurrentPackageName(null);
29143
- }
29144
- })
29145
- }), jsx(Grid.Col, {
29146
- span: 6,
29147
- children: jsx(Select, {
29148
- disabled: !currentScope,
29149
- searchable: true,
29150
- placeholder: 'Seleziona un package name',
29151
- data: getPackageNames(currentScope),
29152
- value: currentPackageName,
29153
- label: 'Package name',
29154
- onChange: v => {
29155
- setCurrentPackageName(v);
29156
- }
29157
- })
29158
- })]
29159
- }), jsx(Divider, {}), (currentScope && currentPackageName && !permissionLoading && routeRules.length) === 0 && jsxs(Stack, {
29160
- children: [jsx(Group, {
29161
- justify: 'right',
29162
- align: 'center',
29163
- children: jsx(Button, {
29164
- leftSection: jsx(IconPlus, {
29165
- size: 18
29166
- }),
29167
- onClick: () => setCreateRouteRuleModalOpened(true),
29168
- children: "Nuova regola"
29169
- })
29170
- }), jsx(Center, {
29171
- children: jsx(Text, {
29172
- size: 'md',
29173
- children: "Nessuna regola esistente."
29174
- })
29175
- })]
29176
- }), (!currentScope || !currentPackageName) && jsxs(Stack, {
29177
- align: 'center',
29178
- mt: 32,
29179
- mb: 32,
29180
- children: [jsx(IconCloudOff, {
29181
- color: 'gray',
29182
- size: 64
29183
- }), jsx(Center, {
29184
- children: jsx(Text, {
29185
- size: 'md',
29186
- children: "Seleziona uno scope e un package name per visualizzare i permessi associati."
29187
- })
29188
- })]
29189
- }), !permissionLoading && routeRules.length > 0 && jsxs(Stack, {
29190
- children: [jsx(Group, {
29191
- justify: 'right',
29192
- align: 'center',
29193
- children: jsx(Button, {
29194
- leftSection: jsx(IconPlus, {
29195
- size: 18
29317
+ const isTestEmailAddressValid = useCallback(() => {
29318
+ if (!testEmailAddress) return false;
29319
+ const re = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g;
29320
+ return re.test(testEmailAddress);
29321
+ }, [testEmailAddress]);
29322
+ return jsxs(Box, {
29323
+ pos: "relative",
29324
+ children: [jsx(LoadingOverlay, {
29325
+ visible: loading,
29326
+ zIndex: 1000,
29327
+ overlayProps: {
29328
+ radius: "sm",
29329
+ blur: 2
29330
+ }
29331
+ }), jsxs(Stack, {
29332
+ children: [jsx(DataCard, {
29333
+ title: "Configurazione server email",
29334
+ children: jsxs(Stack, {
29335
+ children: [!configExists && jsx(Alert, {
29336
+ color: "yellow",
29337
+ title: "Configurazione non trovata",
29338
+ children: "Non \u00E8 stata trovata alcuna configurazione per il server email. Si prega di configurare il server email prima di procedere."
29339
+ }), !directForm.values['type'] && jsxs(Fragment, {
29340
+ children: [jsx(Text, {
29341
+ size: 'lg',
29342
+ children: "Scegli il provider:"
29343
+ }), jsxs(Group, {
29344
+ children: [jsx(Button, {
29345
+ onClick: () => directForm.setFieldValue('type', EmailServerProviderType.Direct.toString()),
29346
+ children: "Server SMTP"
29347
+ }), jsx(Button, {
29348
+ onClick: () => directForm.setFieldValue('type', EmailServerProviderType.Mailgun.toString()),
29349
+ children: "Mailgun"
29350
+ })]
29351
+ })]
29352
+ }), jsxs("form", {
29353
+ id: 'providerForm',
29354
+ autoComplete: 'off',
29355
+ onSubmit: directForm.onSubmit((values, event) => {
29356
+ if (directForm.isValid()) saveConfig(values);
29196
29357
  }),
29197
- onClick: () => setCreateRouteRuleModalOpened(true),
29198
- children: "Nuova regola"
29199
- })
29200
- }), jsxs(Table, {
29201
- highlightOnHover: true,
29202
- children: [jsx(Table.Thead, {
29203
- children: jsxs(Table.Tr, {
29204
- children: [jsx(Table.Th, {
29205
- children: "Id"
29206
- }), jsx(Table.Th, {
29207
- children: "Scope"
29208
- }), jsx(Table.Th, {
29209
- children: "Rotta"
29210
- }), jsx(Table.Th, {
29211
- children: "Permessi"
29212
- }), jsx(Table.Th, {
29213
- style: {
29214
- maxWidth: 80,
29215
- width: 80
29216
- },
29217
- children: "Azioni"
29358
+ children: [((_a = directForm.values['type']) === null || _a === void 0 ? void 0 : _a.toString()) === '0' && jsxs(Stack, {
29359
+ children: [jsx(Select, Object.assign({
29360
+ data: [{
29361
+ label: 'Server SMTP',
29362
+ value: '0'
29363
+ }, {
29364
+ label: 'Mailgun',
29365
+ value: '1'
29366
+ }],
29367
+ label: "Provider"
29368
+ }, directForm.getInputProps('type'), {
29369
+ placeholder: "Seleziona provider"
29370
+ })), jsx(TextInput, Object.assign({
29371
+ label: "Email Mittente",
29372
+ placeholder: "jhon@example.com"
29373
+ }, directForm.getInputProps('fromAddress'))), jsx(TextInput, Object.assign({
29374
+ label: "Nome Mittente",
29375
+ placeholder: "Jhon Red"
29376
+ }, directForm.getInputProps('fromName'))), jsx(TextInput, Object.assign({
29377
+ label: "Server SMTP",
29378
+ placeholder: "smtp.example.com"
29379
+ }, directForm.getInputProps('directServer'))), jsx(NumberInput, Object.assign({
29380
+ label: "Porta",
29381
+ placeholder: "587"
29382
+ }, directForm.getInputProps('directPort'))), jsx(TextInput, Object.assign({
29383
+ label: "Username",
29384
+ placeholder: "user@example.com"
29385
+ }, directForm.getInputProps('directUser'))), jsx(TextInput, Object.assign({
29386
+ label: "Password",
29387
+ type: "password"
29388
+ }, directForm.getInputProps('directPassword'))), jsx(Switch, Object.assign({
29389
+ label: 'SSL/TLS'
29390
+ }, directForm.getInputProps('directUseSsl', {
29391
+ type: 'checkbox'
29392
+ })))]
29393
+ }), ((_b = directForm.values['type']) === null || _b === void 0 ? void 0 : _b.toString()) === '1' && jsxs(Stack, {
29394
+ children: [jsx(Select, Object.assign({
29395
+ data: [{
29396
+ label: 'Server SMTP',
29397
+ value: '0'
29398
+ }, {
29399
+ label: 'Mailgun',
29400
+ value: '1'
29401
+ }],
29402
+ label: "Provider"
29403
+ }, directForm.getInputProps('type'), {
29404
+ placeholder: "Seleziona provider",
29405
+ autoComplete: 'off'
29406
+ })), jsx(TextInput, Object.assign({
29407
+ label: "Email Mittente",
29408
+ placeholder: "jhon@example.com"
29409
+ }, directForm.getInputProps('fromAddress'))), jsx(TextInput, Object.assign({
29410
+ label: "Nome Mittente",
29411
+ placeholder: "Jhon Red"
29412
+ }, directForm.getInputProps('fromName'))), jsx(TextInput, Object.assign({
29413
+ label: "Base URL",
29414
+ placeholder: 'Es: https://api.eu.mailgun.net/v3'
29415
+ }, directForm.getInputProps('mailgunBaseUrl'))), jsx(TextInput, Object.assign({
29416
+ label: "Dominio",
29417
+ placeholder: 'Es: mg.example.com'
29418
+ }, directForm.getInputProps('mailgunDomain'))), jsx(PasswordInput, Object.assign({
29419
+ autoComplete: 'off',
29420
+ label: "API Key"
29421
+ }, directForm.getInputProps('mailgunApiKey')))]
29422
+ }), directForm.values['type'] !== undefined && jsxs(Stack, {
29423
+ children: [jsx(Divider, {
29424
+ mt: 16
29425
+ }), jsx(Group, {
29426
+ justify: 'right',
29427
+ align: 'end',
29428
+ children: jsx(Button, {
29429
+ type: 'submit',
29430
+ children: "Salva"
29431
+ })
29218
29432
  })]
29219
- })
29220
- }), jsx(Table.Tbody, {
29221
- children: routeRules.map((element, i) => {
29222
- return jsxs(Table.Tr, {
29223
- children: [jsx(Table.Td, {
29224
- children: element.id
29225
- }), jsx(Table.Td, {
29226
- children: `${element.scope}.${element.packageName}`
29227
- }), jsx(Table.Td, {
29228
- children: `/${element.scope}/${element.packageName}/${element.route}`
29229
- }), jsx(Table.Td, {
29230
- children: element.permissionsCount
29231
- }), jsx(Table.Td, {
29232
- style: {
29233
- maxWidth: 130,
29234
- width: 130
29235
- },
29236
- children: jsxs(Group, {
29237
- children: [jsx(ActionIcon, {
29238
- onClick: () => {
29239
- setCurrentRouteRule(element);
29240
- setManagePermissionModalOpened(true);
29241
- },
29242
- children: jsx(IconLock, {
29243
- size: 18
29244
- })
29245
- }), jsx(ActionIcon, {
29246
- onClick: () => {
29247
- deleteRouteRule(element);
29248
- },
29249
- children: jsx(IconTrash, {
29250
- size: 18
29251
- })
29252
- })]
29253
- })
29254
- })]
29255
- }, i);
29433
+ })]
29434
+ })]
29435
+ })
29436
+ }), !configExists && jsx(DataCard, {
29437
+ title: "Test invio email",
29438
+ children: jsxs(Stack, {
29439
+ children: [jsx(Alert, {
29440
+ color: "yellow",
29441
+ title: "Attenzione",
29442
+ children: "Questa funzione invier\u00E0 una email di test al destinatario specificato con l'ultima configurazione salvata"
29443
+ }), jsx(TextInput, {
29444
+ label: "Email destinatario",
29445
+ value: testEmailAddress,
29446
+ onChange: v => setTestEmailAddress(v.target.value),
29447
+ placeholder: "Es: jhon@example.com"
29448
+ }), jsx(Group, {
29449
+ justify: 'right',
29450
+ align: 'end',
29451
+ children: jsx(Button, {
29452
+ loading: testEmailSending,
29453
+ disabled: !isTestEmailAddressValid(),
29454
+ onClick: testSendEmail,
29455
+ children: "Invia"
29256
29456
  })
29257
29457
  })]
29258
- })]
29458
+ })
29259
29459
  })]
29260
- }), currentRouteRule && jsx(Modal, {
29261
- size: '60%',
29262
- centered: true,
29263
- opened: managePermissionModalOpened,
29264
- onClose: () => {
29265
- getRouteRulesForScope();
29266
- setManagePermissionModalOpened(false);
29267
- setCurrentRouteRule(undefined);
29268
- },
29269
- title: `Gestione permessi ${currentRouteRule.route}`,
29270
- children: jsx(PermissionNavigator, {
29271
- context: {
29272
- type: 'route-rule',
29273
- id: currentRouteRule.id.toString()
29274
- },
29275
- onUpdate: () => {}
29276
- })
29277
- }), jsx(Modal, {
29278
- size: '60%',
29279
- centered: true,
29280
- opened: createRouteRuleModalOpened,
29281
- onClose: () => {
29282
- getRouteRulesForScope();
29283
- setCreateRouteRuleModalOpened(false);
29284
- },
29285
- title: `Crea nuova regola`,
29286
- children: jsx(RouteRuleCreateForm, {
29287
- scope: currentScope,
29288
- packageName: currentPackageName,
29289
- onCreated: () => {
29290
- getRouteRulesForScope();
29291
- setCreateRouteRuleModalOpened(false);
29292
- },
29293
- onCanceled: () => {
29294
- setCreateRouteRuleModalOpened(false);
29295
- }
29296
- })
29297
29460
  })]
29298
29461
  });
29299
29462
  }
@@ -29389,24 +29552,23 @@ function Settings(props) {
29389
29552
  size: 18
29390
29553
  }),
29391
29554
  description: 'Gestisci i permessi utente'
29392
- }, {
29393
- key: 'routes',
29394
- title: jsxs(Text, {
29395
- children: ["Regole sulle rotte ", jsx("small", {
29396
- children: jsx("b", {
29397
- children: "(Avanzato)"
29398
- })
29399
- })]
29555
+ }]
29556
+ }, {
29557
+ name: 'Comunicazioni',
29558
+ items: [{
29559
+ key: 'email-configuration',
29560
+ title: jsx(Text, {
29561
+ children: "Configurazione e-mail"
29400
29562
  }),
29401
29563
  onClick: () => {
29402
- window.location.hash = 'routes';
29403
- setCurrentTab('routes');
29564
+ window.location.hash = 'email-configuration';
29565
+ setCurrentTab('email-configuration');
29404
29566
  },
29405
29567
  disabled: false,
29406
- icon: jsx(IconRoute, {
29568
+ icon: jsx(IconMail, {
29407
29569
  size: 18
29408
29570
  }),
29409
- description: 'Gestisci le regole sulle rotte'
29571
+ description: 'Configura il server di posta'
29410
29572
  }]
29411
29573
  }, {
29412
29574
  name: 'Integrazione',
@@ -29540,10 +29702,10 @@ function Settings(props) {
29540
29702
  return jsx(DomainRoleGrid, {});
29541
29703
  case 'permissions':
29542
29704
  return jsx(PermissionGrid, {});
29543
- case 'routes':
29544
- return jsx(RouteRuleGrid, {});
29545
29705
  case 'print-server':
29546
29706
  return jsx(PrintServerList, {});
29707
+ case 'email-configuration':
29708
+ return jsx(EmailServerConfiguration, {});
29547
29709
  case 'apidoc':
29548
29710
  return apiRestDoc ? jsx(DataCard, {
29549
29711
  title: 'Documentazione API REST',
@@ -29580,7 +29742,7 @@ function MainRoutes(props) {
29580
29742
  default: KorebiIde
29581
29743
  })));
29582
29744
  return jsxs(FlxRoutes, {
29583
- children: [props.isAdminFrontend && jsxs(Fragment, {
29745
+ children: [props.isAdminFrontend && props.hasAdminAccess && jsxs(Fragment, {
29584
29746
  children: [jsx(Route, {
29585
29747
  path: 'settings',
29586
29748
  element: jsx(Settings, {
@@ -30143,6 +30305,47 @@ function FluxoShell(props) {
30143
30305
  checkFrontendSetup(props.frontends);
30144
30306
  // Get the initial configuration
30145
30307
  FluxoClientSys.Instance.configuration.getInitialConfiguration().then(res => {
30308
+ // If the user allowedFrontends is empty and user is logged, return a router with an error page (unauthorized)
30309
+ if (res.frontends.length === 0 && res.isUserLogged) {
30310
+ setRouter(createBrowserRouter([{
30311
+ path: '*',
30312
+ element: jsx(Center, {
30313
+ w: '100%',
30314
+ children: jsx(Card, {
30315
+ maw: 450,
30316
+ w: 450,
30317
+ withBorder: true,
30318
+ mt: 64,
30319
+ children: jsxs(Stack, {
30320
+ justify: 'center',
30321
+ align: 'center',
30322
+ children: [jsx(Text, {
30323
+ size: "xl",
30324
+ color: 'red',
30325
+ children: "Autorizzazioni mancanti"
30326
+ }), jsx(Text, {
30327
+ size: "sm",
30328
+ children: "Contatta l'amministratore di sistema"
30329
+ }), jsx(Divider, {
30330
+ w: '100%'
30331
+ }), jsx(Center, {
30332
+ children: jsx(Button, {
30333
+ onClick: () => {
30334
+ FluxoClientSys.Instance.auth.logout();
30335
+ window.location.reload();
30336
+ },
30337
+ children: "Esci"
30338
+ })
30339
+ })]
30340
+ })
30341
+ })
30342
+ })
30343
+ }], {
30344
+ basename: '/'
30345
+ }));
30346
+ setBrandColors(res.ui.colors);
30347
+ return;
30348
+ }
30146
30349
  // Get the frontend to render
30147
30350
  let frontendByRender = props.frontends.find(f => f.id === res.currentFrontend);
30148
30351
  // If no frontend to render is found, get the default one
@@ -30166,13 +30369,13 @@ function FluxoShell(props) {
30166
30369
  FluxoStateDispatcher.dispatchSetSysFeatures(res.features);
30167
30370
  FluxoStateDispatcher.dispatchSetUserPermissions(res.permissions.map(a => a.fullIdentifier));
30168
30371
  FluxoStateDispatcher.dispatchSetUserDomainRoles(res.domainRoles);
30169
- FluxoStateDispatcher.dispatchSetRouteRules(res.routeRules);
30170
30372
  FluxoStateDispatcher.dispatchSetFrontends(props.frontends.map(a => ({
30171
30373
  id: a.id,
30172
30374
  name: a.name
30173
30375
  })));
30174
30376
  FluxoStateDispatcher.dispatchSetCurrentFrontend(res.currentFrontend);
30175
30377
  FluxoStateDispatcher.dispatchAllowedFrontends(res.frontends);
30378
+ FluxoStateDispatcher.dispatchHasAdminAccess(res.hasAdminAccess);
30176
30379
  const rObjs = [generateAuthRoutes(), {
30177
30380
  path: 'frontend-switcher',
30178
30381
  element: jsx(ProtectedRoute, {
@@ -30189,6 +30392,7 @@ function FluxoShell(props) {
30189
30392
  }, {
30190
30393
  path: '/*',
30191
30394
  element: jsx(MainRoutes, {
30395
+ hasAdminAccess: res.hasAdminAccess,
30192
30396
  isAdminFrontend: flxFrontend.id === 'admin',
30193
30397
  pluginEndpoint: props.pluginEndpoint,
30194
30398
  frontends: props.frontends
@@ -30268,6 +30472,12 @@ function FluxoShell(props) {
30268
30472
  fontSize: '10.5pt'
30269
30473
  }
30270
30474
  },
30475
+ PasswordInput: {
30476
+ defaultProps: {
30477
+ size: 'xs',
30478
+ fontSize: '10.5pt'
30479
+ }
30480
+ },
30271
30481
  Textarea: {
30272
30482
  defaultProps: {
30273
30483
  size: 'xs',