xladmin 0.3.6 → 0.3.7

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.
@@ -5,6 +5,7 @@ type ShellContextValue = {
5
5
  pendingPath: string | null;
6
6
  pendingView: 'overview' | 'model' | 'generic' | null;
7
7
  startPendingNavigation: (path: string, view?: 'overview' | 'model' | 'generic') => void;
8
+ finishPendingNavigation: (path?: string) => void;
8
9
  };
9
10
  export declare function ShellContextProvider({ value, children, }: {
10
11
  value: ShellContextValue;
package/dist/index.js CHANGED
@@ -1372,7 +1372,7 @@ function FormDialog({
1372
1372
  }
1373
1373
 
1374
1374
  // src/components/OverviewPage.tsx
1375
- import { useEffect as useEffect7, useMemo as useMemo7, useState as useState7 } from "react";
1375
+ import { useEffect as useEffect7, useLayoutEffect, useMemo as useMemo7, useState as useState7 } from "react";
1376
1376
  import { Alert as Alert3, Box as Box6, Grid, Paper as Paper4, Skeleton as Skeleton2, Stack as Stack6 } from "@mui/material";
1377
1377
 
1378
1378
  // src/hooks/useAdminDocumentTitle.ts
@@ -1403,6 +1403,31 @@ function useAdminData() {
1403
1403
  return useContext4(AdminDataContext);
1404
1404
  }
1405
1405
 
1406
+ // src/components/layout/ShellContext.tsx
1407
+ import { createContext as createContext5, useContext as useContext5 } from "react";
1408
+ import { jsx as jsx7 } from "react/jsx-runtime";
1409
+ var defaultShellContextValue = {
1410
+ isMobile: false,
1411
+ openMobileSidebar: () => {
1412
+ },
1413
+ pendingPath: null,
1414
+ pendingView: null,
1415
+ startPendingNavigation: () => {
1416
+ },
1417
+ finishPendingNavigation: () => {
1418
+ }
1419
+ };
1420
+ var ShellContext = createContext5(defaultShellContextValue);
1421
+ function ShellContextProvider({
1422
+ value,
1423
+ children
1424
+ }) {
1425
+ return /* @__PURE__ */ jsx7(ShellContext.Provider, { value, children });
1426
+ }
1427
+ function useShellContext() {
1428
+ return useContext5(ShellContext);
1429
+ }
1430
+
1406
1431
  // src/components/ModelsBlocks.tsx
1407
1432
  import { memo as memo2, useMemo as useMemo6 } from "react";
1408
1433
  import { Box as Box4, Stack as Stack4, useMediaQuery, useTheme as useTheme2 } from "@mui/material";
@@ -1421,10 +1446,10 @@ import {
1421
1446
 
1422
1447
  // src/components/models-blocks/BlockTitle.tsx
1423
1448
  import { Stack as Stack2, Typography as Typography2 } from "@mui/material";
1424
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1449
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1425
1450
  function BlockTitle({ block, compact = false }) {
1426
1451
  return /* @__PURE__ */ jsxs4(Stack2, { spacing: 0.25, children: [
1427
- /* @__PURE__ */ jsx7(
1452
+ /* @__PURE__ */ jsx8(
1428
1453
  Typography2,
1429
1454
  {
1430
1455
  variant: compact ? "subtitle1" : "h6",
@@ -1436,7 +1461,7 @@ function BlockTitle({ block, compact = false }) {
1436
1461
  children: block.title
1437
1462
  }
1438
1463
  ),
1439
- block.description && !compact ? /* @__PURE__ */ jsx7(Typography2, { color: "text.secondary", sx: { fontSize: compact ? 12 : 14, lineHeight: 1.3 }, children: block.description }) : null
1464
+ block.description && !compact ? /* @__PURE__ */ jsx8(Typography2, { color: "text.secondary", sx: { fontSize: compact ? 12 : 14, lineHeight: 1.3 }, children: block.description }) : null
1440
1465
  ] });
1441
1466
  }
1442
1467
 
@@ -1495,10 +1520,10 @@ function getStorageKey(blockSlug) {
1495
1520
  }
1496
1521
 
1497
1522
  // src/components/NavLink.tsx
1498
- import { jsx as jsx8 } from "react/jsx-runtime";
1523
+ import { jsx as jsx9 } from "react/jsx-runtime";
1499
1524
  function NavLink({ href, children, style, title, onClick, router }) {
1500
1525
  const resolvedRouter = useAdminRouter(router);
1501
- return /* @__PURE__ */ jsx8(
1526
+ return /* @__PURE__ */ jsx9(
1502
1527
  "a",
1503
1528
  {
1504
1529
  href,
@@ -1514,7 +1539,7 @@ function NavLink({ href, children, style, title, onClick, router }) {
1514
1539
  }
1515
1540
 
1516
1541
  // src/components/models-blocks/DashboardModelsBlock.tsx
1517
- import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1542
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
1518
1543
  function DashboardModelsBlock({ block, basePath }) {
1519
1544
  const [isExpanded, setIsExpanded] = useBlockExpandedState(block.slug, block.default_expanded);
1520
1545
  return /* @__PURE__ */ jsxs5(
@@ -1533,10 +1558,10 @@ function DashboardModelsBlock({ block, basePath }) {
1533
1558
  }
1534
1559
  },
1535
1560
  children: [
1536
- /* @__PURE__ */ jsx9(
1561
+ /* @__PURE__ */ jsx10(
1537
1562
  AccordionSummary,
1538
1563
  {
1539
- expandIcon: block.collapsible ? /* @__PURE__ */ jsx9(ExpandMoreIcon, { fontSize: "small" }) : void 0,
1564
+ expandIcon: block.collapsible ? /* @__PURE__ */ jsx10(ExpandMoreIcon, { fontSize: "small" }) : void 0,
1540
1565
  sx: {
1541
1566
  minHeight: "48px",
1542
1567
  pr: 1.75,
@@ -1558,15 +1583,15 @@ function DashboardModelsBlock({ block, basePath }) {
1558
1583
  mb: 1.05
1559
1584
  }
1560
1585
  },
1561
- children: /* @__PURE__ */ jsx9(BlockTitle, { block })
1586
+ children: /* @__PURE__ */ jsx10(BlockTitle, { block })
1562
1587
  }
1563
1588
  ),
1564
- /* @__PURE__ */ jsx9(AccordionDetails, { sx: { px: 1.35, pb: 1.35, pt: 0 }, children: /* @__PURE__ */ jsx9(Stack3, { spacing: 0.5, sx: { px: 0.4 }, children: block.models.map((model) => /* @__PURE__ */ jsx9(
1589
+ /* @__PURE__ */ jsx10(AccordionDetails, { sx: { px: 1.35, pb: 1.35, pt: 0 }, children: /* @__PURE__ */ jsx10(Stack3, { spacing: 0.5, sx: { px: 0.4 }, children: block.models.map((model) => /* @__PURE__ */ jsx10(
1565
1590
  NavLink,
1566
1591
  {
1567
1592
  href: `${basePath}/${model.slug}`,
1568
1593
  style: { textDecoration: "none", display: "block" },
1569
- children: /* @__PURE__ */ jsx9(
1594
+ children: /* @__PURE__ */ jsx10(
1570
1595
  ButtonBase,
1571
1596
  {
1572
1597
  sx: {
@@ -1576,7 +1601,7 @@ function DashboardModelsBlock({ block, basePath }) {
1576
1601
  borderRadius: "8px",
1577
1602
  overflow: "hidden"
1578
1603
  },
1579
- children: /* @__PURE__ */ jsx9(
1604
+ children: /* @__PURE__ */ jsx10(
1580
1605
  ListItemButton,
1581
1606
  {
1582
1607
  sx: {
@@ -1585,7 +1610,7 @@ function DashboardModelsBlock({ block, basePath }) {
1585
1610
  px: 1.25,
1586
1611
  py: 0.4
1587
1612
  },
1588
- children: /* @__PURE__ */ jsx9(ListItemText, { primary: model.title })
1613
+ children: /* @__PURE__ */ jsx10(ListItemText, { primary: model.title })
1589
1614
  }
1590
1615
  )
1591
1616
  }
@@ -1610,7 +1635,7 @@ import {
1610
1635
  ListItemText as ListItemText2,
1611
1636
  Paper as Paper2
1612
1637
  } from "@mui/material";
1613
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1638
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
1614
1639
  function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate }) {
1615
1640
  const [isExpanded, setIsExpanded] = useBlockExpandedState(block.slug, block.default_expanded);
1616
1641
  if (block.collapsible) {
@@ -1630,10 +1655,10 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1630
1655
  }
1631
1656
  },
1632
1657
  children: [
1633
- /* @__PURE__ */ jsx10(
1658
+ /* @__PURE__ */ jsx11(
1634
1659
  AccordionSummary2,
1635
1660
  {
1636
- expandIcon: /* @__PURE__ */ jsx10(ExpandMoreIcon2, { fontSize: "small" }),
1661
+ expandIcon: /* @__PURE__ */ jsx11(ExpandMoreIcon2, { fontSize: "small" }),
1637
1662
  sx: {
1638
1663
  minHeight: "42px",
1639
1664
  pr: 1.25,
@@ -1649,10 +1674,10 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1649
1674
  my: 0
1650
1675
  }
1651
1676
  },
1652
- children: /* @__PURE__ */ jsx10(BlockTitle, { block, compact: true })
1677
+ children: /* @__PURE__ */ jsx11(BlockTitle, { block, compact: true })
1653
1678
  }
1654
1679
  ),
1655
- /* @__PURE__ */ jsx10(AccordionDetails2, { sx: { p: 0 }, children: /* @__PURE__ */ jsx10(
1680
+ /* @__PURE__ */ jsx11(AccordionDetails2, { sx: { p: 0 }, children: /* @__PURE__ */ jsx11(
1656
1681
  SidebarModelsList,
1657
1682
  {
1658
1683
  models: block.models,
@@ -1674,8 +1699,8 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1674
1699
  overflow: "hidden"
1675
1700
  },
1676
1701
  children: [
1677
- /* @__PURE__ */ jsx10(Box3, { sx: { px: 1.25, py: 1 }, children: /* @__PURE__ */ jsx10(BlockTitle, { block, compact: true }) }),
1678
- /* @__PURE__ */ jsx10(
1702
+ /* @__PURE__ */ jsx11(Box3, { sx: { px: 1.25, py: 1 }, children: /* @__PURE__ */ jsx11(BlockTitle, { block, compact: true }) }),
1703
+ /* @__PURE__ */ jsx11(
1679
1704
  SidebarModelsList,
1680
1705
  {
1681
1706
  models: block.models,
@@ -1689,16 +1714,16 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1689
1714
  );
1690
1715
  }
1691
1716
  function SidebarModelsList({ models, basePath, activeModelSlug, onModelNavigate }) {
1692
- return /* @__PURE__ */ jsx10(List, { dense: true, disablePadding: true, sx: { display: "flex", flexDirection: "column", gap: 0.5, p: 1.35 }, children: models.map((model) => {
1717
+ return /* @__PURE__ */ jsx11(List, { dense: true, disablePadding: true, sx: { display: "flex", flexDirection: "column", gap: 0.5, p: 1.35 }, children: models.map((model) => {
1693
1718
  const href = `${basePath}/${model.slug}`;
1694
1719
  const isActive = activeModelSlug === model.slug;
1695
- return /* @__PURE__ */ jsx10(
1720
+ return /* @__PURE__ */ jsx11(
1696
1721
  NavLink,
1697
1722
  {
1698
1723
  href,
1699
1724
  style: { textDecoration: "none", display: "block" },
1700
1725
  onClick: () => onModelNavigate == null ? void 0 : onModelNavigate(href),
1701
- children: /* @__PURE__ */ jsx10(
1726
+ children: /* @__PURE__ */ jsx11(
1702
1727
  ListItemButton2,
1703
1728
  {
1704
1729
  selected: isActive,
@@ -1717,7 +1742,7 @@ function SidebarModelsList({ models, basePath, activeModelSlug, onModelNavigate
1717
1742
  backgroundColor: "rgba(255, 255, 255, 0.2)"
1718
1743
  }
1719
1744
  },
1720
- children: /* @__PURE__ */ jsx10(ListItemText2, { primary: model.title })
1745
+ children: /* @__PURE__ */ jsx11(ListItemText2, { primary: model.title })
1721
1746
  }
1722
1747
  )
1723
1748
  },
@@ -1727,7 +1752,7 @@ function SidebarModelsList({ models, basePath, activeModelSlug, onModelNavigate
1727
1752
  }
1728
1753
 
1729
1754
  // src/components/ModelsBlocks.tsx
1730
- import { jsx as jsx11 } from "react/jsx-runtime";
1755
+ import { jsx as jsx12 } from "react/jsx-runtime";
1731
1756
  var ModelsBlocks = memo2(function ModelsBlocks2({
1732
1757
  basePath,
1733
1758
  models,
@@ -1758,7 +1783,7 @@ var ModelsBlocks = memo2(function ModelsBlocks2({
1758
1783
  return distributeBlocksByHeight(normalizedBlocks, columnCount);
1759
1784
  }, [isMdUp, isXlUp, normalizedBlocks]);
1760
1785
  if (variant === "sidebar") {
1761
- return /* @__PURE__ */ jsx11(Stack4, { spacing: 1, children: normalizedBlocks.map((block) => /* @__PURE__ */ jsx11(
1786
+ return /* @__PURE__ */ jsx12(Stack4, { spacing: 1, children: normalizedBlocks.map((block) => /* @__PURE__ */ jsx12(
1762
1787
  SidebarModelsBlock,
1763
1788
  {
1764
1789
  block,
@@ -1769,7 +1794,7 @@ var ModelsBlocks = memo2(function ModelsBlocks2({
1769
1794
  block.slug
1770
1795
  )) });
1771
1796
  }
1772
- return /* @__PURE__ */ jsx11(Box4, { sx: { display: "flex", gap: 2, alignItems: "flex-start" }, children: dashboardColumns.map((column, columnIndex) => /* @__PURE__ */ jsx11(Box4, { sx: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx11(Stack4, { spacing: 2, children: column.map((block) => /* @__PURE__ */ jsx11(DashboardModelsBlock, { block, basePath }, block.slug)) }) }, columnIndex)) });
1797
+ return /* @__PURE__ */ jsx12(Box4, { sx: { display: "flex", gap: 2, alignItems: "flex-start" }, children: dashboardColumns.map((column, columnIndex) => /* @__PURE__ */ jsx12(Box4, { sx: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx12(Stack4, { spacing: 2, children: column.map((block) => /* @__PURE__ */ jsx12(DashboardModelsBlock, { block, basePath }, block.slug)) }) }, columnIndex)) });
1773
1798
  });
1774
1799
  function distributeBlocksByHeight(blocks, columnCount) {
1775
1800
  const columns = Array.from({ length: columnCount }, () => []);
@@ -1796,31 +1821,6 @@ import MenuIcon from "@mui/icons-material/Menu";
1796
1821
  import { Box as Box5 } from "@mui/material";
1797
1822
  import ExpandMoreIcon3 from "@mui/icons-material/ExpandMore";
1798
1823
  import { Alert as Alert2, Collapse, IconButton, Paper as Paper3, Skeleton, Stack as Stack5, Typography as Typography3 } from "@mui/material";
1799
-
1800
- // src/components/layout/ShellContext.tsx
1801
- import { createContext as createContext5, useContext as useContext5 } from "react";
1802
- import { jsx as jsx12 } from "react/jsx-runtime";
1803
- var defaultShellContextValue = {
1804
- isMobile: false,
1805
- openMobileSidebar: () => {
1806
- },
1807
- pendingPath: null,
1808
- pendingView: null,
1809
- startPendingNavigation: () => {
1810
- }
1811
- };
1812
- var ShellContext = createContext5(defaultShellContextValue);
1813
- function ShellContextProvider({
1814
- value,
1815
- children
1816
- }) {
1817
- return /* @__PURE__ */ jsx12(ShellContext.Provider, { value, children });
1818
- }
1819
- function useShellContext() {
1820
- return useContext5(ShellContext);
1821
- }
1822
-
1823
- // src/components/layout/MainHeader.tsx
1824
1824
  import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1825
1825
  var MAIN_HEADER_PADDING_X = 2.5;
1826
1826
  var MAIN_HEADER_PADDING_T = 1.35;
@@ -1980,6 +1980,7 @@ var inFlightModelsRequest = null;
1980
1980
  function OverviewPage({ client, basePath }) {
1981
1981
  const t = useAdminTranslation();
1982
1982
  useAdminDocumentTitle(t("admin_title"), t("overview_title"));
1983
+ const { pendingPath, finishPendingNavigation } = useShellContext();
1983
1984
  const adminData = useAdminData();
1984
1985
  const shellModelsResponse = useMemo7(() => {
1985
1986
  if (adminData.models.length === 0 && adminData.blocks.length === 0) {
@@ -2033,6 +2034,18 @@ function OverviewPage({ client, basePath }) {
2033
2034
  isMounted = false;
2034
2035
  };
2035
2036
  }, [client, shellModelsResponse, t]);
2037
+ useLayoutEffect(() => {
2038
+ if (pendingPath === null) {
2039
+ return;
2040
+ }
2041
+ if (isLoading) {
2042
+ return;
2043
+ }
2044
+ if (!data && !error) {
2045
+ return;
2046
+ }
2047
+ finishPendingNavigation();
2048
+ }, [data, error, finishPendingNavigation, isLoading, pendingPath]);
2036
2049
  if (isLoading && !data) {
2037
2050
  return /* @__PURE__ */ jsx14(OverviewPageSkeleton, {});
2038
2051
  }
@@ -2095,6 +2108,7 @@ function OverviewPageSkeleton() {
2095
2108
  }
2096
2109
 
2097
2110
  // src/components/ModelPage.tsx
2111
+ import { useLayoutEffect as useLayoutEffect3 } from "react";
2098
2112
  import AddIcon from "@mui/icons-material/Add";
2099
2113
  import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
2100
2114
  import ChevronRightIcon from "@mui/icons-material/ChevronRight";
@@ -2714,7 +2728,7 @@ var SearchField = memo5(function SearchField2({
2714
2728
  });
2715
2729
 
2716
2730
  // src/components/model-page/useModelPageController.ts
2717
- import { useCallback as useCallback5, useEffect as useEffect10, useMemo as useMemo9, useRef as useRef4, useState as useState10 } from "react";
2731
+ import { useCallback as useCallback5, useEffect as useEffect10, useLayoutEffect as useLayoutEffect2, useMemo as useMemo9, useRef as useRef4, useState as useState10 } from "react";
2718
2732
 
2719
2733
  // src/cache.ts
2720
2734
  var MAX_CACHE_ENTRIES = 100;
@@ -2900,7 +2914,7 @@ function useModelPageController({
2900
2914
  useEffect10(() => {
2901
2915
  setPageInput(String(currentPage));
2902
2916
  }, [currentPage]);
2903
- useEffect10(() => {
2917
+ useLayoutEffect2(() => {
2904
2918
  var _a2, _b2, _c2, _d2;
2905
2919
  if (previousSlugRef.current === slug) {
2906
2920
  return;
@@ -2940,7 +2954,7 @@ function useModelPageController({
2940
2954
  setPendingDeleteScope(null);
2941
2955
  setPendingDeleteMode("single");
2942
2956
  }, [client, locationSearch, slug]);
2943
- useEffect10(() => {
2957
+ useLayoutEffect2(() => {
2944
2958
  var _a2, _b2;
2945
2959
  const nextSearchParams = new URLSearchParams(locationSearch);
2946
2960
  const nextQuery = (_a2 = nextSearchParams.get("q")) != null ? _a2 : "";
@@ -3394,6 +3408,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3394
3408
  const location = useAdminLocation(resolvedRouter);
3395
3409
  const theme = useTheme3();
3396
3410
  const isMobile = useMediaQuery2(theme.breakpoints.down("md"));
3411
+ const { pendingPath, finishPendingNavigation } = useShellContext();
3397
3412
  const controller = useModelPageController({
3398
3413
  client,
3399
3414
  slug,
@@ -3402,6 +3417,21 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3402
3417
  router: resolvedRouter,
3403
3418
  t
3404
3419
  });
3420
+ useLayoutEffect3(() => {
3421
+ if (pendingPath === null) {
3422
+ return;
3423
+ }
3424
+ if (controller.isLoading) {
3425
+ return;
3426
+ }
3427
+ if (!controller.meta && !controller.error) {
3428
+ return;
3429
+ }
3430
+ if (controller.meta && controller.meta.slug !== slug) {
3431
+ return;
3432
+ }
3433
+ finishPendingNavigation(location.pathname);
3434
+ }, [controller.error, controller.isLoading, controller.meta, finishPendingNavigation, location.pathname, pendingPath, slug]);
3405
3435
  useAdminDocumentTitle(t("admin_title"), (_b = (_a = controller.meta) == null ? void 0 : _a.title) != null ? _b : slug);
3406
3436
  if (!controller.isLoading && controller.error && !controller.data) {
3407
3437
  return /* @__PURE__ */ jsx20(Alert5, { severity: "error", children: controller.error });
@@ -3826,6 +3856,7 @@ function resolveFieldSortable(field) {
3826
3856
  }
3827
3857
 
3828
3858
  // src/components/ObjectPage.tsx
3859
+ import { useLayoutEffect as useLayoutEffect5 } from "react";
3829
3860
  import ArrowBackIcon from "@mui/icons-material/ArrowBack";
3830
3861
  import MoreVertIcon2 from "@mui/icons-material/MoreVert";
3831
3862
  import { Alert as Alert6, Box as Box13, Button as Button5, IconButton as IconButton4, Menu as Menu2, MenuItem as MenuItem3, Paper as Paper9, Stack as Stack13, Typography as Typography7, useMediaQuery as useMediaQuery3 } from "@mui/material";
@@ -3943,7 +3974,7 @@ var ReadonlyObjectField = memo7(function ReadonlyObjectField2({
3943
3974
  });
3944
3975
 
3945
3976
  // src/components/object-page/useObjectPageController.ts
3946
- import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo10, useState as useState11 } from "react";
3977
+ import { useCallback as useCallback7, useLayoutEffect as useLayoutEffect4, useMemo as useMemo10, useState as useState11 } from "react";
3947
3978
 
3948
3979
  // src/utils/isDeepEqual.ts
3949
3980
  function isDeepEqual(left, right) {
@@ -4007,7 +4038,7 @@ function useObjectPageController({
4007
4038
  const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState11(false);
4008
4039
  const [deletePreviewError, setDeletePreviewError] = useState11(null);
4009
4040
  const [actionsAnchorEl, setActionsAnchorEl] = useState11(null);
4010
- useEffect11(() => {
4041
+ useLayoutEffect4(() => {
4011
4042
  var _a2;
4012
4043
  let isMounted = true;
4013
4044
  const bucket = getClientCacheBucket(client);
@@ -4224,6 +4255,7 @@ function ObjectPage({ client, slug, id, router }) {
4224
4255
  const pathname = location.pathname;
4225
4256
  const theme = useTheme4();
4226
4257
  const isPhone = useMediaQuery3(theme.breakpoints.down("sm"));
4258
+ const { pendingPath, finishPendingNavigation } = useShellContext();
4227
4259
  const listPath = pathname.split("/").slice(0, -1).join("/");
4228
4260
  const controller = useObjectPageController({
4229
4261
  client,
@@ -4233,6 +4265,21 @@ function ObjectPage({ client, slug, id, router }) {
4233
4265
  router: resolvedRouter,
4234
4266
  t
4235
4267
  });
4268
+ useLayoutEffect5(() => {
4269
+ if (pendingPath === null) {
4270
+ return;
4271
+ }
4272
+ if (controller.isLoading) {
4273
+ return;
4274
+ }
4275
+ if (!controller.meta && !controller.error) {
4276
+ return;
4277
+ }
4278
+ if (controller.meta && controller.meta.slug !== slug) {
4279
+ return;
4280
+ }
4281
+ finishPendingNavigation(pathname);
4282
+ }, [controller.error, controller.isLoading, controller.meta, finishPendingNavigation, pathname, pendingPath, slug]);
4236
4283
  useAdminDocumentTitle(t("admin_title"), (_b = (_a = controller.meta) == null ? void 0 : _a.title) != null ? _b : slug, controller.objectTitle);
4237
4284
  if (controller.isLoading && !controller.data) {
4238
4285
  return /* @__PURE__ */ jsx24(ObjectPageSkeleton, {});
@@ -4450,7 +4497,7 @@ function ObjectPage({ client, slug, id, router }) {
4450
4497
  }
4451
4498
 
4452
4499
  // src/components/Shell.tsx
4453
- import { useEffect as useEffect12, useMemo as useMemo11, useState as useState12 } from "react";
4500
+ import { useEffect as useEffect11, useMemo as useMemo11, useState as useState12 } from "react";
4454
4501
  import { Box as Box16, CssBaseline, Drawer, GlobalStyles, Stack as Stack14, useMediaQuery as useMediaQuery4 } from "@mui/material";
4455
4502
  import { ThemeProvider } from "@mui/material/styles";
4456
4503
 
@@ -4585,13 +4632,9 @@ var defaultAdminTheme = createTheme({
4585
4632
  import { Box as Box14 } from "@mui/material";
4586
4633
  import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
4587
4634
  function Main({ children }) {
4588
- const { pathname } = useAdminLocation();
4635
+ useAdminLocation();
4589
4636
  const { pendingPath, pendingView } = useShellContext();
4590
- const normalizeAdminPath2 = (path) => {
4591
- const normalizedPath = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
4592
- return normalizedPath.replace(/^\/(ru|en)(?=\/|$)/, "") || "/";
4593
- };
4594
- const isPendingNavigation = pendingPath !== null && normalizeAdminPath2(pathname) !== normalizeAdminPath2(pendingPath);
4637
+ const isPendingNavigation = pendingPath !== null;
4595
4638
  return /* @__PURE__ */ jsxs17(
4596
4639
  Box14,
4597
4640
  {
@@ -4708,23 +4751,14 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4708
4751
  const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState12(false);
4709
4752
  const [pendingPath, setPendingPath] = useState12(null);
4710
4753
  const [pendingView, setPendingView] = useState12(null);
4711
- useEffect12(() => {
4754
+ useEffect11(() => {
4712
4755
  if (isDesktopSidebar) {
4713
4756
  setIsMobileSidebarOpen(false);
4714
4757
  }
4715
4758
  }, [isDesktopSidebar]);
4716
- useEffect12(() => {
4759
+ useEffect11(() => {
4717
4760
  setIsMobileSidebarOpen(false);
4718
4761
  }, [pathname]);
4719
- useEffect12(() => {
4720
- if (pendingPath === null) {
4721
- return;
4722
- }
4723
- if (normalizeAdminPath(pathname) === normalizeAdminPath(pendingPath)) {
4724
- setPendingPath(null);
4725
- setPendingView(null);
4726
- }
4727
- }, [pathname, pendingPath]);
4728
4762
  const shellContextValue = useMemo11(() => ({
4729
4763
  isMobile: !isDesktopSidebar,
4730
4764
  openMobileSidebar: () => setIsMobileSidebarOpen(true),
@@ -4736,6 +4770,16 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4736
4770
  }
4737
4771
  setPendingPath(path);
4738
4772
  setPendingView(view);
4773
+ },
4774
+ finishPendingNavigation: (path) => {
4775
+ if (pendingPath === null) {
4776
+ return;
4777
+ }
4778
+ if (path && normalizeAdminPath(path) !== normalizeAdminPath(pendingPath)) {
4779
+ return;
4780
+ }
4781
+ setPendingPath(null);
4782
+ setPendingView(null);
4739
4783
  }
4740
4784
  }), [isDesktopSidebar, pathname, pendingPath, pendingView]);
4741
4785
  return /* @__PURE__ */ jsx27(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsx27(ThemeProvider, { theme: activeTheme, children: /* @__PURE__ */ jsx27(AdminLocaleProvider, { locale, children: /* @__PURE__ */ jsx27(AdminDataProvider, { value: { locale: locale === "en" ? "en" : "ru", models, blocks }, children: /* @__PURE__ */ jsx27(ShellContextProvider, { value: shellContextValue, children: /* @__PURE__ */ jsxs19(AdminMessageProvider, { children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xladmin",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Framework-agnostic React + MUI admin frontend for xladmin.",
5
5
  "license": "MIT",
6
6
  "type": "module",