@oondemand/oon-core-front 0.3.6 → 0.3.8

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
@@ -1800,8 +1800,149 @@ function formatWidget(value, kind, field) {
1800
1800
  return String(value);
1801
1801
  }
1802
1802
 
1803
+ // src/components/ui-v2/CorePage.tsx
1804
+ import { Box as Box10, Heading as Heading7, Stack as Stack6, Text as Text11 } from "@chakra-ui/react";
1805
+
1806
+ // src/security/PermissionGate.tsx
1807
+ import { Fragment, jsx as jsx14 } from "react/jsx-runtime";
1808
+ function PermissionGate({
1809
+ permission,
1810
+ fallback = null,
1811
+ children
1812
+ }) {
1813
+ const { hasPermission } = useOonAuth();
1814
+ return /* @__PURE__ */ jsx14(Fragment, { children: hasPermission(permission) ? children : fallback });
1815
+ }
1816
+
1817
+ // src/app/componentRegistry.tsx
1818
+ import { Box as Box8, Text as Text9 } from "@chakra-ui/react";
1819
+ import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1820
+ var PREFIX_BUCKETS = {
1821
+ "custom": "pageComponents",
1822
+ "fields": "fieldRenderers",
1823
+ "cells": "cellRenderers",
1824
+ "cards": "cardRenderers",
1825
+ "actions": "actionRenderers",
1826
+ "menus": "menuRenderers"
1827
+ };
1828
+ function registryKey(key) {
1829
+ return key.startsWith("custom:") ? key.slice("custom:".length) : key;
1830
+ }
1831
+ function resolveComponent(registry, key, bucket) {
1832
+ if (!key) return null;
1833
+ const normalized = registryKey(key);
1834
+ const inferred = key.includes(".") ? PREFIX_BUCKETS[key.split(".")[0]] : void 0;
1835
+ const targetBucket = bucket ?? inferred ?? "pageComponents";
1836
+ return registry?.[targetBucket]?.[normalized] ?? registry?.[targetBucket]?.[key] ?? null;
1837
+ }
1838
+ function MissingRenderer({ renderer, children }) {
1839
+ if (import.meta.env?.MODE === "production") return /* @__PURE__ */ jsx15(Fragment2, { children: children ?? null });
1840
+ return /* @__PURE__ */ jsxs9(Box8, { borderWidth: "1px", borderStyle: "dashed", borderColor: "orange.300", bg: "orange.50", color: "orange.900", borderRadius: "md", p: 3, children: [
1841
+ /* @__PURE__ */ jsx15(Text9, { fontSize: "sm", fontWeight: "600", children: "Renderer n\xE3o encontrado" }),
1842
+ /* @__PURE__ */ jsxs9(Text9, { fontSize: "xs", children: [
1843
+ "Registre a chave ",
1844
+ renderer ? /* @__PURE__ */ jsx15("code", { children: renderer }) : "solicitada",
1845
+ " no registry da UI."
1846
+ ] }),
1847
+ children
1848
+ ] });
1849
+ }
1850
+
1851
+ // src/components/ui-v2/CorePrimitives.tsx
1852
+ import { Box as Box9, Button as Button6, Flex as Flex6, Heading as Heading6, Spinner as Spinner3, Text as Text10 } from "@chakra-ui/react";
1853
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1854
+ function CorePage({ children }) {
1855
+ return /* @__PURE__ */ jsx16(Box9, { children });
1856
+ }
1857
+ function CorePageHeader({ title, description, actions }) {
1858
+ return /* @__PURE__ */ jsxs10(Flex6, { align: "start", justify: "space-between", gap: 4, mb: 6, children: [
1859
+ /* @__PURE__ */ jsxs10(Box9, { children: [
1860
+ title ? /* @__PURE__ */ jsx16(Heading6, { size: "lg", children: title }) : null,
1861
+ description ? /* @__PURE__ */ jsx16(Text10, { color: "gray.600", mt: 1, children: description }) : null
1862
+ ] }),
1863
+ actions
1864
+ ] });
1865
+ }
1866
+ function CoreToolbar({ children }) {
1867
+ return /* @__PURE__ */ jsx16(Flex6, { align: "center", gap: 2, mb: 4, children });
1868
+ }
1869
+ function CoreDataGrid(props) {
1870
+ return /* @__PURE__ */ jsx16(CoreCollection, { ...props });
1871
+ }
1872
+ function CoreCards(props) {
1873
+ return /* @__PURE__ */ jsx16(CoreCollection, { model: props.model, mode: "minimal", label: props.model });
1874
+ }
1875
+ function CoreForm(props) {
1876
+ return /* @__PURE__ */ jsx16(Box9, { children: props.children });
1877
+ }
1878
+ function CoreField({ label, children }) {
1879
+ return /* @__PURE__ */ jsxs10(Box9, { children: [
1880
+ /* @__PURE__ */ jsx16(Text10, { fontSize: "sm", fontWeight: "600", children: label }),
1881
+ children
1882
+ ] });
1883
+ }
1884
+ function CoreRelationField(props) {
1885
+ return /* @__PURE__ */ jsx16(CoreField, { ...props });
1886
+ }
1887
+ function CoreActions({ children }) {
1888
+ return /* @__PURE__ */ jsx16(Flex6, { gap: 2, children });
1889
+ }
1890
+ function CoreEmptyState({ title = "Nenhum dado encontrado", actionLabel, onAction }) {
1891
+ return /* @__PURE__ */ jsxs10(Box9, { textAlign: "center", py: 10, children: [
1892
+ /* @__PURE__ */ jsx16(Text10, { children: title }),
1893
+ actionLabel ? /* @__PURE__ */ jsx16(Button6, { mt: 3, onClick: onAction, children: actionLabel }) : null
1894
+ ] });
1895
+ }
1896
+ function CoreLoadingState({ label = "Carregando..." }) {
1897
+ return /* @__PURE__ */ jsxs10(Flex6, { align: "center", gap: 3, children: [
1898
+ /* @__PURE__ */ jsx16(Spinner3, { size: "sm" }),
1899
+ /* @__PURE__ */ jsx16(Text10, { children: label })
1900
+ ] });
1901
+ }
1902
+
1903
+ // src/components/ui-v2/CorePage.tsx
1904
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
1905
+ function renderMarkdown(content) {
1906
+ return content.split(/\n{2,}/).map((paragraph, index) => /* @__PURE__ */ jsx17(Text11, { whiteSpace: "pre-wrap", children: paragraph }, index));
1907
+ }
1908
+ function CoreBlock({ block, registry }) {
1909
+ if (block.hidden) return null;
1910
+ const content = (() => {
1911
+ switch (block.type) {
1912
+ case "custom": {
1913
+ const Component = resolveComponent(registry, block.component, "pageComponents");
1914
+ return Component ? /* @__PURE__ */ jsx17(Component, { block, ...block.props }) : /* @__PURE__ */ jsx17(MissingRenderer, { renderer: block.component });
1915
+ }
1916
+ case "collection.datagrid":
1917
+ return /* @__PURE__ */ jsx17(CoreDataGrid, { model: block.model, mode: block.mode, columns: block.columns, form: block.form, label: block.title ?? block.model });
1918
+ case "collection.cards": {
1919
+ const Component = resolveComponent(registry, block.renderer, "cardRenderers");
1920
+ return Component ? /* @__PURE__ */ jsx17(Component, { block, model: block.model }) : /* @__PURE__ */ jsx17(CoreCards, { model: block.model, renderer: block.renderer });
1921
+ }
1922
+ case "section":
1923
+ return /* @__PURE__ */ jsxs11(Box10, { children: [
1924
+ /* @__PURE__ */ jsx17(Heading7, { size: "md", mb: block.description ? 1 : 4, children: block.title }),
1925
+ block.description ? /* @__PURE__ */ jsx17(Text11, { color: "gray.600", mb: 4, children: block.description }) : null,
1926
+ /* @__PURE__ */ jsx17(Stack6, { gap: 4, children: block.blocks?.map((child, index) => /* @__PURE__ */ jsx17(CoreBlock, { block: child, registry }, child.id ?? index)) })
1927
+ ] });
1928
+ case "markdown":
1929
+ return /* @__PURE__ */ jsx17(Stack6, { gap: 2, children: renderMarkdown(block.content) });
1930
+ default:
1931
+ return /* @__PURE__ */ jsx17(MissingRenderer, { renderer: block.type });
1932
+ }
1933
+ })();
1934
+ return /* @__PURE__ */ jsx17(PermissionGate, { permission: block.permissions, children: content });
1935
+ }
1936
+ function CorePage2({ page, registry }) {
1937
+ const Component = resolveComponent(registry, page.component, "pageComponents");
1938
+ return /* @__PURE__ */ jsx17(PermissionGate, { permission: page.permissions, children: Component ? /* @__PURE__ */ jsx17(Component, { page }) : /* @__PURE__ */ jsxs11(CorePage, { children: [
1939
+ /* @__PURE__ */ jsx17(CorePageHeader, { title: page.title ?? page.label }),
1940
+ /* @__PURE__ */ jsx17(Stack6, { gap: 6, children: page.blocks?.map((block, index) => /* @__PURE__ */ jsx17(CoreBlock, { block, registry }, block.id ?? index)) })
1941
+ ] }) });
1942
+ }
1943
+
1803
1944
  // src/app/moduleRegistry.tsx
1804
- import { jsx as jsx14 } from "react/jsx-runtime";
1945
+ import { jsx as jsx18 } from "react/jsx-runtime";
1805
1946
  function slug(value) {
1806
1947
  return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
1807
1948
  }
@@ -1824,7 +1965,7 @@ function renderView(view) {
1824
1965
  switch (view.type) {
1825
1966
  case "collection": {
1826
1967
  const v = view;
1827
- return /* @__PURE__ */ jsx14(
1968
+ return /* @__PURE__ */ jsx18(
1828
1969
  CoreCollection,
1829
1970
  {
1830
1971
  model: v.model,
@@ -1838,11 +1979,11 @@ function renderView(view) {
1838
1979
  }
1839
1980
  case "document": {
1840
1981
  const v = view;
1841
- return /* @__PURE__ */ jsx14(CoreDocument, { model: v.model, label: viewLabel(v), approval: v.approval, attachments: v.attachments });
1982
+ return /* @__PURE__ */ jsx18(CoreDocument, { model: v.model, label: viewLabel(v), approval: v.approval, attachments: v.attachments });
1842
1983
  }
1843
1984
  case "pipeline": {
1844
1985
  const v = view;
1845
- return /* @__PURE__ */ jsx14(
1986
+ return /* @__PURE__ */ jsx18(
1846
1987
  CorePipeline,
1847
1988
  {
1848
1989
  model: v.model,
@@ -1854,7 +1995,7 @@ function renderView(view) {
1854
1995
  }
1855
1996
  case "dashboard": {
1856
1997
  const v = view;
1857
- return /* @__PURE__ */ jsx14(CoreDashboard, { label: viewLabel(v), widgets: v.widgets });
1998
+ return /* @__PURE__ */ jsx18(CoreDashboard, { label: viewLabel(v), widgets: v.widgets });
1858
1999
  }
1859
2000
  default:
1860
2001
  return null;
@@ -1867,6 +2008,13 @@ function viewToRoute(view) {
1867
2008
  permissions: "permissions" in view ? view.permissions : void 0
1868
2009
  };
1869
2010
  }
2011
+ function pageToRoute(page, registry) {
2012
+ return { path: page.path, element: /* @__PURE__ */ jsx18(CorePage2, { page, registry }), permissions: page.permissions };
2013
+ }
2014
+ function pageToMenu(page) {
2015
+ if (page.hidden || !page.label) return null;
2016
+ return { label: page.label, href: page.path, icon: page.icon, section: page.section, permissions: page.permissions, order: page.order };
2017
+ }
1870
2018
  function viewToMenu(view) {
1871
2019
  return {
1872
2020
  label: viewLabel(view),
@@ -1893,9 +2041,22 @@ function resolveRegistry(config) {
1893
2041
  menu.push(viewToMenu(view));
1894
2042
  }
1895
2043
  }
1896
- for (const view of config.ui?.views ?? []) {
1897
- pushRoute(viewToRoute(view));
1898
- menu.push(viewToMenu(view));
2044
+ const navMode = config.ui?.navigation?.mode ?? "auto";
2045
+ const includeAuto = navMode === "auto" || navMode === "mixed";
2046
+ const includeManual = navMode === "manual" || navMode === "mixed";
2047
+ if (includeAuto) {
2048
+ for (const view of config.ui?.views ?? []) {
2049
+ pushRoute(viewToRoute(view));
2050
+ menu.push(viewToMenu(view));
2051
+ }
2052
+ for (const page of config.ui?.pages ?? []) {
2053
+ pushRoute(pageToRoute(page, config.registry ?? config.ui?.registry));
2054
+ const item = pageToMenu(page);
2055
+ if (item) menu.push(item);
2056
+ }
2057
+ }
2058
+ if (includeManual) {
2059
+ for (const item of config.ui?.navigation?.items ?? []) menu.push(item);
1899
2060
  }
1900
2061
  menu.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
1901
2062
  return { routes, menu };
@@ -1907,14 +2068,14 @@ import {
1907
2068
  createBrowserRouter
1908
2069
  } from "react-router-dom";
1909
2070
 
1910
- // src/shell/AuthenticatedLayout.tsx
1911
- import { Box as Box9, Button as Button6, Flex as Flex7, Spacer as Spacer2, Text as Text10 } from "@chakra-ui/react";
2071
+ // src/shell/DefaultShell.tsx
2072
+ import { Box as Box12, Button as Button7, Flex as Flex8, Spacer as Spacer2, Text as Text13 } from "@chakra-ui/react";
1912
2073
  import { Outlet } from "react-router-dom";
1913
2074
 
1914
2075
  // src/shell/Sidebar.tsx
1915
- import { Box as Box8, Flex as Flex6, Image, Stack as Stack6, Text as Text9 } from "@chakra-ui/react";
2076
+ import { Box as Box11, Flex as Flex7, Image, Stack as Stack7, Text as Text12 } from "@chakra-ui/react";
1916
2077
  import { NavLink } from "react-router-dom";
1917
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2078
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1918
2079
  function groupBySection(items) {
1919
2080
  const groups = /* @__PURE__ */ new Map();
1920
2081
  for (const item of items) {
@@ -1924,11 +2085,11 @@ function groupBySection(items) {
1924
2085
  }
1925
2086
  return Array.from(groups.entries());
1926
2087
  }
1927
- function Sidebar({ app, menu }) {
2088
+ function Sidebar({ app, menu, registry }) {
1928
2089
  const { hasPermission } = useOonAuth();
1929
- const visible = menu.filter((item) => hasPermission(item.permissions));
1930
- return /* @__PURE__ */ jsxs9(
1931
- Box8,
2090
+ const visible = menu.filter((item) => !item.hidden && hasPermission(item.permissions));
2091
+ return /* @__PURE__ */ jsxs12(
2092
+ Box11,
1932
2093
  {
1933
2094
  as: "nav",
1934
2095
  w: { base: "76px", lg: "248px" },
@@ -1943,9 +2104,9 @@ function Sidebar({ app, menu }) {
1943
2104
  alignSelf: "flex-start",
1944
2105
  overflowY: "auto",
1945
2106
  children: [
1946
- /* @__PURE__ */ jsxs9(Flex6, { align: "center", gap: 3, mb: 6, px: { base: 1, lg: 2 }, minH: "42px", children: [
1947
- app.logo ? /* @__PURE__ */ jsx15(Image, { src: app.logo, alt: app.name, maxH: "36px", maxW: { base: "44px", lg: "150px" }, objectFit: "contain" }) : /* @__PURE__ */ jsx15(
1948
- Flex6,
2107
+ /* @__PURE__ */ jsxs12(Flex7, { align: "center", gap: 3, mb: 6, px: { base: 1, lg: 2 }, minH: "42px", children: [
2108
+ app.logo ? /* @__PURE__ */ jsx19(Image, { src: app.logo, alt: app.name, maxH: "36px", maxW: { base: "44px", lg: "150px" }, objectFit: "contain" }) : /* @__PURE__ */ jsx19(
2109
+ Flex7,
1949
2110
  {
1950
2111
  w: "38px",
1951
2112
  h: "38px",
@@ -1960,14 +2121,14 @@ function Sidebar({ app, menu }) {
1960
2121
  children: "O"
1961
2122
  }
1962
2123
  ),
1963
- /* @__PURE__ */ jsxs9(Box8, { display: { base: "none", lg: "block" }, minW: 0, children: [
1964
- /* @__PURE__ */ jsx15(Text9, { fontWeight: "700", fontSize: "sm", color: "#07262E", lineClamp: 1, children: app.name }),
1965
- /* @__PURE__ */ jsx15(Text9, { fontSize: "10px", color: "gray.500", textTransform: "uppercase", letterSpacing: "0.08em", children: "Opera\xE7\xE3o digital" })
2124
+ /* @__PURE__ */ jsxs12(Box11, { display: { base: "none", lg: "block" }, minW: 0, children: [
2125
+ /* @__PURE__ */ jsx19(Text12, { fontWeight: "700", fontSize: "sm", color: "#07262E", lineClamp: 1, children: app.name }),
2126
+ /* @__PURE__ */ jsx19(Text12, { fontSize: "10px", color: "gray.500", textTransform: "uppercase", letterSpacing: "0.08em", children: "Opera\xE7\xE3o digital" })
1966
2127
  ] })
1967
2128
  ] }),
1968
- /* @__PURE__ */ jsx15(Stack6, { gap: 5, children: groupBySection(visible).map(([section, items]) => /* @__PURE__ */ jsxs9(Stack6, { gap: 1, children: [
1969
- /* @__PURE__ */ jsx15(
1970
- Text9,
2129
+ /* @__PURE__ */ jsx19(Stack7, { gap: 5, children: groupBySection(visible).map(([section, items]) => /* @__PURE__ */ jsxs12(Stack7, { gap: 1, children: [
2130
+ /* @__PURE__ */ jsx19(
2131
+ Text12,
1971
2132
  {
1972
2133
  display: { base: "none", lg: "block" },
1973
2134
  fontSize: "10px",
@@ -1980,82 +2141,101 @@ function Sidebar({ app, menu }) {
1980
2141
  children: section
1981
2142
  }
1982
2143
  ),
1983
- items.map((item) => /* @__PURE__ */ jsx15(NavLink, { to: item.href, end: item.href === "/", title: item.label, children: ({ isActive }) => /* @__PURE__ */ jsxs9(
1984
- Flex6,
1985
- {
1986
- align: "center",
1987
- justify: { base: "center", lg: "flex-start" },
1988
- gap: 3,
1989
- px: { base: 2, lg: 3 },
1990
- py: "10px",
1991
- borderRadius: "9px",
1992
- fontSize: "13px",
1993
- fontWeight: isActive ? "600" : "500",
1994
- bg: isActive ? "brand.50" : "transparent",
1995
- color: isActive ? "brand.700" : "#46545C",
1996
- borderLeftWidth: "3px",
1997
- borderLeftColor: isActive ? "brand.500" : "transparent",
1998
- transition: "all 0.15s ease",
1999
- _hover: { bg: isActive ? "brand.50" : "#F8F9FA", color: "brand.700" },
2000
- children: [
2001
- item.icon ? /* @__PURE__ */ jsx15(Box8, { flex: "0 0 auto", children: item.icon }) : /* @__PURE__ */ jsx15(Box8, { w: "7px", h: "7px", borderRadius: "full", bg: isActive ? "brand.500" : "gray.300" }),
2002
- /* @__PURE__ */ jsx15(Text9, { display: { base: "none", lg: "block" }, lineClamp: 1, children: item.label })
2003
- ]
2004
- }
2005
- ) }, item.href))
2144
+ items.map((item) => {
2145
+ const CustomMenuItem = resolveComponent(registry, item.renderer, "menuRenderers");
2146
+ if (CustomMenuItem) return /* @__PURE__ */ jsx19(CustomMenuItem, { item }, item.href);
2147
+ return /* @__PURE__ */ jsx19(NavLink, { to: item.href, end: item.href === "/", title: item.label, children: ({ isActive }) => /* @__PURE__ */ jsxs12(
2148
+ Flex7,
2149
+ {
2150
+ align: "center",
2151
+ justify: { base: "center", lg: "flex-start" },
2152
+ gap: 3,
2153
+ px: { base: 2, lg: 3 },
2154
+ py: "10px",
2155
+ borderRadius: "9px",
2156
+ fontSize: "13px",
2157
+ fontWeight: isActive ? "600" : "500",
2158
+ bg: isActive ? "brand.50" : "transparent",
2159
+ color: isActive ? "brand.700" : "#46545C",
2160
+ borderLeftWidth: "3px",
2161
+ borderLeftColor: isActive ? "brand.500" : "transparent",
2162
+ transition: "all 0.15s ease",
2163
+ _hover: { bg: isActive ? "brand.50" : "#F8F9FA", color: "brand.700" },
2164
+ children: [
2165
+ item.icon ? /* @__PURE__ */ jsx19(Box11, { flex: "0 0 auto", children: item.icon }) : /* @__PURE__ */ jsx19(Box11, { w: "7px", h: "7px", borderRadius: "full", bg: isActive ? "brand.500" : "gray.300" }),
2166
+ /* @__PURE__ */ jsx19(Text12, { display: { base: "none", lg: "block" }, lineClamp: 1, children: item.label })
2167
+ ]
2168
+ }
2169
+ ) }, item.href);
2170
+ })
2006
2171
  ] }, section)) })
2007
2172
  ]
2008
2173
  }
2009
2174
  );
2010
2175
  }
2011
2176
 
2012
- // src/shell/AuthenticatedLayout.tsx
2013
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
2014
- function AuthenticatedLayout({ app, menu }) {
2177
+ // src/shell/DefaultShell.tsx
2178
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
2179
+ function CoreTopbar({ app }) {
2015
2180
  const { user, logout } = useOonAuth();
2016
- return /* @__PURE__ */ jsxs10(Flex7, { align: "stretch", minH: "100vh", bg: "#F8F9FA", children: [
2017
- /* @__PURE__ */ jsx16(Sidebar, { app, menu }),
2018
- /* @__PURE__ */ jsxs10(Flex7, { direction: "column", flex: "1", minW: 0, children: [
2019
- /* @__PURE__ */ jsxs10(
2020
- Flex7,
2021
- {
2022
- as: "header",
2023
- align: "center",
2024
- minH: "64px",
2025
- px: { base: 4, lg: 6 },
2026
- py: 3,
2027
- borderBottomWidth: "1px",
2028
- borderColor: "#E8ECEF",
2029
- bg: "rgba(255, 255, 255, 0.96)",
2030
- backdropFilter: "blur(10px)",
2031
- position: "sticky",
2032
- top: 0,
2033
- zIndex: 10,
2034
- children: [
2035
- /* @__PURE__ */ jsxs10(Box9, { children: [
2036
- /* @__PURE__ */ jsx16(Text10, { fontSize: "xs", fontWeight: "600", color: "brand.500", textTransform: "uppercase", letterSpacing: "0.08em", children: "Central Oon" }),
2037
- /* @__PURE__ */ jsx16(Text10, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: app.title ?? app.name })
2038
- ] }),
2039
- /* @__PURE__ */ jsx16(Spacer2, {}),
2040
- user ? /* @__PURE__ */ jsxs10(Flex7, { align: "center", gap: 3, children: [
2041
- /* @__PURE__ */ jsxs10(Box9, { textAlign: "right", display: { base: "none", md: "block" }, children: [
2042
- /* @__PURE__ */ jsx16(Text10, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: user.nome }),
2043
- user.email ? /* @__PURE__ */ jsx16(Text10, { fontSize: "xs", color: "gray.500", children: user.email }) : null
2044
- ] }),
2045
- /* @__PURE__ */ jsx16(Button6, { size: "sm", variant: "outline", colorPalette: "brand", borderRadius: "8px", onClick: logout, children: "Sair" })
2046
- ] }) : null
2047
- ]
2048
- }
2049
- ),
2050
- /* @__PURE__ */ jsx16(Box9, { as: "main", flex: "1", p: { base: 4, lg: 6 }, minW: 0, children: /* @__PURE__ */ jsx16(Box9, { maxW: "1680px", mx: "auto", children: /* @__PURE__ */ jsx16(Outlet, {}) }) })
2181
+ return /* @__PURE__ */ jsxs13(Flex8, { as: "header", align: "center", minH: "64px", px: { base: 4, lg: 6 }, py: 3, borderBottomWidth: "1px", borderColor: "#E8ECEF", bg: "rgba(255, 255, 255, 0.96)", backdropFilter: "blur(10px)", position: "sticky", top: 0, zIndex: 10, children: [
2182
+ /* @__PURE__ */ jsxs13(Box12, { children: [
2183
+ /* @__PURE__ */ jsx20(Text13, { fontSize: "xs", fontWeight: "600", color: "brand.500", textTransform: "uppercase", letterSpacing: "0.08em", children: "Central Oon" }),
2184
+ /* @__PURE__ */ jsx20(Text13, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: app.title ?? app.name })
2185
+ ] }),
2186
+ /* @__PURE__ */ jsx20(Spacer2, {}),
2187
+ user ? /* @__PURE__ */ jsxs13(Flex8, { align: "center", gap: 3, children: [
2188
+ /* @__PURE__ */ jsxs13(Box12, { textAlign: "right", display: { base: "none", md: "block" }, children: [
2189
+ /* @__PURE__ */ jsx20(Text13, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: user.nome }),
2190
+ user.email ? /* @__PURE__ */ jsx20(Text13, { fontSize: "xs", color: "gray.500", children: user.email }) : null
2191
+ ] }),
2192
+ /* @__PURE__ */ jsx20(Button7, { size: "sm", variant: "outline", colorPalette: "brand", borderRadius: "8px", onClick: logout, children: "Sair" })
2193
+ ] }) : null
2194
+ ] });
2195
+ }
2196
+ function Slot({ name, slot, registry, app, menu }) {
2197
+ if (slot === "none") return null;
2198
+ if (slot?.startsWith("custom:")) {
2199
+ const C = resolveComponent(registry, slot, "layoutSlots");
2200
+ return C ? /* @__PURE__ */ jsx20(C, { app, menu }) : /* @__PURE__ */ jsx20(MissingRenderer, { renderer: slot });
2201
+ }
2202
+ if (name === "sidebar") return /* @__PURE__ */ jsx20(Sidebar, { app, menu, registry });
2203
+ if (name === "topbar") return /* @__PURE__ */ jsx20(CoreTopbar, { app });
2204
+ if (name === "footer" && slot === "core") return /* @__PURE__ */ jsx20(Box12, { as: "footer", px: 6, py: 4, color: "gray.500", fontSize: "xs", borderTopWidth: "1px", children: "OonCore" });
2205
+ return null;
2206
+ }
2207
+ function DefaultShell({ app, menu, layout, registry }) {
2208
+ const portal = layout?.shell === "portal" || layout?.shell === "content-only";
2209
+ const mainPadding = portal ? { base: 4, lg: 10 } : { base: 4, lg: 6 };
2210
+ return /* @__PURE__ */ jsxs13(Flex8, { align: "stretch", minH: "100vh", bg: portal ? "white" : "#F8F9FA", children: [
2211
+ /* @__PURE__ */ jsx20(Slot, { name: "sidebar", slot: layout?.sidebar ?? "core", registry, app, menu }),
2212
+ /* @__PURE__ */ jsxs13(Flex8, { direction: "column", flex: "1", minW: 0, children: [
2213
+ /* @__PURE__ */ jsx20(Slot, { name: "topbar", slot: layout?.topbar ?? "core", registry, app, menu }),
2214
+ /* @__PURE__ */ jsx20(Slot, { name: "header", slot: layout?.header, registry, app, menu }),
2215
+ /* @__PURE__ */ jsx20(Box12, { as: "main", flex: "1", p: mainPadding, minW: 0, children: /* @__PURE__ */ jsx20(Box12, { maxW: portal ? "1180px" : "1680px", mx: "auto", children: /* @__PURE__ */ jsx20(Outlet, {}) }) }),
2216
+ /* @__PURE__ */ jsx20(Slot, { name: "footer", slot: layout?.footer ?? "none", registry, app, menu })
2051
2217
  ] })
2052
2218
  ] });
2053
2219
  }
2220
+ function PortalShell(props) {
2221
+ return /* @__PURE__ */ jsx20(DefaultShell, { ...props, layout: { ...props.layout, shell: "portal" } });
2222
+ }
2223
+
2224
+ // src/shell/AuthenticatedLayout.tsx
2225
+ import { jsx as jsx21 } from "react/jsx-runtime";
2226
+ function AuthenticatedLayout({ app, menu, layout, registry }) {
2227
+ if (layout?.shell?.startsWith("custom:")) {
2228
+ const CustomShell = resolveComponent(registry, layout.shell, "layoutSlots");
2229
+ return CustomShell ? /* @__PURE__ */ jsx21(CustomShell, { app, menu, layout }) : /* @__PURE__ */ jsx21(MissingRenderer, { renderer: layout.shell });
2230
+ }
2231
+ if (layout?.shell === "portal") return /* @__PURE__ */ jsx21(PortalShell, { app, menu, layout, registry });
2232
+ return /* @__PURE__ */ jsx21(DefaultShell, { app, menu, layout, registry });
2233
+ }
2054
2234
 
2055
2235
  // src/security/AccessDeniedPage.tsx
2056
- import { Box as Box10, Button as Button7, Flex as Flex8, Heading as Heading6, Text as Text11, VStack } from "@chakra-ui/react";
2236
+ import { Box as Box13, Button as Button8, Flex as Flex9, Heading as Heading8, Text as Text14, VStack } from "@chakra-ui/react";
2057
2237
  import { useNavigate } from "react-router-dom";
2058
- import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
2238
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
2059
2239
  function AccessDeniedPage({ app }) {
2060
2240
  const { logout } = useOonAuth();
2061
2241
  const navigate = useNavigate();
@@ -2063,8 +2243,8 @@ function AccessDeniedPage({ app }) {
2063
2243
  logout();
2064
2244
  navigate("/login", { replace: true });
2065
2245
  }
2066
- return /* @__PURE__ */ jsx17(Flex8, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx17(
2067
- Box10,
2246
+ return /* @__PURE__ */ jsx22(Flex9, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx22(
2247
+ Box13,
2068
2248
  {
2069
2249
  width: "100%",
2070
2250
  maxW: "560px",
@@ -2074,9 +2254,9 @@ function AccessDeniedPage({ app }) {
2074
2254
  borderRadius: "18px",
2075
2255
  boxShadow: "0 24px 70px rgba(7, 38, 46, 0.10)",
2076
2256
  p: { base: 6, md: 10 },
2077
- children: /* @__PURE__ */ jsxs11(VStack, { align: "stretch", gap: 6, children: [
2078
- /* @__PURE__ */ jsx17(
2079
- Box10,
2257
+ children: /* @__PURE__ */ jsxs14(VStack, { align: "stretch", gap: 6, children: [
2258
+ /* @__PURE__ */ jsx22(
2259
+ Box13,
2080
2260
  {
2081
2261
  width: "56px",
2082
2262
  height: "56px",
@@ -2092,9 +2272,9 @@ function AccessDeniedPage({ app }) {
2092
2272
  children: "!"
2093
2273
  }
2094
2274
  ),
2095
- /* @__PURE__ */ jsxs11(Box10, { children: [
2096
- /* @__PURE__ */ jsx17(
2097
- Text11,
2275
+ /* @__PURE__ */ jsxs14(Box13, { children: [
2276
+ /* @__PURE__ */ jsx22(
2277
+ Text14,
2098
2278
  {
2099
2279
  color: "#39BFED",
2100
2280
  fontSize: "xs",
@@ -2104,15 +2284,15 @@ function AccessDeniedPage({ app }) {
2104
2284
  children: "Acesso negado"
2105
2285
  }
2106
2286
  ),
2107
- /* @__PURE__ */ jsx17(Heading6, { mt: 2, size: "lg", color: "#07262E", children: "Voc\xEA n\xE3o possui permiss\xE3o para este aplicativo" }),
2108
- /* @__PURE__ */ jsxs11(Text11, { mt: 3, color: "gray.600", children: [
2287
+ /* @__PURE__ */ jsx22(Heading8, { mt: 2, size: "lg", color: "#07262E", children: "Voc\xEA n\xE3o possui permiss\xE3o para este aplicativo" }),
2288
+ /* @__PURE__ */ jsxs14(Text14, { mt: 3, color: "gray.600", children: [
2109
2289
  "Seu usu\xE1rio foi autenticado, mas n\xE3o existe uma permiss\xE3o ativa para acessar ",
2110
2290
  app.title ?? app.name,
2111
2291
  ". Solicite o acesso ao administrador da sua organiza\xE7\xE3o."
2112
2292
  ] })
2113
2293
  ] }),
2114
- /* @__PURE__ */ jsx17(
2115
- Button7,
2294
+ /* @__PURE__ */ jsx22(
2295
+ Button8,
2116
2296
  {
2117
2297
  alignSelf: "flex-start",
2118
2298
  bg: "#07262E",
@@ -2129,7 +2309,7 @@ function AccessDeniedPage({ app }) {
2129
2309
 
2130
2310
  // src/security/AppAccessGuard.tsx
2131
2311
  import { Navigate, useLocation } from "react-router-dom";
2132
- import { Fragment, jsx as jsx18 } from "react/jsx-runtime";
2312
+ import { Fragment as Fragment3, jsx as jsx23 } from "react/jsx-runtime";
2133
2313
  function loginRedirect(pathname, search) {
2134
2314
  const destination = `${pathname}${search}`;
2135
2315
  return `/login?redirect=${encodeURIComponent(destination)}`;
@@ -2137,9 +2317,9 @@ function loginRedirect(pathname, search) {
2137
2317
  function AppAccessGuard({ children }) {
2138
2318
  const { status, retry } = useOonAuth();
2139
2319
  const location = useLocation();
2140
- if (status === "loading") return /* @__PURE__ */ jsx18(LoadingScreen, {});
2320
+ if (status === "loading") return /* @__PURE__ */ jsx23(LoadingScreen, {});
2141
2321
  if (status === "unauthenticated") {
2142
- return /* @__PURE__ */ jsx18(
2322
+ return /* @__PURE__ */ jsx23(
2143
2323
  Navigate,
2144
2324
  {
2145
2325
  to: loginRedirect(location.pathname, location.search),
@@ -2148,10 +2328,10 @@ function AppAccessGuard({ children }) {
2148
2328
  );
2149
2329
  }
2150
2330
  if (status === "forbidden") {
2151
- return /* @__PURE__ */ jsx18(Navigate, { to: "/acesso-negado", replace: true });
2331
+ return /* @__PURE__ */ jsx23(Navigate, { to: "/acesso-negado", replace: true });
2152
2332
  }
2153
2333
  if (status === "error") {
2154
- return /* @__PURE__ */ jsx18(
2334
+ return /* @__PURE__ */ jsx23(
2155
2335
  LoadingScreen,
2156
2336
  {
2157
2337
  message: "N\xE3o foi poss\xEDvel validar seu acesso. Tente novamente.",
@@ -2162,22 +2342,22 @@ function AppAccessGuard({ children }) {
2162
2342
  }
2163
2343
  );
2164
2344
  }
2165
- return /* @__PURE__ */ jsx18(Fragment, { children });
2345
+ return /* @__PURE__ */ jsx23(Fragment3, { children });
2166
2346
  }
2167
2347
 
2168
2348
  // src/security/LoginPage.tsx
2169
2349
  import { useState as useState8 } from "react";
2170
2350
  import {
2171
- Box as Box11,
2172
- Button as Button8,
2173
- Flex as Flex9,
2174
- Heading as Heading7,
2351
+ Box as Box14,
2352
+ Button as Button9,
2353
+ Flex as Flex10,
2354
+ Heading as Heading9,
2175
2355
  Input as Input4,
2176
- Text as Text12,
2356
+ Text as Text15,
2177
2357
  VStack as VStack2
2178
2358
  } from "@chakra-ui/react";
2179
2359
  import { Navigate as Navigate2, useLocation as useLocation2 } from "react-router-dom";
2180
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2360
+ import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
2181
2361
  function safeRedirect(search) {
2182
2362
  const value = new URLSearchParams(search).get("redirect") || "/";
2183
2363
  if (!value.startsWith("/") || value.startsWith("//")) return "/";
@@ -2195,10 +2375,10 @@ function LoginPage({ app }) {
2195
2375
  const [message, setMessage] = useState8(null);
2196
2376
  const redirect = safeRedirect(location.search);
2197
2377
  if (status === "authenticated") {
2198
- return /* @__PURE__ */ jsx19(Navigate2, { to: redirect, replace: true });
2378
+ return /* @__PURE__ */ jsx24(Navigate2, { to: redirect, replace: true });
2199
2379
  }
2200
2380
  if (status === "forbidden") {
2201
- return /* @__PURE__ */ jsx19(Navigate2, { to: "/acesso-negado", replace: true });
2381
+ return /* @__PURE__ */ jsx24(Navigate2, { to: "/acesso-negado", replace: true });
2202
2382
  }
2203
2383
  async function handleSubmit(event) {
2204
2384
  event.preventDefault();
@@ -2216,8 +2396,8 @@ function LoginPage({ app }) {
2216
2396
  setSubmitting(false);
2217
2397
  }
2218
2398
  }
2219
- return /* @__PURE__ */ jsx19(Flex9, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx19(
2220
- Box11,
2399
+ return /* @__PURE__ */ jsx24(Flex10, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx24(
2400
+ Box14,
2221
2401
  {
2222
2402
  width: "100%",
2223
2403
  maxW: "440px",
@@ -2227,10 +2407,10 @@ function LoginPage({ app }) {
2227
2407
  borderRadius: "18px",
2228
2408
  boxShadow: "0 24px 70px rgba(7, 38, 46, 0.10)",
2229
2409
  p: { base: 6, md: 9 },
2230
- children: /* @__PURE__ */ jsx19("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs12(VStack2, { align: "stretch", gap: 6, children: [
2231
- /* @__PURE__ */ jsxs12(Box11, { children: [
2232
- /* @__PURE__ */ jsx19(
2233
- Text12,
2410
+ children: /* @__PURE__ */ jsx24("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs15(VStack2, { align: "stretch", gap: 6, children: [
2411
+ /* @__PURE__ */ jsxs15(Box14, { children: [
2412
+ /* @__PURE__ */ jsx24(
2413
+ Text15,
2234
2414
  {
2235
2415
  color: "#39BFED",
2236
2416
  fontSize: "xs",
@@ -2240,13 +2420,13 @@ function LoginPage({ app }) {
2240
2420
  children: "Central Oon"
2241
2421
  }
2242
2422
  ),
2243
- /* @__PURE__ */ jsx19(Heading7, { mt: 2, size: "lg", color: "#07262E", children: app.title ?? app.name }),
2244
- /* @__PURE__ */ jsx19(Text12, { mt: 2, color: "gray.600", fontSize: "sm", children: "Entre com seu usu\xE1rio autorizado para acessar este aplicativo." })
2423
+ /* @__PURE__ */ jsx24(Heading9, { mt: 2, size: "lg", color: "#07262E", children: app.title ?? app.name }),
2424
+ /* @__PURE__ */ jsx24(Text15, { mt: 2, color: "gray.600", fontSize: "sm", children: "Entre com seu usu\xE1rio autorizado para acessar este aplicativo." })
2245
2425
  ] }),
2246
- /* @__PURE__ */ jsxs12(VStack2, { align: "stretch", gap: 4, children: [
2247
- /* @__PURE__ */ jsxs12(Box11, { children: [
2248
- /* @__PURE__ */ jsx19(Text12, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "E-mail" }),
2249
- /* @__PURE__ */ jsx19(
2426
+ /* @__PURE__ */ jsxs15(VStack2, { align: "stretch", gap: 4, children: [
2427
+ /* @__PURE__ */ jsxs15(Box14, { children: [
2428
+ /* @__PURE__ */ jsx24(Text15, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "E-mail" }),
2429
+ /* @__PURE__ */ jsx24(
2250
2430
  Input4,
2251
2431
  {
2252
2432
  type: "email",
@@ -2258,9 +2438,9 @@ function LoginPage({ app }) {
2258
2438
  }
2259
2439
  )
2260
2440
  ] }),
2261
- /* @__PURE__ */ jsxs12(Box11, { children: [
2262
- /* @__PURE__ */ jsx19(Text12, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Senha" }),
2263
- /* @__PURE__ */ jsx19(
2441
+ /* @__PURE__ */ jsxs15(Box14, { children: [
2442
+ /* @__PURE__ */ jsx24(Text15, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Senha" }),
2443
+ /* @__PURE__ */ jsx24(
2264
2444
  Input4,
2265
2445
  {
2266
2446
  type: "password",
@@ -2273,8 +2453,8 @@ function LoginPage({ app }) {
2273
2453
  )
2274
2454
  ] })
2275
2455
  ] }),
2276
- message ? /* @__PURE__ */ jsx19(
2277
- Box11,
2456
+ message ? /* @__PURE__ */ jsx24(
2457
+ Box14,
2278
2458
  {
2279
2459
  role: "alert",
2280
2460
  borderRadius: "10px",
@@ -2286,8 +2466,8 @@ function LoginPage({ app }) {
2286
2466
  children: message
2287
2467
  }
2288
2468
  ) : null,
2289
- /* @__PURE__ */ jsx19(
2290
- Button8,
2469
+ /* @__PURE__ */ jsx24(
2470
+ Button9,
2291
2471
  {
2292
2472
  type: "submit",
2293
2473
  bg: "#07262E",
@@ -2304,8 +2484,8 @@ function LoginPage({ app }) {
2304
2484
 
2305
2485
  // src/security/ActivationPage.tsx
2306
2486
  import { useEffect as useEffect5, useState as useState9 } from "react";
2307
- import { Box as Box12, Button as Button9, Heading as Heading8, Input as Input5, Text as Text13, VStack as VStack3 } from "@chakra-ui/react";
2308
- import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
2487
+ import { Box as Box15, Button as Button10, Heading as Heading10, Input as Input5, Text as Text16, VStack as VStack3 } from "@chakra-ui/react";
2488
+ import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
2309
2489
  function encodeBasicCredentials2(email, password) {
2310
2490
  const bytes = new TextEncoder().encode(`${email}:${password}`);
2311
2491
  let binary = "";
@@ -2439,12 +2619,12 @@ function ActivationPage() {
2439
2619
  }
2440
2620
  }
2441
2621
  function renderField(field, values, setValues) {
2442
- return /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2443
- /* @__PURE__ */ jsxs13(Text13, { fontWeight: "medium", children: [
2622
+ return /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2623
+ /* @__PURE__ */ jsxs16(Text16, { fontWeight: "medium", children: [
2444
2624
  field.label,
2445
2625
  field.required ? " *" : ""
2446
2626
  ] }),
2447
- /* @__PURE__ */ jsx20(
2627
+ /* @__PURE__ */ jsx25(
2448
2628
  Input5,
2449
2629
  {
2450
2630
  type: field.type === "password" || field.type === "secret" ? "password" : field.type === "email" ? "email" : field.type === "url" ? "url" : field.type === "number" || field.type === "integer" ? "number" : "text",
@@ -2456,15 +2636,15 @@ function ActivationPage() {
2456
2636
  onChange: (event) => setValues({ ...values, [field.name]: event.target.value })
2457
2637
  }
2458
2638
  ),
2459
- field.helpText ? /* @__PURE__ */ jsx20(Text13, { fontSize: "sm", color: "gray.500", children: field.helpText }) : null
2639
+ field.helpText ? /* @__PURE__ */ jsx25(Text16, { fontSize: "sm", color: "gray.500", children: field.helpText }) : null
2460
2640
  ] }, field.name);
2461
2641
  }
2462
2642
  function renderDevLocalActivation() {
2463
- return /* @__PURE__ */ jsxs13(Fragment2, { children: [
2464
- /* @__PURE__ */ jsx20(Text13, { color: "gray.700", children: "Entre com seu e-mail e senha para ativar esta Central em ambiente de desenvolvimento. Se o e-mail ainda n\xE3o existir na Central de Ativa\xE7\xF5es, o usu\xE1rio ser\xE1 criado automaticamente com perfil de desenvolvedor." }),
2465
- /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2466
- /* @__PURE__ */ jsx20(Text13, { fontWeight: "medium", children: "Nome do usu\xE1rio" }),
2467
- /* @__PURE__ */ jsx20(
2643
+ return /* @__PURE__ */ jsxs16(Fragment4, { children: [
2644
+ /* @__PURE__ */ jsx25(Text16, { color: "gray.700", children: "Entre com seu e-mail e senha para ativar esta Central em ambiente de desenvolvimento. Se o e-mail ainda n\xE3o existir na Central de Ativa\xE7\xF5es, o usu\xE1rio ser\xE1 criado automaticamente com perfil de desenvolvedor." }),
2645
+ /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2646
+ /* @__PURE__ */ jsx25(Text16, { fontWeight: "medium", children: "Nome do usu\xE1rio" }),
2647
+ /* @__PURE__ */ jsx25(
2468
2648
  Input5,
2469
2649
  {
2470
2650
  value: devName,
@@ -2474,9 +2654,9 @@ function ActivationPage() {
2474
2654
  }
2475
2655
  )
2476
2656
  ] }),
2477
- /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2478
- /* @__PURE__ */ jsx20(Text13, { fontWeight: "medium", children: "E-mail *" }),
2479
- /* @__PURE__ */ jsx20(
2657
+ /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2658
+ /* @__PURE__ */ jsx25(Text16, { fontWeight: "medium", children: "E-mail *" }),
2659
+ /* @__PURE__ */ jsx25(
2480
2660
  Input5,
2481
2661
  {
2482
2662
  type: "email",
@@ -2487,9 +2667,9 @@ function ActivationPage() {
2487
2667
  }
2488
2668
  )
2489
2669
  ] }),
2490
- /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2491
- /* @__PURE__ */ jsx20(Text13, { fontWeight: "medium", children: "Senha *" }),
2492
- /* @__PURE__ */ jsx20(
2670
+ /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2671
+ /* @__PURE__ */ jsx25(Text16, { fontWeight: "medium", children: "Senha *" }),
2672
+ /* @__PURE__ */ jsx25(
2493
2673
  Input5,
2494
2674
  {
2495
2675
  type: "password",
@@ -2501,8 +2681,8 @@ function ActivationPage() {
2501
2681
  }
2502
2682
  )
2503
2683
  ] }),
2504
- /* @__PURE__ */ jsx20(
2505
- Button9,
2684
+ /* @__PURE__ */ jsx25(
2685
+ Button10,
2506
2686
  {
2507
2687
  colorPalette: "blue",
2508
2688
  onClick: activateDevLocal,
@@ -2511,8 +2691,8 @@ function ActivationPage() {
2511
2691
  children: "Ativar ambiente de desenvolvimento"
2512
2692
  }
2513
2693
  ),
2514
- /* @__PURE__ */ jsx20(
2515
- Button9,
2694
+ /* @__PURE__ */ jsx25(
2695
+ Button10,
2516
2696
  {
2517
2697
  variant: "outline",
2518
2698
  onClick: () => setShowCodeFlow(true),
@@ -2525,7 +2705,7 @@ function ActivationPage() {
2525
2705
  const rootMode = config?.mode === "root-bootstrap" || activation.details?.role === "root";
2526
2706
  const isDevelopmentMember = !rootMode && config?.technical?.ambiente === "desenvolvimento";
2527
2707
  if (activation.status === "loading" || !config) {
2528
- return /* @__PURE__ */ jsx20(Box12, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs13(
2708
+ return /* @__PURE__ */ jsx25(Box15, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs16(
2529
2709
  VStack3,
2530
2710
  {
2531
2711
  maxW: "760px",
@@ -2536,14 +2716,14 @@ function ActivationPage() {
2536
2716
  align: "stretch",
2537
2717
  gap: 5,
2538
2718
  children: [
2539
- /* @__PURE__ */ jsx20(Heading8, { children: "Preparando ativa\xE7\xE3o..." }),
2540
- error ? /* @__PURE__ */ jsx20(Text13, { color: "red.600", children: error }) : null
2719
+ /* @__PURE__ */ jsx25(Heading10, { children: "Preparando ativa\xE7\xE3o..." }),
2720
+ error ? /* @__PURE__ */ jsx25(Text16, { color: "red.600", children: error }) : null
2541
2721
  ]
2542
2722
  }
2543
2723
  ) });
2544
2724
  }
2545
2725
  if (rootMode) {
2546
- return /* @__PURE__ */ jsx20(Box12, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs13(
2726
+ return /* @__PURE__ */ jsx25(Box15, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs16(
2547
2727
  VStack3,
2548
2728
  {
2549
2729
  maxW: "560px",
@@ -2554,20 +2734,20 @@ function ActivationPage() {
2554
2734
  align: "stretch",
2555
2735
  gap: 5,
2556
2736
  children: [
2557
- /* @__PURE__ */ jsx20(Heading8, { children: "Ativa\xE7\xE3o inicial do Ecossistema Oon" }),
2558
- /* @__PURE__ */ jsx20(Text13, { color: "gray.600", children: "Esta \xE9 a aplica\xE7\xE3o root do ecossistema. Informe somente o e-mail e a senha do primeiro administrador. O Core criar\xE1 a estrutura m\xEDnima necess\xE1ria para liberar o primeiro login." }),
2559
- /* @__PURE__ */ jsxs13(Text13, { fontSize: "sm", color: "gray.500", children: [
2737
+ /* @__PURE__ */ jsx25(Heading10, { children: "Ativa\xE7\xE3o inicial do Ecossistema Oon" }),
2738
+ /* @__PURE__ */ jsx25(Text16, { color: "gray.600", children: "Esta \xE9 a aplica\xE7\xE3o root do ecossistema. Informe somente o e-mail e a senha do primeiro administrador. O Core criar\xE1 a estrutura m\xEDnima necess\xE1ria para liberar o primeiro login." }),
2739
+ /* @__PURE__ */ jsxs16(Text16, { fontSize: "sm", color: "gray.500", children: [
2560
2740
  "App: ",
2561
2741
  config.technical.appCode,
2562
2742
  " \xB7 Ambiente:",
2563
2743
  " ",
2564
2744
  config.technical.ambiente
2565
2745
  ] }),
2566
- error ? /* @__PURE__ */ jsx20(Text13, { color: "red.600", children: error }) : null,
2567
- step !== 6 ? /* @__PURE__ */ jsxs13(Fragment2, { children: [
2568
- /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2569
- /* @__PURE__ */ jsx20(Text13, { fontWeight: "medium", children: "E-mail do administrador *" }),
2570
- /* @__PURE__ */ jsx20(
2746
+ error ? /* @__PURE__ */ jsx25(Text16, { color: "red.600", children: error }) : null,
2747
+ step !== 6 ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
2748
+ /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2749
+ /* @__PURE__ */ jsx25(Text16, { fontWeight: "medium", children: "E-mail do administrador *" }),
2750
+ /* @__PURE__ */ jsx25(
2571
2751
  Input5,
2572
2752
  {
2573
2753
  type: "email",
@@ -2578,9 +2758,9 @@ function ActivationPage() {
2578
2758
  }
2579
2759
  )
2580
2760
  ] }),
2581
- /* @__PURE__ */ jsxs13(Box12, { w: "100%", children: [
2582
- /* @__PURE__ */ jsx20(Text13, { fontWeight: "medium", children: "Senha *" }),
2583
- /* @__PURE__ */ jsx20(
2761
+ /* @__PURE__ */ jsxs16(Box15, { w: "100%", children: [
2762
+ /* @__PURE__ */ jsx25(Text16, { fontWeight: "medium", children: "Senha *" }),
2763
+ /* @__PURE__ */ jsx25(
2584
2764
  Input5,
2585
2765
  {
2586
2766
  type: "password",
@@ -2592,8 +2772,8 @@ function ActivationPage() {
2592
2772
  }
2593
2773
  )
2594
2774
  ] }),
2595
- /* @__PURE__ */ jsx20(
2596
- Button9,
2775
+ /* @__PURE__ */ jsx25(
2776
+ Button10,
2597
2777
  {
2598
2778
  colorPalette: "blue",
2599
2779
  onClick: activateRoot,
@@ -2602,15 +2782,15 @@ function ActivationPage() {
2602
2782
  children: "Criar ecossistema e ativar"
2603
2783
  }
2604
2784
  )
2605
- ] }) : /* @__PURE__ */ jsxs13(Fragment2, { children: [
2606
- /* @__PURE__ */ jsx20(Heading8, { size: "md", children: "Ativa\xE7\xE3o conclu\xEDda" }),
2607
- /* @__PURE__ */ jsx20(Text13, { children: "Usu\xE1rio, tenant, aplicativo, licen\xE7a e permiss\xF5es foram preparados. Redirecionando para o primeiro login..." })
2785
+ ] }) : /* @__PURE__ */ jsxs16(Fragment4, { children: [
2786
+ /* @__PURE__ */ jsx25(Heading10, { size: "md", children: "Ativa\xE7\xE3o conclu\xEDda" }),
2787
+ /* @__PURE__ */ jsx25(Text16, { children: "Usu\xE1rio, tenant, aplicativo, licen\xE7a e permiss\xF5es foram preparados. Redirecionando para o primeiro login..." })
2608
2788
  ] })
2609
2789
  ]
2610
2790
  }
2611
2791
  ) });
2612
2792
  }
2613
- return /* @__PURE__ */ jsx20(Box12, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs13(
2793
+ return /* @__PURE__ */ jsx25(Box15, { minH: "100vh", bg: "gray.50", p: 8, children: /* @__PURE__ */ jsxs16(
2614
2794
  VStack3,
2615
2795
  {
2616
2796
  maxW: "760px",
@@ -2621,8 +2801,8 @@ function ActivationPage() {
2621
2801
  align: "stretch",
2622
2802
  gap: 5,
2623
2803
  children: [
2624
- /* @__PURE__ */ jsx20(Heading8, { children: "Ativa\xE7\xE3o da Central Oon" }),
2625
- /* @__PURE__ */ jsxs13(Text13, { children: [
2804
+ /* @__PURE__ */ jsx25(Heading10, { children: "Ativa\xE7\xE3o da Central Oon" }),
2805
+ /* @__PURE__ */ jsxs16(Text16, { children: [
2626
2806
  "App: ",
2627
2807
  config.technical.appCode,
2628
2808
  " \xB7 Ambiente:",
@@ -2632,11 +2812,11 @@ function ActivationPage() {
2632
2812
  " ",
2633
2813
  config.technical.centralAtivacaoUrl || config.technical.centralAtivacaoHost
2634
2814
  ] }),
2635
- error ? /* @__PURE__ */ jsx20(Text13, { color: "red.600", children: error }) : null,
2815
+ error ? /* @__PURE__ */ jsx25(Text16, { color: "red.600", children: error }) : null,
2636
2816
  step === 1 && isDevelopmentMember && !showCodeFlow ? renderDevLocalActivation() : null,
2637
- step === 1 && (!isDevelopmentMember || showCodeFlow) && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2638
- /* @__PURE__ */ jsx20(Text13, { children: "Informe o c\xF3digo de ativa\xE7\xE3o para validar tenant, aplicativo e licen\xE7a antes de consumir o c\xF3digo." }),
2639
- /* @__PURE__ */ jsx20(
2817
+ step === 1 && (!isDevelopmentMember || showCodeFlow) && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2818
+ /* @__PURE__ */ jsx25(Text16, { children: "Informe o c\xF3digo de ativa\xE7\xE3o para validar tenant, aplicativo e licen\xE7a antes de consumir o c\xF3digo." }),
2819
+ /* @__PURE__ */ jsx25(
2640
2820
  Input5,
2641
2821
  {
2642
2822
  "aria-label": "C\xF3digo de ativa\xE7\xE3o",
@@ -2645,8 +2825,8 @@ function ActivationPage() {
2645
2825
  placeholder: "OON-XXXX"
2646
2826
  }
2647
2827
  ),
2648
- /* @__PURE__ */ jsx20(
2649
- Button9,
2828
+ /* @__PURE__ */ jsx25(
2829
+ Button10,
2650
2830
  {
2651
2831
  onClick: validateCode,
2652
2832
  loading: submitting,
@@ -2654,8 +2834,8 @@ function ActivationPage() {
2654
2834
  children: "Validar c\xF3digo"
2655
2835
  }
2656
2836
  ),
2657
- isDevelopmentMember ? /* @__PURE__ */ jsx20(
2658
- Button9,
2837
+ isDevelopmentMember ? /* @__PURE__ */ jsx25(
2838
+ Button10,
2659
2839
  {
2660
2840
  variant: "outline",
2661
2841
  onClick: () => setShowCodeFlow(false),
@@ -2664,25 +2844,25 @@ function ActivationPage() {
2664
2844
  }
2665
2845
  ) : null
2666
2846
  ] }),
2667
- step === 2 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2668
- /* @__PURE__ */ jsx20(Heading8, { size: "md", children: "Confirma\xE7\xE3o" }),
2669
- /* @__PURE__ */ jsx20("pre", { children: JSON.stringify(preview, null, 2) }),
2670
- /* @__PURE__ */ jsx20(Button9, { onClick: () => setStep(3), children: "Continuar" })
2847
+ step === 2 && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2848
+ /* @__PURE__ */ jsx25(Heading10, { size: "md", children: "Confirma\xE7\xE3o" }),
2849
+ /* @__PURE__ */ jsx25("pre", { children: JSON.stringify(preview, null, 2) }),
2850
+ /* @__PURE__ */ jsx25(Button10, { onClick: () => setStep(3), children: "Continuar" })
2671
2851
  ] }),
2672
- step === 3 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2852
+ step === 3 && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2673
2853
  config.globalFields.map(
2674
2854
  (field) => renderField(field, global, setGlobal)
2675
2855
  ),
2676
- /* @__PURE__ */ jsx20(Button9, { onClick: () => setStep(4), children: "Continuar" })
2856
+ /* @__PURE__ */ jsx25(Button10, { onClick: () => setStep(4), children: "Continuar" })
2677
2857
  ] }),
2678
- step === 4 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2679
- config.appFields.length ? config.appFields.map((field) => renderField(field, app, setApp)) : /* @__PURE__ */ jsx20(Text13, { children: "Nenhum par\xE2metro adicional declarado." }),
2680
- /* @__PURE__ */ jsx20(Button9, { onClick: () => setStep(5), children: "Revisar" })
2858
+ step === 4 && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2859
+ config.appFields.length ? config.appFields.map((field) => renderField(field, app, setApp)) : /* @__PURE__ */ jsx25(Text16, { children: "Nenhum par\xE2metro adicional declarado." }),
2860
+ /* @__PURE__ */ jsx25(Button10, { onClick: () => setStep(5), children: "Revisar" })
2681
2861
  ] }),
2682
- step === 5 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2683
- /* @__PURE__ */ jsx20(Text13, { children: "Ao confirmar, o c\xF3digo ser\xE1 consumido e a inst\xE2ncia ser\xE1 registrada no Ecossistema Oon." }),
2684
- /* @__PURE__ */ jsx20(
2685
- Button9,
2862
+ step === 5 && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2863
+ /* @__PURE__ */ jsx25(Text16, { children: "Ao confirmar, o c\xF3digo ser\xE1 consumido e a inst\xE2ncia ser\xE1 registrada no Ecossistema Oon." }),
2864
+ /* @__PURE__ */ jsx25(
2865
+ Button10,
2686
2866
  {
2687
2867
  colorPalette: "blue",
2688
2868
  onClick: completeMemberActivation,
@@ -2692,14 +2872,14 @@ function ActivationPage() {
2692
2872
  }
2693
2873
  )
2694
2874
  ] }),
2695
- step === 6 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
2696
- /* @__PURE__ */ jsx20(Heading8, { size: "md", children: "Ativa\xE7\xE3o conclu\xEDda" }),
2697
- devResult?.appCode ? /* @__PURE__ */ jsxs13(Text13, { children: [
2875
+ step === 6 && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2876
+ /* @__PURE__ */ jsx25(Heading10, { size: "md", children: "Ativa\xE7\xE3o conclu\xEDda" }),
2877
+ devResult?.appCode ? /* @__PURE__ */ jsxs16(Text16, { children: [
2698
2878
  "C\xF3digo do app: ",
2699
2879
  devResult.appCode,
2700
2880
  ". Redirecionando para a Central em desenvolvimento..."
2701
- ] }) : /* @__PURE__ */ jsx20(Text13, { children: "Redirecionando para o login..." }),
2702
- devResult?.instrucoes?.env ? /* @__PURE__ */ jsx20(Text13, { fontSize: "sm", color: "gray.500", children: devResult.instrucoes.env }) : null
2881
+ ] }) : /* @__PURE__ */ jsx25(Text16, { children: "Redirecionando para o login..." }),
2882
+ devResult?.instrucoes?.env ? /* @__PURE__ */ jsx25(Text16, { fontSize: "sm", color: "gray.500", children: devResult.instrucoes.env }) : null
2703
2883
  ] })
2704
2884
  ]
2705
2885
  }
@@ -2709,47 +2889,47 @@ function InstanceBlockedPage({
2709
2889
  title,
2710
2890
  message
2711
2891
  }) {
2712
- return /* @__PURE__ */ jsxs13(Box12, { p: 8, children: [
2713
- /* @__PURE__ */ jsx20(Heading8, { children: title }),
2714
- /* @__PURE__ */ jsx20(Text13, { children: message })
2892
+ return /* @__PURE__ */ jsxs16(Box15, { p: 8, children: [
2893
+ /* @__PURE__ */ jsx25(Heading10, { children: title }),
2894
+ /* @__PURE__ */ jsx25(Text16, { children: message })
2715
2895
  ] });
2716
2896
  }
2717
2897
 
2718
2898
  // src/security/RouteGuard.tsx
2719
- import { Fragment as Fragment3, jsx as jsx21 } from "react/jsx-runtime";
2899
+ import { Fragment as Fragment5, jsx as jsx26 } from "react/jsx-runtime";
2720
2900
  function RouteGuard({
2721
2901
  permission,
2722
2902
  children
2723
2903
  }) {
2724
2904
  const { status, hasPermission } = useOonAuth();
2725
- if (status === "loading") return /* @__PURE__ */ jsx21(LoadingScreen, {});
2726
- if (status === "unauthenticated") return /* @__PURE__ */ jsx21(LoadingScreen, { message: "Redirecionando para o login..." });
2905
+ if (status === "loading") return /* @__PURE__ */ jsx26(LoadingScreen, {});
2906
+ if (status === "unauthenticated") return /* @__PURE__ */ jsx26(LoadingScreen, { message: "Redirecionando para o login..." });
2727
2907
  if (!hasPermission(permission)) {
2728
- return /* @__PURE__ */ jsx21(LoadingScreen, { message: "Voc\xEA n\xE3o tem acesso a esta tela." });
2908
+ return /* @__PURE__ */ jsx26(LoadingScreen, { message: "Voc\xEA n\xE3o tem acesso a esta tela." });
2729
2909
  }
2730
- return /* @__PURE__ */ jsx21(Fragment3, { children });
2910
+ return /* @__PURE__ */ jsx26(Fragment5, { children });
2731
2911
  }
2732
2912
 
2733
2913
  // src/security/ActivationGuard.tsx
2734
2914
  import { Navigate as Navigate3 } from "react-router-dom";
2735
- import { jsx as jsx22 } from "react/jsx-runtime";
2915
+ import { jsx as jsx27 } from "react/jsx-runtime";
2736
2916
  function ActivationGuard({ children }) {
2737
2917
  const { status } = useActivation();
2738
2918
  if (status === "loading") return null;
2739
- if (status === "suspended") return /* @__PURE__ */ jsx22(Navigate3, { to: "/instancia-suspensa", replace: true });
2740
- if (status === "revoked") return /* @__PURE__ */ jsx22(Navigate3, { to: "/instancia-revogada", replace: true });
2741
- if (status !== "active" && window.location.pathname !== "/ativacao") return /* @__PURE__ */ jsx22(Navigate3, { to: "/ativacao", replace: true });
2919
+ if (status === "suspended") return /* @__PURE__ */ jsx27(Navigate3, { to: "/instancia-suspensa", replace: true });
2920
+ if (status === "revoked") return /* @__PURE__ */ jsx27(Navigate3, { to: "/instancia-revogada", replace: true });
2921
+ if (status !== "active" && window.location.pathname !== "/ativacao") return /* @__PURE__ */ jsx27(Navigate3, { to: "/ativacao", replace: true });
2742
2922
  return children;
2743
2923
  }
2744
2924
 
2745
2925
  // src/app/createOonRouter.tsx
2746
- import { jsx as jsx23 } from "react/jsx-runtime";
2747
- function createOonRouter({ app, menu, routes, security }) {
2926
+ import { jsx as jsx28 } from "react/jsx-runtime";
2927
+ function createOonRouter({ app, menu, routes, security, layout, registry }) {
2748
2928
  const guardEnabled = security?.enableRouteGuard !== false;
2749
2929
  const publicRoutes = routes.filter((route) => route.public).map((route) => ({ path: route.path, element: route.element }));
2750
2930
  const privateSource = routes.filter((route) => !route.public);
2751
2931
  const privateRoutes = privateSource.map((route) => {
2752
- const element = guardEnabled ? /* @__PURE__ */ jsx23(RouteGuard, { permission: route.permissions, children: route.element }) : route.element;
2932
+ const element = guardEnabled ? /* @__PURE__ */ jsx28(RouteGuard, { permission: route.permissions, children: route.element }) : route.element;
2753
2933
  return route.path === "/" ? { index: true, element } : { path: route.path.replace(/^\//, ""), element };
2754
2934
  });
2755
2935
  const hasIndexRoute = privateSource.some((route) => route.path === "/");
@@ -2757,7 +2937,7 @@ function createOonRouter({ app, menu, routes, security }) {
2757
2937
  if (!hasIndexRoute && firstRoute) {
2758
2938
  privateRoutes.unshift({
2759
2939
  index: true,
2760
- element: /* @__PURE__ */ jsx23(Navigate4, { to: firstRoute.path, replace: true })
2940
+ element: /* @__PURE__ */ jsx28(Navigate4, { to: firstRoute.path, replace: true })
2761
2941
  });
2762
2942
  }
2763
2943
  const customPaths = new Set(publicRoutes.map((route) => route.path));
@@ -2765,19 +2945,19 @@ function createOonRouter({ app, menu, routes, security }) {
2765
2945
  if (!customPaths.has("/login")) {
2766
2946
  builtInPublicRoutes.push({
2767
2947
  path: "/login",
2768
- element: /* @__PURE__ */ jsx23(ActivationGuard, { children: /* @__PURE__ */ jsx23(LoginPage, { app }) })
2948
+ element: /* @__PURE__ */ jsx28(ActivationGuard, { children: /* @__PURE__ */ jsx28(LoginPage, { app }) })
2769
2949
  });
2770
2950
  }
2771
2951
  if (!customPaths.has("/ativacao")) {
2772
2952
  builtInPublicRoutes.push({
2773
2953
  path: "/ativacao",
2774
- element: /* @__PURE__ */ jsx23(ActivationPage, {})
2954
+ element: /* @__PURE__ */ jsx28(ActivationPage, {})
2775
2955
  });
2776
2956
  }
2777
2957
  if (!customPaths.has("/instancia-suspensa")) {
2778
2958
  builtInPublicRoutes.push({
2779
2959
  path: "/instancia-suspensa",
2780
- element: /* @__PURE__ */ jsx23(
2960
+ element: /* @__PURE__ */ jsx28(
2781
2961
  InstanceBlockedPage,
2782
2962
  {
2783
2963
  title: "Inst\xE2ncia suspensa",
@@ -2789,7 +2969,7 @@ function createOonRouter({ app, menu, routes, security }) {
2789
2969
  if (!customPaths.has("/instancia-revogada")) {
2790
2970
  builtInPublicRoutes.push({
2791
2971
  path: "/instancia-revogada",
2792
- element: /* @__PURE__ */ jsx23(
2972
+ element: /* @__PURE__ */ jsx28(
2793
2973
  InstanceBlockedPage,
2794
2974
  {
2795
2975
  title: "Inst\xE2ncia revogada",
@@ -2801,7 +2981,7 @@ function createOonRouter({ app, menu, routes, security }) {
2801
2981
  if (!customPaths.has("/acesso-negado")) {
2802
2982
  builtInPublicRoutes.push({
2803
2983
  path: "/acesso-negado",
2804
- element: /* @__PURE__ */ jsx23(AccessDeniedPage, { app })
2984
+ element: /* @__PURE__ */ jsx28(AccessDeniedPage, { app })
2805
2985
  });
2806
2986
  }
2807
2987
  const tree = [
@@ -2809,7 +2989,7 @@ function createOonRouter({ app, menu, routes, security }) {
2809
2989
  ...publicRoutes,
2810
2990
  {
2811
2991
  path: "/",
2812
- element: /* @__PURE__ */ jsx23(ActivationGuard, { children: /* @__PURE__ */ jsx23(AppAccessGuard, { children: /* @__PURE__ */ jsx23(AuthenticatedLayout, { app, menu }) }) }),
2992
+ element: /* @__PURE__ */ jsx28(ActivationGuard, { children: /* @__PURE__ */ jsx28(AppAccessGuard, { children: /* @__PURE__ */ jsx28(AuthenticatedLayout, { app, menu, layout, registry }) }) }),
2813
2993
  children: privateRoutes
2814
2994
  }
2815
2995
  ];
@@ -2817,7 +2997,7 @@ function createOonRouter({ app, menu, routes, security }) {
2817
2997
  }
2818
2998
 
2819
2999
  // src/app/OonApp.tsx
2820
- import { jsx as jsx24 } from "react/jsx-runtime";
3000
+ import { jsx as jsx29 } from "react/jsx-runtime";
2821
3001
  function localLoginUrl() {
2822
3002
  const current = `${window.location.pathname}${window.location.search}`;
2823
3003
  return `/login?redirect=${encodeURIComponent(current)}`;
@@ -2846,15 +3026,17 @@ function OonApp({ config }) {
2846
3026
  app: config.app,
2847
3027
  menu,
2848
3028
  routes,
2849
- security: config.security
3029
+ security: config.security,
3030
+ layout: config.layout ?? config.ui?.layout,
3031
+ registry: config.registry ?? config.ui?.registry
2850
3032
  });
2851
3033
  return { http: http2, storage: storage2, router: router2 };
2852
3034
  }, [config]);
2853
- return /* @__PURE__ */ jsx24(OonProviders, { config, http, storage, children: /* @__PURE__ */ jsx24(RouterProvider, { router }) });
3035
+ return /* @__PURE__ */ jsx29(OonProviders, { config, http, storage, children: /* @__PURE__ */ jsx29(RouterProvider, { router }) });
2854
3036
  }
2855
3037
 
2856
3038
  // src/start.tsx
2857
- import { jsx as jsx25 } from "react/jsx-runtime";
3039
+ import { jsx as jsx30 } from "react/jsx-runtime";
2858
3040
  function validateConfig(config) {
2859
3041
  if (!config?.app?.id) throw new Error("oonCoreFront.start: config.app.id \xE9 obrigat\xF3rio.");
2860
3042
  if (!config?.api?.baseUrl) throw new Error("oonCoreFront.start: config.api.baseUrl \xE9 obrigat\xF3rio.");
@@ -2888,7 +3070,7 @@ function start(config) {
2888
3070
  const el = document.getElementById(rootId);
2889
3071
  if (!el) throw new Error(`oonCoreFront.start: elemento #${rootId} n\xE3o encontrado no DOM.`);
2890
3072
  createRoot(el).render(
2891
- /* @__PURE__ */ jsx25(StrictMode, { children: /* @__PURE__ */ jsx25(OonApp, { config }) })
3073
+ /* @__PURE__ */ jsx30(StrictMode, { children: /* @__PURE__ */ jsx30(OonApp, { config }) })
2892
3074
  );
2893
3075
  }
2894
3076
  var oonCoreFront = { start };
@@ -2951,7 +3133,9 @@ function manifestToConfig(manifest, runtime) {
2951
3133
  redactAssistantContext: true,
2952
3134
  disableConsoleInProduction: true
2953
3135
  },
2954
- ui: { views }
3136
+ layout: manifest.layout,
3137
+ registry: manifest.registry,
3138
+ ui: { schemaVersion: manifest.schemaVersion, layout: manifest.layout, registry: manifest.registry, navigation: manifest.navigation, views, pages: manifest.pages }
2955
3139
  };
2956
3140
  }
2957
3141
  function startFromManifest(manifest, runtime) {
@@ -2976,34 +3160,34 @@ function defineOonModule(mod) {
2976
3160
  }
2977
3161
 
2978
3162
  // src/components/CoreIntegration.tsx
2979
- import { Badge as Badge3, Box as Box13, Button as Button10, Flex as Flex10, Heading as Heading9, Stack as Stack7, Text as Text14 } from "@chakra-ui/react";
3163
+ import { Badge as Badge3, Box as Box16, Button as Button11, Flex as Flex11, Heading as Heading11, Stack as Stack8, Text as Text17 } from "@chakra-ui/react";
2980
3164
  import { useMutation as useMutation3 } from "@tanstack/react-query";
2981
- import { jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
3165
+ import { jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
2982
3166
  function CoreIntegration({ label = "Integra\xE7\xF5es" }) {
2983
3167
  const { http } = useOonApi();
2984
3168
  const metadata = useCoreMetadata();
2985
3169
  const reprocess = useMutation3({
2986
3170
  mutationFn: () => http.post("/integrations/actions/process-active", {}, { headers: { "x-oon-origin": "integration" } })
2987
3171
  });
2988
- if (metadata.isLoading) return /* @__PURE__ */ jsx26(LoadingScreen, {});
2989
- if (metadata.isError) return /* @__PURE__ */ jsx26(ErrorState, { error: metadata.error });
3172
+ if (metadata.isLoading) return /* @__PURE__ */ jsx31(LoadingScreen, {});
3173
+ if (metadata.isError) return /* @__PURE__ */ jsx31(ErrorState, { error: metadata.error });
2990
3174
  const integrations = metadata.data?.integrations ?? [];
2991
- return /* @__PURE__ */ jsxs14(Stack7, { gap: 6, children: [
2992
- /* @__PURE__ */ jsxs14(Flex10, { align: "center", justify: "space-between", children: [
2993
- /* @__PURE__ */ jsx26(Heading9, { size: "lg", children: label }),
2994
- /* @__PURE__ */ jsx26(Button10, { size: "sm", variant: "outline", loading: reprocess.isPending, onClick: () => reprocess.mutate(), children: "Reprocessar ativos" })
3175
+ return /* @__PURE__ */ jsxs17(Stack8, { gap: 6, children: [
3176
+ /* @__PURE__ */ jsxs17(Flex11, { align: "center", justify: "space-between", children: [
3177
+ /* @__PURE__ */ jsx31(Heading11, { size: "lg", children: label }),
3178
+ /* @__PURE__ */ jsx31(Button11, { size: "sm", variant: "outline", loading: reprocess.isPending, onClick: () => reprocess.mutate(), children: "Reprocessar ativos" })
2995
3179
  ] }),
2996
- /* @__PURE__ */ jsx26(Stack7, { gap: 3, children: integrations.length === 0 ? /* @__PURE__ */ jsx26(Text14, { color: "gray.400", children: "Nenhuma integra\xE7\xE3o declarada." }) : integrations.map((it, idx) => /* @__PURE__ */ jsx26(
2997
- Box13,
3180
+ /* @__PURE__ */ jsx31(Stack8, { gap: 3, children: integrations.length === 0 ? /* @__PURE__ */ jsx31(Text17, { color: "gray.400", children: "Nenhuma integra\xE7\xE3o declarada." }) : integrations.map((it, idx) => /* @__PURE__ */ jsx31(
3181
+ Box16,
2998
3182
  {
2999
3183
  borderWidth: "1px",
3000
3184
  borderColor: "gray.200",
3001
3185
  borderRadius: "md",
3002
3186
  bg: "white",
3003
3187
  p: 4,
3004
- children: /* @__PURE__ */ jsxs14(Flex10, { align: "center", justify: "space-between", children: [
3005
- /* @__PURE__ */ jsx26(Text14, { fontWeight: "medium", children: it.label ?? it.name ?? "Integra\xE7\xE3o" }),
3006
- /* @__PURE__ */ jsx26(Badge3, { colorPalette: it.status === "erro" ? "red" : it.status === "ativo" ? "green" : "gray", children: it.status ?? "\u2014" })
3188
+ children: /* @__PURE__ */ jsxs17(Flex11, { align: "center", justify: "space-between", children: [
3189
+ /* @__PURE__ */ jsx31(Text17, { fontWeight: "medium", children: it.label ?? it.name ?? "Integra\xE7\xE3o" }),
3190
+ /* @__PURE__ */ jsx31(Badge3, { colorPalette: it.status === "erro" ? "red" : it.status === "ativo" ? "green" : "gray", children: it.status ?? "\u2014" })
3007
3191
  ] })
3008
3192
  },
3009
3193
  it.id ?? it.name ?? idx
@@ -3012,9 +3196,9 @@ function CoreIntegration({ label = "Integra\xE7\xF5es" }) {
3012
3196
  }
3013
3197
 
3014
3198
  // src/components/CoreCurrency.tsx
3015
- import { Button as Button11, Flex as Flex11, Heading as Heading10, Stack as Stack8, Text as Text15 } from "@chakra-ui/react";
3199
+ import { Button as Button12, Flex as Flex12, Heading as Heading12, Stack as Stack9, Text as Text18 } from "@chakra-ui/react";
3016
3200
  import { useMutation as useMutation4, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
3017
- import { jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
3201
+ import { jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
3018
3202
  function CoreCurrency({ model = "Moeda", label = "Multi-moedas", endpoint = "/moedas", columns }) {
3019
3203
  const { http } = useOonApi();
3020
3204
  const queryClient = useQueryClient3();
@@ -3022,21 +3206,21 @@ function CoreCurrency({ model = "Moeda", label = "Multi-moedas", endpoint = "/mo
3022
3206
  mutationFn: () => http.post(`${endpoint}/actions/update-rates`, {}, { headers: { "x-oon-origin": "integration" } }),
3023
3207
  onSuccess: () => queryClient.invalidateQueries({ queryKey: ["oon", "list", endpoint] })
3024
3208
  });
3025
- return /* @__PURE__ */ jsxs15(Stack8, { gap: 6, children: [
3026
- /* @__PURE__ */ jsxs15(Flex11, { align: "center", justify: "space-between", children: [
3027
- /* @__PURE__ */ jsx27(Heading10, { size: "lg", children: label }),
3028
- /* @__PURE__ */ jsx27(Button11, { size: "sm", colorPalette: "blue", loading: updateRates.isPending, onClick: () => updateRates.mutate(), children: "Atualizar cota\xE7\xF5es" })
3209
+ return /* @__PURE__ */ jsxs18(Stack9, { gap: 6, children: [
3210
+ /* @__PURE__ */ jsxs18(Flex12, { align: "center", justify: "space-between", children: [
3211
+ /* @__PURE__ */ jsx32(Heading12, { size: "lg", children: label }),
3212
+ /* @__PURE__ */ jsx32(Button12, { size: "sm", colorPalette: "blue", loading: updateRates.isPending, onClick: () => updateRates.mutate(), children: "Atualizar cota\xE7\xF5es" })
3029
3213
  ] }),
3030
- updateRates.isError ? /* @__PURE__ */ jsx27(Text15, { fontSize: "sm", color: "red.600", children: updateRates.error?.message }) : null,
3031
- /* @__PURE__ */ jsx27(CoreCollection, { model, label: "", mode: columns ? "full" : "dynamic", endpoint, columns })
3214
+ updateRates.isError ? /* @__PURE__ */ jsx32(Text18, { fontSize: "sm", color: "red.600", children: updateRates.error?.message }) : null,
3215
+ /* @__PURE__ */ jsx32(CoreCollection, { model, label: "", mode: columns ? "full" : "dynamic", endpoint, columns })
3032
3216
  ] });
3033
3217
  }
3034
3218
 
3035
3219
  // src/components/CoreAssistant.tsx
3036
3220
  import { useState as useState10 } from "react";
3037
- import { Box as Box14, Button as Button12, Flex as Flex12, Heading as Heading11, Input as Input6, Stack as Stack9, Text as Text16 } from "@chakra-ui/react";
3221
+ import { Box as Box17, Button as Button13, Flex as Flex13, Heading as Heading13, Input as Input6, Stack as Stack10, Text as Text19 } from "@chakra-ui/react";
3038
3222
  import { useMutation as useMutation5 } from "@tanstack/react-query";
3039
- import { jsx as jsx28, jsxs as jsxs16 } from "react/jsx-runtime";
3223
+ import { jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
3040
3224
  function CoreAssistant({ assistantCode, label = "Assistente", entity, endpoint = "/assistant-runs" }) {
3041
3225
  const { http } = useOonApi();
3042
3226
  const [messages, setMessages] = useState10([]);
@@ -3065,11 +3249,11 @@ function CoreAssistant({ assistantCode, label = "Assistente", entity, endpoint =
3065
3249
  setInput("");
3066
3250
  ask.mutate(text);
3067
3251
  };
3068
- return /* @__PURE__ */ jsxs16(Stack9, { gap: 4, maxW: "560px", children: [
3069
- /* @__PURE__ */ jsx28(Heading11, { size: "md", children: label }),
3070
- /* @__PURE__ */ jsx28(Box14, { borderWidth: "1px", borderColor: "gray.200", borderRadius: "md", bg: "white", p: 4, minH: "240px", children: /* @__PURE__ */ jsxs16(Stack9, { gap: 3, children: [
3071
- messages.length === 0 ? /* @__PURE__ */ jsx28(Text16, { color: "gray.400", fontSize: "sm", children: "Fa\xE7a uma pergunta ao assistente." }) : messages.map((m, idx) => /* @__PURE__ */ jsx28(Flex12, { justify: m.role === "user" ? "flex-end" : "flex-start", children: /* @__PURE__ */ jsx28(
3072
- Box14,
3252
+ return /* @__PURE__ */ jsxs19(Stack10, { gap: 4, maxW: "560px", children: [
3253
+ /* @__PURE__ */ jsx33(Heading13, { size: "md", children: label }),
3254
+ /* @__PURE__ */ jsx33(Box17, { borderWidth: "1px", borderColor: "gray.200", borderRadius: "md", bg: "white", p: 4, minH: "240px", children: /* @__PURE__ */ jsxs19(Stack10, { gap: 3, children: [
3255
+ messages.length === 0 ? /* @__PURE__ */ jsx33(Text19, { color: "gray.400", fontSize: "sm", children: "Fa\xE7a uma pergunta ao assistente." }) : messages.map((m, idx) => /* @__PURE__ */ jsx33(Flex13, { justify: m.role === "user" ? "flex-end" : "flex-start", children: /* @__PURE__ */ jsx33(
3256
+ Box17,
3073
3257
  {
3074
3258
  bg: m.role === "user" ? "brand.500" : "gray.100",
3075
3259
  color: m.role === "user" ? "white" : "gray.800",
@@ -3081,11 +3265,11 @@ function CoreAssistant({ assistantCode, label = "Assistente", entity, endpoint =
3081
3265
  children: m.content
3082
3266
  }
3083
3267
  ) }, idx)),
3084
- ask.isPending ? /* @__PURE__ */ jsx28(Text16, { color: "gray.400", fontSize: "sm", children: "Pensando\u2026" }) : null,
3085
- ask.isError ? /* @__PURE__ */ jsx28(Text16, { color: "red.600", fontSize: "sm", children: ask.error?.message }) : null
3268
+ ask.isPending ? /* @__PURE__ */ jsx33(Text19, { color: "gray.400", fontSize: "sm", children: "Pensando\u2026" }) : null,
3269
+ ask.isError ? /* @__PURE__ */ jsx33(Text19, { color: "red.600", fontSize: "sm", children: ask.error?.message }) : null
3086
3270
  ] }) }),
3087
- /* @__PURE__ */ jsxs16(Flex12, { gap: 2, children: [
3088
- /* @__PURE__ */ jsx28(
3271
+ /* @__PURE__ */ jsxs19(Flex13, { gap: 2, children: [
3272
+ /* @__PURE__ */ jsx33(
3089
3273
  Input6,
3090
3274
  {
3091
3275
  size: "sm",
@@ -3097,29 +3281,29 @@ function CoreAssistant({ assistantCode, label = "Assistente", entity, endpoint =
3097
3281
  }
3098
3282
  }
3099
3283
  ),
3100
- /* @__PURE__ */ jsx28(Button12, { size: "sm", colorPalette: "blue", onClick: send, loading: ask.isPending, children: "Enviar" })
3284
+ /* @__PURE__ */ jsx33(Button13, { size: "sm", colorPalette: "blue", onClick: send, loading: ask.isPending, children: "Enviar" })
3101
3285
  ] })
3102
3286
  ] });
3103
3287
  }
3104
-
3105
- // src/security/PermissionGate.tsx
3106
- import { Fragment as Fragment4, jsx as jsx29 } from "react/jsx-runtime";
3107
- function PermissionGate({
3108
- permission,
3109
- fallback = null,
3110
- children
3111
- }) {
3112
- const { hasPermission } = useOonAuth();
3113
- return /* @__PURE__ */ jsx29(Fragment4, { children: hasPermission(permission) ? children : fallback });
3114
- }
3115
3288
  export {
3289
+ CoreActions,
3116
3290
  CoreAssistant,
3291
+ CoreCards,
3117
3292
  CoreCollection,
3118
3293
  CoreCurrency,
3119
3294
  CoreDashboard,
3295
+ CoreDataGrid,
3120
3296
  CoreDocument,
3297
+ CoreEmptyState,
3298
+ CoreField,
3299
+ CoreForm,
3121
3300
  CoreIntegration,
3301
+ CoreLoadingState,
3302
+ CorePage2 as CorePage,
3303
+ CorePageHeader,
3122
3304
  CorePipeline,
3305
+ CoreRelationField,
3306
+ CoreToolbar,
3123
3307
  PermissionGate,
3124
3308
  defineCollectionView,
3125
3309
  defineDashboard,