@oondemand/oon-core-front 0.3.58 → 0.3.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4220,10 +4220,21 @@ import { jsx as jsx25 } from "react/jsx-runtime";
4220
4220
  function slug2(value2) {
4221
4221
  return value2.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
4222
4222
  }
4223
- function requiredAccess2(source) {
4224
- const values = [...source.permissions ?? [], ...source.capabilities ?? []].filter(Boolean);
4223
+ function requiredPermissions(source) {
4224
+ const values = [...source.permissions ?? []].filter(Boolean);
4225
4225
  return values.length ? values : void 0;
4226
4226
  }
4227
+ function declaredAppCapabilities(config) {
4228
+ const capabilities = config.app.capabilities;
4229
+ return Array.isArray(capabilities) ? capabilities : void 0;
4230
+ }
4231
+ function supportsCapabilities(config, source) {
4232
+ const required = (source.capabilities ?? []).filter(Boolean);
4233
+ if (!required.length) return true;
4234
+ const declared = declaredAppCapabilities(config);
4235
+ if (!declared) return true;
4236
+ return required.every((capability) => declared.includes(capability));
4237
+ }
4227
4238
  function viewId(view) {
4228
4239
  if (view.id) return view.id;
4229
4240
  if (view.type === "dashboard") return "dashboard";
@@ -4299,15 +4310,29 @@ function viewToRoute(view, registry) {
4299
4310
  return {
4300
4311
  path: viewPath(view),
4301
4312
  element: renderView(view, registry),
4302
- permissions: requiredAccess2(view)
4313
+ permissions: requiredPermissions(view),
4314
+ capabilities: "capabilities" in view ? view.capabilities : void 0
4303
4315
  };
4304
4316
  }
4305
4317
  function pageToRoute(page, registry) {
4306
- return { path: page.path, element: /* @__PURE__ */ jsx25(CorePage2, { page, registry }), permissions: requiredAccess2(page) };
4318
+ return {
4319
+ path: page.path,
4320
+ element: /* @__PURE__ */ jsx25(CorePage2, { page, registry }),
4321
+ permissions: requiredPermissions(page),
4322
+ capabilities: page.capabilities
4323
+ };
4307
4324
  }
4308
4325
  function pageToMenu(page) {
4309
4326
  if (page.hidden || !page.label) return null;
4310
- return { label: page.label, href: page.path, icon: page.icon, section: page.section, permissions: requiredAccess2(page), capabilities: page.capabilities, order: page.order };
4327
+ return {
4328
+ label: page.label,
4329
+ href: page.path,
4330
+ icon: page.icon,
4331
+ section: page.section,
4332
+ permissions: requiredPermissions(page),
4333
+ capabilities: page.capabilities,
4334
+ order: page.order
4335
+ };
4311
4336
  }
4312
4337
  function viewToMenu(view) {
4313
4338
  return {
@@ -4315,7 +4340,7 @@ function viewToMenu(view) {
4315
4340
  href: viewPath(view),
4316
4341
  icon: view.icon,
4317
4342
  section: view.section,
4318
- permissions: requiredAccess2(view),
4343
+ permissions: requiredPermissions(view),
4319
4344
  capabilities: "capabilities" in view ? view.capabilities : void 0
4320
4345
  };
4321
4346
  }
@@ -4325,16 +4350,20 @@ function resolveRegistry(config) {
4325
4350
  const seenPaths = /* @__PURE__ */ new Set();
4326
4351
  const componentRegistry = config.registry ?? config.ui?.registry;
4327
4352
  const pushRoute = (route) => {
4328
- if (seenPaths.has(route.path)) return;
4353
+ if (!supportsCapabilities(config, route) || seenPaths.has(route.path)) return;
4329
4354
  seenPaths.add(route.path);
4330
- routes.push(route);
4355
+ routes.push({ ...route, permissions: requiredPermissions(route) });
4356
+ };
4357
+ const pushMenu = (item) => {
4358
+ if (!supportsCapabilities(config, item)) return;
4359
+ menu.push({ ...item, permissions: requiredPermissions(item) });
4331
4360
  };
4332
4361
  for (const mod of config.modules ?? []) {
4333
- for (const route of mod.routes ?? []) pushRoute({ ...route, permissions: requiredAccess2(route) });
4334
- for (const item of mod.menu ?? []) menu.push({ ...item, permissions: requiredAccess2(item) });
4362
+ for (const route of mod.routes ?? []) pushRoute(route);
4363
+ for (const item of mod.menu ?? []) pushMenu(item);
4335
4364
  for (const view of mod.views ?? []) {
4336
4365
  pushRoute(viewToRoute(view, componentRegistry));
4337
- menu.push(viewToMenu(view));
4366
+ pushMenu(viewToMenu(view));
4338
4367
  }
4339
4368
  }
4340
4369
  const navMode = config.ui?.navigation?.mode ?? "auto";
@@ -4343,16 +4372,16 @@ function resolveRegistry(config) {
4343
4372
  if (includeAuto) {
4344
4373
  for (const view of config.ui?.views ?? []) {
4345
4374
  pushRoute(viewToRoute(view, componentRegistry));
4346
- menu.push(viewToMenu(view));
4375
+ pushMenu(viewToMenu(view));
4347
4376
  }
4348
4377
  for (const page of config.ui?.pages ?? []) {
4349
4378
  pushRoute(pageToRoute(page, componentRegistry));
4350
4379
  const item = pageToMenu(page);
4351
- if (item) menu.push(item);
4380
+ if (item) pushMenu(item);
4352
4381
  }
4353
4382
  }
4354
4383
  if (includeManual) {
4355
- for (const item of config.ui?.navigation?.items ?? []) menu.push({ ...item, permissions: requiredAccess2(item) });
4384
+ for (const item of config.ui?.navigation?.items ?? []) pushMenu(item);
4356
4385
  }
4357
4386
  menu.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
4358
4387
  return { routes, menu };
@@ -4366,7 +4395,7 @@ import {
4366
4395
 
4367
4396
  // src/shell/DefaultShell.tsx
4368
4397
  import { Box as Box18, Button as Button11, Flex as Flex11, Spacer as Spacer2, Text as Text19 } from "@chakra-ui/react";
4369
- import { Outlet } from "react-router-dom";
4398
+ import { Outlet, useNavigate } from "react-router-dom";
4370
4399
 
4371
4400
  // src/shell/Sidebar.tsx
4372
4401
  import { Box as Box17, Flex as Flex10, Image, Stack as Stack8, Text as Text18 } from "@chakra-ui/react";
@@ -4473,7 +4502,7 @@ function Sidebar({ app, menu, registry }) {
4473
4502
  // package.json
4474
4503
  var package_default = {
4475
4504
  name: "@oondemand/oon-core-front",
4476
- version: "0.3.58",
4505
+ version: "0.3.59",
4477
4506
  repository: {
4478
4507
  type: "git",
4479
4508
  url: "git+https://github.com/oondemand/oon-platform.git",
@@ -4593,8 +4622,50 @@ function shortCommit(commit) {
4593
4622
 
4594
4623
  // src/shell/DefaultShell.tsx
4595
4624
  import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
4596
- function CoreTopbar({ app }) {
4597
- const { user, logout } = useOonAuth();
4625
+ function SettingsIcon() {
4626
+ return /* @__PURE__ */ jsxs19(
4627
+ "svg",
4628
+ {
4629
+ "aria-hidden": "true",
4630
+ width: "18",
4631
+ height: "18",
4632
+ viewBox: "0 0 24 24",
4633
+ fill: "none",
4634
+ xmlns: "http://www.w3.org/2000/svg",
4635
+ children: [
4636
+ /* @__PURE__ */ jsx27(
4637
+ "path",
4638
+ {
4639
+ d: "M12 15.25a3.25 3.25 0 1 0 0-6.5 3.25 3.25 0 0 0 0 6.5Z",
4640
+ stroke: "currentColor",
4641
+ strokeWidth: "1.8"
4642
+ }
4643
+ ),
4644
+ /* @__PURE__ */ jsx27(
4645
+ "path",
4646
+ {
4647
+ d: "M19.43 12.98c.04-.32.07-.65.07-.98s-.03-.66-.08-.98l2.12-1.66-2-3.46-2.5 1a7.64 7.64 0 0 0-1.7-.98L15 3.25h-4l-.35 2.67c-.61.25-1.18.58-1.7.98l-2.5-1-2 3.46 2.12 1.66c-.04.32-.07.65-.07.98s.03.66.08.98l-2.12 1.66 2 3.46 2.5-1c.52.4 1.09.73 1.7.98l.34 2.67h4l.35-2.67a7.64 7.64 0 0 0 1.7-.98l2.5 1 2-3.46-2.12-1.66Z",
4648
+ stroke: "currentColor",
4649
+ strokeWidth: "1.8",
4650
+ strokeLinecap: "round",
4651
+ strokeLinejoin: "round"
4652
+ }
4653
+ )
4654
+ ]
4655
+ }
4656
+ );
4657
+ }
4658
+ function resolveSettingsHref(menu) {
4659
+ const explicit = menu.find((item) => item.action === "settings");
4660
+ if (explicit) return explicit.href;
4661
+ const settingsPage = menu.find((item) => item.href === "/configuracoes");
4662
+ if (settingsPage) return settingsPage.href;
4663
+ const integrationsPage = menu.find((item) => item.href === "/integracoes");
4664
+ return integrationsPage?.href ?? null;
4665
+ }
4666
+ function CoreTopbar({ app, menu }) {
4667
+ const { user, logout, hasPermission } = useOonAuth();
4668
+ const navigate = useNavigate();
4598
4669
  const metadataQuery = useCoreMetadata();
4599
4670
  const runtime = resolveRuntimeVersionInfo(app, metadataQuery.data);
4600
4671
  const centralVersion = runtime.centralVersion ?? "n\xE3o informada";
@@ -4615,6 +4686,9 @@ function CoreTopbar({ app }) {
4615
4686
  runtime.releaseId ? `Release ${runtime.releaseId}` : void 0,
4616
4687
  runtime.startedAt ? `Backend iniciado ${formatRuntimeDate(runtime.startedAt)}` : void 0
4617
4688
  ].filter(Boolean).join(" \xB7 ");
4689
+ const settingsHref = resolveSettingsHref(
4690
+ menu.filter((item) => !item.hidden && hasPermission(item.permissions))
4691
+ );
4618
4692
  return /* @__PURE__ */ jsxs19(
4619
4693
  Flex11,
4620
4694
  {
@@ -4660,6 +4734,21 @@ function CoreTopbar({ app }) {
4660
4734
  /* @__PURE__ */ jsx27(Text19, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: user.nome }),
4661
4735
  user.email ? /* @__PURE__ */ jsx27(Text19, { fontSize: "xs", color: "gray.500", children: user.email }) : null
4662
4736
  ] }),
4737
+ settingsHref ? /* @__PURE__ */ jsx27(
4738
+ Button11,
4739
+ {
4740
+ size: "sm",
4741
+ variant: "outline",
4742
+ colorPalette: "brand",
4743
+ borderRadius: "8px",
4744
+ minW: "36px",
4745
+ px: 2,
4746
+ "aria-label": "Abrir configura\xE7\xF5es",
4747
+ title: "Configura\xE7\xF5es",
4748
+ onClick: () => navigate(settingsHref),
4749
+ children: /* @__PURE__ */ jsx27(SettingsIcon, {})
4750
+ }
4751
+ ) : null,
4663
4752
  /* @__PURE__ */ jsx27(
4664
4753
  Button11,
4665
4754
  {
@@ -4689,7 +4778,7 @@ function Slot({
4689
4778
  return Component ? /* @__PURE__ */ jsx27(Component, { app, menu }) : /* @__PURE__ */ jsx27(MissingRenderer, { renderer: slot });
4690
4779
  }
4691
4780
  if (name === "sidebar") return /* @__PURE__ */ jsx27(Sidebar, { app, menu, registry });
4692
- if (name === "topbar") return /* @__PURE__ */ jsx27(CoreTopbar, { app });
4781
+ if (name === "topbar") return /* @__PURE__ */ jsx27(CoreTopbar, { app, menu });
4693
4782
  if (name === "footer" && slot === "core") {
4694
4783
  return /* @__PURE__ */ jsx27(Box18, { as: "footer", px: 6, py: 4, color: "gray.500", fontSize: "xs", borderTopWidth: "1px", children: "OonCore" });
4695
4784
  }
@@ -4757,11 +4846,11 @@ function AuthenticatedLayout({ app, menu, layout, registry }) {
4757
4846
 
4758
4847
  // src/security/AccessDeniedPage.tsx
4759
4848
  import { Box as Box19, Button as Button12, Flex as Flex12, Heading as Heading9, Text as Text20, VStack } from "@chakra-ui/react";
4760
- import { useNavigate } from "react-router-dom";
4849
+ import { useNavigate as useNavigate2 } from "react-router-dom";
4761
4850
  import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
4762
4851
  function AccessDeniedPage({ app }) {
4763
4852
  const { logout } = useOonAuth();
4764
- const navigate = useNavigate();
4853
+ const navigate = useNavigate2();
4765
4854
  function useAnotherAccount() {
4766
4855
  logout();
4767
4856
  navigate("/login", { replace: true });