@localazy/strapi-plugin 1.3.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +30 -0
  2. package/dist/_chunks/{FetchIdentity-BJGoZPpM.mjs → FetchIdentity-Bm7bc5bS.mjs} +36 -44
  3. package/dist/_chunks/{FetchIdentity-CtBRO-Cn.js → FetchIdentity-CcEjakiz.js} +25 -33
  4. package/dist/_chunks/{LanguagesSelector-DJxgCwgM.mjs → LanguagesSelector-B1rwN7-Y.mjs} +4 -3
  5. package/dist/_chunks/{LanguagesSelector-CNaKrS-m.js → LanguagesSelector-DejYCwBl.js} +4 -3
  6. package/dist/_chunks/{LocalazyApp-CJRpsTKr.mjs → LocalazyApp-C4kbsnQh.mjs} +148 -35
  7. package/dist/_chunks/{LocalazyApp-B1qCCEPe.js → LocalazyApp-jPO7Yr1S.js} +154 -41
  8. package/dist/_chunks/{LocalazyContentTransferSetup-CLAWn95U.mjs → LocalazyContentTransferSetup-C1wDD9hA.mjs} +58 -22
  9. package/dist/_chunks/{LocalazyContentTransferSetup-CCxiLHdG.js → LocalazyContentTransferSetup-DZh4ZdSi.js} +63 -27
  10. package/dist/_chunks/{LocalazyGlobalSettings-BJ5qfFfK.js → LocalazyGlobalSettings-D76it6rn.js} +57 -26
  11. package/dist/_chunks/{LocalazyGlobalSettings-Z-4Ykc_J.mjs → LocalazyGlobalSettings-DOW5rjLn.mjs} +56 -25
  12. package/dist/_chunks/{LocalazyPanel-CL_mzzfD.mjs → LocalazyPanel-C_Z4W49T.mjs} +12 -6
  13. package/dist/_chunks/{LocalazyPanel-DE3TtHOQ.js → LocalazyPanel-D2LQpqii.js} +14 -8
  14. package/dist/_chunks/{LocalazyStatusColumn-R5n6q_cx.mjs → LocalazyStatusColumn-C_ZCd_s7.mjs} +10 -4
  15. package/dist/_chunks/{LocalazyStatusColumn-BMLcklG-.js → LocalazyStatusColumn-Dy6N4_X6.js} +10 -4
  16. package/dist/_chunks/{RequireLocalazyAuth-WKKFdQlR.js → RequireLocalazyAuth-BVwF0bRC.js} +31 -4
  17. package/dist/_chunks/{RequireLocalazyAuth-Dzsu6UNS.mjs → RequireLocalazyAuth-DNhTZZ_6.mjs} +32 -5
  18. package/dist/_chunks/{entry-exclusion-service-DxqTlZFR.mjs → entry-exclusion-service-CF_yNCly.mjs} +1 -1
  19. package/dist/_chunks/{entry-exclusion-service-CggmAKxq.js → entry-exclusion-service-CH3ZoJQN.js} +1 -1
  20. package/dist/_chunks/{has-model-changed-FMGVcFHU.mjs → has-model-changed-CVJEuGxM.mjs} +2 -2
  21. package/dist/_chunks/{has-model-changed-BR53L6pA.js → has-model-changed-DdYbyv0v.js} +2 -2
  22. package/dist/_chunks/{i18n-QelOdIB2.mjs → i18n-76ox2llT.mjs} +9 -2
  23. package/dist/_chunks/{i18n-CAsbU4pi.js → i18n-C5ucROBh.js} +9 -2
  24. package/dist/_chunks/{index-BmxGKspv.js → index-CEGaWWh3.js} +33 -11
  25. package/dist/_chunks/{index-BK7lmZSN.js → index-CTkxoioB.js} +1 -0
  26. package/dist/_chunks/{index-toauQlIK.mjs → index-DP2ugzc_.mjs} +34 -12
  27. package/dist/_chunks/{index-CHjIMO9T.mjs → index-shryj0jT.mjs} +19 -18
  28. package/dist/_chunks/{strapi-api-base-CT9lknwW.js → strapi-api-base-CCUuu7EY.js} +1 -1
  29. package/dist/_chunks/{strapi-api-base-BflplVsH.mjs → strapi-api-base-IiMEtDoH.mjs} +1 -1
  30. package/dist/admin/index.js +1 -1
  31. package/dist/admin/index.mjs +1 -1
  32. package/dist/admin/src/components/LocalazyStatusColumn.d.ts +1 -1
  33. package/dist/admin/src/constants/permissions.d.ts +29 -0
  34. package/dist/admin/src/modules/@common/components/LanguagesSelector.d.ts +1 -0
  35. package/dist/admin/src/modules/activity-logs/locale/en.d.ts +4 -0
  36. package/dist/admin/src/modules/activity-logs/services/debug-bundle-service.d.ts +10 -0
  37. package/dist/admin/src/modules/login/locale/en.d.ts +1 -0
  38. package/dist/admin/src/modules/plugin-settings/components/Tree.d.ts +1 -0
  39. package/dist/admin/src/modules/plugin-settings/components/TreeItem.d.ts +1 -0
  40. package/dist/admin/src/modules/plugin-settings/components/WebhookSetup.d.ts +4 -1
  41. package/dist/admin/src/modules/plugin-settings/locale/en.d.ts +2 -0
  42. package/dist/admin/src/modules/plugin-settings/services/plugin-settings-service.d.ts +4 -0
  43. package/dist/server/index.js +665 -38
  44. package/dist/server/index.mjs +665 -39
  45. package/dist/server/src/bootstrap.d.ts +1 -1
  46. package/dist/server/src/constants/permissions.d.ts +38 -0
  47. package/dist/server/src/controllers/debug-bundle-controller.d.ts +7 -0
  48. package/dist/server/src/controllers/index.d.ts +6 -0
  49. package/dist/server/src/controllers/plugin-settings-controller.d.ts +1 -0
  50. package/dist/server/src/core/index.d.ts +5 -1
  51. package/dist/server/src/db/model/activity-logs.d.ts +10 -0
  52. package/dist/server/src/index.d.ts +64 -8
  53. package/dist/server/src/routes/activity-logs-routes.d.ts +20 -3
  54. package/dist/server/src/routes/debug-bundle-routes.d.ts +14 -0
  55. package/dist/server/src/routes/entry-exclusion-routes.d.ts +20 -3
  56. package/dist/server/src/routes/index.d.ts +52 -6
  57. package/dist/server/src/routes/localazy-auth-routes.d.ts +6 -1
  58. package/dist/server/src/routes/localazy-project-routes.d.ts +20 -3
  59. package/dist/server/src/routes/localazy-transfer-routes.d.ts +6 -1
  60. package/dist/server/src/routes/localazy-user-routes.d.ts +20 -3
  61. package/dist/server/src/routes/plugin-settings-routes.d.ts +20 -3
  62. package/dist/server/src/routes/strapi-routes.d.ts +20 -3
  63. package/dist/server/src/services/activity-logs-service.d.ts +3 -1
  64. package/dist/server/src/services/index.d.ts +5 -1
  65. package/dist/server/src/services/localazy-transfer-download-service.d.ts +2 -1
  66. package/dist/server/src/services/plugin-settings-service.d.ts +4 -0
  67. package/dist/server/src/utils/build-debug-bundle.d.ts +68 -0
  68. package/dist/server/src/utils/sanitize-debug-bundle.d.ts +25 -0
  69. package/package.json +2 -1
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const reactRouterDom = require("react-router-dom");
5
- const index$1 = require("./index-BK7lmZSN.js");
5
+ const index$1 = require("./index-CTkxoioB.js");
6
6
  const React = require("react");
7
- const FetchIdentity = require("./FetchIdentity-CtBRO-Cn.js");
8
- const index = require("./index-BmxGKspv.js");
7
+ const FetchIdentity = require("./FetchIdentity-CcEjakiz.js");
8
+ const index = require("./index-CEGaWWh3.js");
9
9
  const useTranslation = require("./useTranslation-BdIl-aLe.js");
10
10
  const _commonjsHelpers = require("./_commonjsHelpers-Bc2YnDe1.js");
11
- const strapiApiBase = require("./strapi-api-base-CT9lknwW.js");
12
- const LanguagesSelector = require("./LanguagesSelector-CNaKrS-m.js");
13
11
  const admin = require("@strapi/strapi/admin");
14
- require("./i18n-CAsbU4pi.js");
15
- const hasModelChanged = require("./has-model-changed-BR53L6pA.js");
12
+ const strapiApiBase = require("./strapi-api-base-CCUuu7EY.js");
13
+ const LanguagesSelector = require("./LanguagesSelector-DejYCwBl.js");
14
+ require("./i18n-C5ucROBh.js");
15
+ const hasModelChanged = require("./has-model-changed-DdYbyv0v.js");
16
16
  const styled = require("styled-components");
17
17
  const _interopDefault = (e2) => e2 && e2.__esModule ? e2 : { default: e2 };
18
18
  const React__default = /* @__PURE__ */ _interopDefault(React);
@@ -102,10 +102,6 @@ const useHeaderSubtitle = () => {
102
102
  const currentNavItem = navigation.find((navItem) => pluginSegment.includes(navItem.id));
103
103
  return currentNavItem?.description || "";
104
104
  };
105
- function PluginPageLoader() {
106
- const { t: t2 } = useTranslation.useTranslation();
107
- return /* @__PURE__ */ jsxRuntime.jsx(index$1.Flex, { marginTop: 10, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Loader, { children: t2("common.loading_content") }) });
108
- }
109
105
  var propTypes = { exports: {} };
110
106
  var reactIs = { exports: {} };
111
107
  var reactIs_production_min = {};
@@ -1262,6 +1258,8 @@ if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development") {
1262
1258
  }
1263
1259
  const LoginButton = (props) => {
1264
1260
  const { t: t2 } = useTranslation.useTranslation();
1261
+ const { allowedActions } = admin.useRBAC(index.PERMISSIONS.SETTINGS_UPDATE);
1262
+ const canConnect = !!allowedActions.canUpdate;
1265
1263
  const [isLoading, setIsLoading] = React.useState(false);
1266
1264
  const login = async () => {
1267
1265
  setIsLoading(true);
@@ -1282,7 +1280,8 @@ const LoginButton = (props) => {
1282
1280
  setIsLoading(false);
1283
1281
  props.onResultFetched(pollResult);
1284
1282
  };
1285
- return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { variant: "default", size: "L", loading: isLoading, onClick: login, children: t2("login.login_with_localazy") }) });
1283
+ const button = /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { variant: "default", size: "L", loading: isLoading, onClick: login, disabled: !canConnect, children: t2("login.login_with_localazy") });
1284
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: canConnect ? button : /* @__PURE__ */ jsxRuntime.jsx(index$1.TooltipImpl, { label: t2("login.requires_settings_update_permission"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: button }) }) });
1286
1285
  };
1287
1286
  LoginButton.propTypes = {
1288
1287
  onResultFetched: PropTypes.func.isRequired
@@ -1396,7 +1395,7 @@ const Login = ({ title, subtitle, isLoading = false }) => {
1396
1395
  }, [isLoggedIn, identity]);
1397
1396
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1398
1397
  /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Header, { title, subtitle, as: "h1" }),
1399
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
1398
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
1400
1399
  !isLoading && /* @__PURE__ */ jsxRuntime.jsxs(
1401
1400
  index$1.Box,
1402
1401
  {
@@ -1440,6 +1439,8 @@ const LogoutButton = (props) => {
1440
1439
  const { t: t2 } = useTranslation.useTranslation();
1441
1440
  const [isLoading, setIsLoading] = React.useState(false);
1442
1441
  const { setIdentity } = FetchIdentity.useLocalazyIdentity();
1442
+ const { allowedActions } = admin.useRBAC(index.PERMISSIONS.SETTINGS_UPDATE);
1443
+ const canDisconnect = !!allowedActions.canUpdate;
1443
1444
  const logout = async () => {
1444
1445
  setIsLoading(true);
1445
1446
  void FetchIdentity.LocalazyUserService.deleteIdentity();
@@ -1447,7 +1448,8 @@ const LogoutButton = (props) => {
1447
1448
  setIsLoading(false);
1448
1449
  props.onResultFetched();
1449
1450
  };
1450
- return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$L, {}), variant: "secondary", loading: isLoading, onClick: logout, children: t2("login.logout_from_localazy") }) });
1451
+ const button = /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$L, {}), variant: "secondary", loading: isLoading, onClick: logout, disabled: !canDisconnect, children: t2("login.logout_from_localazy") });
1452
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: canDisconnect ? button : /* @__PURE__ */ jsxRuntime.jsx(index$1.TooltipImpl, { label: t2("login.requires_settings_update_permission"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: button }) }) });
1451
1453
  };
1452
1454
  const OverviewItem = (props) => {
1453
1455
  return /* @__PURE__ */ jsxRuntime.jsxs(index$1.Grid.Root, { padding: 1, col: 6, s: 12, children: [
@@ -1478,7 +1480,7 @@ const Overview = ({ title, subtitle, isLoadingProp = false }) => {
1478
1480
  setIsLoading(true);
1479
1481
  const project = await LanguagesSelector.ProjectService.getConnectedProject();
1480
1482
  setConnectedProject(project);
1481
- void FetchIdentity.PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.OVERVIEW });
1483
+ void FetchIdentity.PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.OVERVIEW });
1482
1484
  setIsLoading(false);
1483
1485
  }
1484
1486
  void initComponent();
@@ -1496,7 +1498,7 @@ const Overview = ({ title, subtitle, isLoadingProp = false }) => {
1496
1498
  primaryAction: /* @__PURE__ */ jsxRuntime.jsx(LogoutButton, { onResultFetched: onLoggedOut })
1497
1499
  }
1498
1500
  ),
1499
- (isLoadingProp || isLoading) && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
1501
+ (isLoadingProp || isLoading) && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
1500
1502
  !(isLoadingProp || isLoading) && /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: /* @__PURE__ */ jsxRuntime.jsxs(
1501
1503
  index$1.Box,
1502
1504
  {
@@ -5065,7 +5067,7 @@ const Upload = (props) => {
5065
5067
  setLocalazySourceLanguage(sourceLanguage);
5066
5068
  setModelChanged(modelChangedResult);
5067
5069
  setLocalesIncompatible(!localesCompatibleResult);
5068
- void FetchIdentity.PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.UPLOAD });
5070
+ void FetchIdentity.PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.UPLOAD });
5069
5071
  setIsLoading(false);
5070
5072
  }
5071
5073
  void initComponent();
@@ -5088,7 +5090,7 @@ const Upload = (props) => {
5088
5090
  )
5089
5091
  }
5090
5092
  ),
5091
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
5093
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
5092
5094
  !isLoading && /* @__PURE__ */ jsxRuntime.jsxs(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: [
5093
5095
  /* @__PURE__ */ jsxRuntime.jsxs(
5094
5096
  index$1.Box,
@@ -5198,16 +5200,9 @@ const Download = (props) => {
5198
5200
  window.open(identity.project.url, "_blank");
5199
5201
  };
5200
5202
  const [projectLanguages, setProjectLanguages] = React.useState([]);
5201
- const [formModel, setFormModel] = React.useState({});
5203
+ const [uiLanguages, setUiLanguages] = React.useState([]);
5202
5204
  const onDownloadLanguagesChange = (languages) => {
5203
- const newFormModel = FetchIdentity.cloneDeep(formModel);
5204
- FetchIdentity.set(newFormModel, "download.uiLanguages", languages);
5205
- setFormModel(newFormModel);
5206
- try {
5207
- void FetchIdentity.PluginSettingsService.updatePluginSettings(newFormModel);
5208
- } catch (e2) {
5209
- console.error(e2.message);
5210
- }
5205
+ setUiLanguages(languages);
5211
5206
  };
5212
5207
  const onDownloadClick = async (fullSync = false) => {
5213
5208
  setIsDownloading(true);
@@ -5216,7 +5211,7 @@ const Download = (props) => {
5216
5211
  success: false,
5217
5212
  report: []
5218
5213
  });
5219
- const result = await LocalazyDownloadService.download({ fullSync });
5214
+ const result = await LocalazyDownloadService.download({ fullSync, uiLanguages });
5220
5215
  const { streamIdentifier } = result;
5221
5216
  downloadAlertsService.setStreamIdentifier(streamIdentifier);
5222
5217
  downloadAlertsService.onDownload((data) => {
@@ -5257,8 +5252,8 @@ const Download = (props) => {
5257
5252
  setHasSyncCursor(syncCursor?.processedKeys !== void 0 && Object.keys(syncCursor.processedKeys).length > 0);
5258
5253
  const projectLanguagesWithoutDefaultLanguage = project?.languages?.filter((language) => language.id !== project.sourceLanguage) || [];
5259
5254
  setProjectLanguages(projectLanguagesWithoutDefaultLanguage);
5260
- setFormModel(globalSettings);
5261
- void FetchIdentity.PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.DOWNLOAD });
5255
+ setUiLanguages(Array.isArray(globalSettings?.download?.uiLanguages) ? globalSettings.download.uiLanguages : []);
5256
+ void FetchIdentity.PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.DOWNLOAD });
5262
5257
  setIsLoading(false);
5263
5258
  }
5264
5259
  void initComponent();
@@ -5293,7 +5288,7 @@ const Download = (props) => {
5293
5288
  ] })
5294
5289
  }
5295
5290
  ),
5296
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
5291
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
5297
5292
  !isLoading && /* @__PURE__ */ jsxRuntime.jsxs(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: [
5298
5293
  /* @__PURE__ */ jsxRuntime.jsxs(
5299
5294
  index$1.Box,
@@ -5316,7 +5311,7 @@ const Download = (props) => {
5316
5311
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
5317
5312
  LanguagesSelector.LanguagesSelector,
5318
5313
  {
5319
- preselectedLanguages: formModel?.download?.uiLanguages || [],
5314
+ preselectedLanguages: uiLanguages,
5320
5315
  projectLanguages,
5321
5316
  onChange: (languages) => onDownloadLanguagesChange(languages),
5322
5317
  label: t2("download.ui_languages"),
@@ -5693,6 +5688,9 @@ const useDebouncedSearch = () => {
5693
5688
  const ActivityLogs = (props) => {
5694
5689
  const { t: t2 } = useTranslation.useTranslation();
5695
5690
  const navigate = reactRouterDom.useNavigate();
5691
+ const {
5692
+ allowedActions: { canTransfer }
5693
+ } = admin.useRBAC(index.PERMISSIONS.TRANSFER);
5696
5694
  const [isLoading, setIsLoading] = React.useState(true);
5697
5695
  const [sessions, setSessions] = React.useState([]);
5698
5696
  const [activeTab, setActiveTab] = React.useState("upload");
@@ -5706,7 +5704,7 @@ const ActivityLogs = (props) => {
5706
5704
  const debouncedSaveSortPrefs = React.useCallback((prefs) => {
5707
5705
  if (saveSortTimerRef.current) clearTimeout(saveSortTimerRef.current);
5708
5706
  saveSortTimerRef.current = setTimeout(() => {
5709
- void FetchIdentity.PluginSettingsService.updatePluginSettings({ activityLogsSort: prefs });
5707
+ void FetchIdentity.PluginSettingsService.updatePluginSettingsUiPrefs({ activityLogsSort: prefs });
5710
5708
  }, 1e3);
5711
5709
  }, []);
5712
5710
  const onSortChange = (eventType, key, direction) => {
@@ -5762,7 +5760,7 @@ const ActivityLogs = (props) => {
5762
5760
  void fetchSessions("upload");
5763
5761
  };
5764
5762
  void init();
5765
- void FetchIdentity.PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.ACTIVITY_LOGS });
5763
+ void FetchIdentity.PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.ACTIVITY_LOGS });
5766
5764
  }, []);
5767
5765
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5768
5766
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5772,7 +5770,16 @@ const ActivityLogs = (props) => {
5772
5770
  subtitle: props.subtitle,
5773
5771
  primaryAction: /* @__PURE__ */ jsxRuntime.jsxs(index$1.Flex, { gap: 2, children: [
5774
5772
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$3P, {}), onClick: onExportLogs, children: t2("activity_logs.export_logs") }),
5775
- /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { variant: "danger-light", startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$j, {}), onClick: () => setShowClearConfirm(true), children: t2("activity_logs.clear_logs") })
5773
+ /* @__PURE__ */ jsxRuntime.jsx(
5774
+ index$1.Button,
5775
+ {
5776
+ variant: "danger-light",
5777
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$j, {}),
5778
+ disabled: !canTransfer,
5779
+ onClick: () => setShowClearConfirm(true),
5780
+ children: t2("activity_logs.clear_logs")
5781
+ }
5782
+ )
5776
5783
  ] })
5777
5784
  }
5778
5785
  ),
@@ -5780,7 +5787,7 @@ const ActivityLogs = (props) => {
5780
5787
  /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$2x, { width: 14, height: 14, fill: "neutral500" }),
5781
5788
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "pi", textColor: "neutral500", children: t2("activity_logs.retention_info") })
5782
5789
  ] }) }),
5783
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
5790
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
5784
5791
  !isLoading && /* @__PURE__ */ jsxRuntime.jsxs(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: [
5785
5792
  clearSuccess && /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Alert, { onClose: () => setClearSuccess(false), closeLabel: t2("activity_logs.close"), variant: "success", children: t2("activity_logs.clear_logs_success") }) }),
5786
5793
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -5901,6 +5908,45 @@ const ActivityLogs = (props) => {
5901
5908
  ] }) })
5902
5909
  ] });
5903
5910
  };
5911
+ const LOCALAZY_HEADER = { "X-Localazy-Initiated-By": "strapi-plugin-localazy" };
5912
+ const fallbackFilename = (sessionId) => `localazy-debug-bundle-${sessionId.slice(0, 8)}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.zip`;
5913
+ const parseFilenameFromContentDisposition = (header) => {
5914
+ if (!header) return null;
5915
+ const match = /filename="?([^";]+)"?/i.exec(header);
5916
+ return match ? match[1] : null;
5917
+ };
5918
+ const triggerBrowserDownload = (blob, filename) => {
5919
+ const url2 = URL.createObjectURL(blob);
5920
+ const a2 = document.createElement("a");
5921
+ a2.href = url2;
5922
+ a2.download = filename;
5923
+ document.body.appendChild(a2);
5924
+ a2.click();
5925
+ document.body.removeChild(a2);
5926
+ setTimeout(() => URL.revokeObjectURL(url2), 3e4);
5927
+ };
5928
+ const downloadDebugBundle = async (sessionId, token, browserInfo) => {
5929
+ const backendURL = window.strapi?.backendURL ?? "";
5930
+ const encodedBrowser = btoa(unescape(encodeURIComponent(JSON.stringify(browserInfo))));
5931
+ const url2 = `${backendURL}/${index.PLUGIN_ID}/activity-logs/${encodeURIComponent(sessionId)}/bundle?browser=${encodeURIComponent(encodedBrowser)}`;
5932
+ const headers = { ...LOCALAZY_HEADER };
5933
+ if (token) {
5934
+ headers.Authorization = `Bearer ${token}`;
5935
+ }
5936
+ const response = await fetch(url2, { method: "GET", headers });
5937
+ if (!response.ok) {
5938
+ let detail = `${response.status} ${response.statusText}`;
5939
+ try {
5940
+ const text = await response.text();
5941
+ if (text) detail = `${detail} — ${text.slice(0, 200)}`;
5942
+ } catch {
5943
+ }
5944
+ throw new Error(`Failed to download debug bundle: ${detail}`);
5945
+ }
5946
+ const blob = await response.blob();
5947
+ const filename = parseFilenameFromContentDisposition(response.headers.get("content-disposition")) ?? fallbackFilename(sessionId);
5948
+ triggerBrowserDownload(blob, filename);
5949
+ };
5904
5950
  const SessionMetadata = ({ session, showEntryCount }) => {
5905
5951
  const { t: t2 } = useTranslation.useTranslation();
5906
5952
  return /* @__PURE__ */ jsxRuntime.jsxs(index$1.Flex, { gap: 6, wrap: "wrap", children: [
@@ -5935,8 +5981,11 @@ const ActivityLogDetail = (props) => {
5935
5981
  const { t: t2 } = useTranslation.useTranslation();
5936
5982
  const theme = styled.useTheme();
5937
5983
  const { sessionId } = reactRouterDom.useParams();
5984
+ const token = admin.useAuth("ActivityLogDetail", (state) => state.token);
5985
+ const { toggleNotification } = admin.useNotification();
5938
5986
  const [isLoading, setIsLoading] = React.useState(true);
5939
5987
  const [session, setSession] = React.useState(null);
5988
+ const [isBuildingBundle, setIsBuildingBundle] = React.useState(false);
5940
5989
  const { searchInput, searchQuery, onSearchChange } = useDebouncedSearch();
5941
5990
  React.useEffect(() => {
5942
5991
  const fetchSession = async () => {
@@ -5952,6 +6001,30 @@ const ActivityLogDetail = (props) => {
5952
6001
  };
5953
6002
  void fetchSession();
5954
6003
  }, [sessionId]);
6004
+ const onDownloadBundle = async () => {
6005
+ if (!sessionId || isBuildingBundle) return;
6006
+ setIsBuildingBundle(true);
6007
+ try {
6008
+ await downloadDebugBundle(sessionId, token, {
6009
+ userAgent: navigator.userAgent,
6010
+ language: navigator.language,
6011
+ viewport: { width: window.innerWidth, height: window.innerHeight }
6012
+ });
6013
+ toggleNotification({
6014
+ type: "success",
6015
+ message: t2("activity_logs.download_bundle_success"),
6016
+ timeout: 5e3
6017
+ });
6018
+ } catch (e2) {
6019
+ console.error("Failed to build debug bundle:", e2);
6020
+ toggleNotification({
6021
+ type: "danger",
6022
+ message: t2("activity_logs.download_bundle_error")
6023
+ });
6024
+ } finally {
6025
+ setIsBuildingBundle(false);
6026
+ }
6027
+ };
5955
6028
  const filteredEntries = (session?.entries || []).filter((entry) => {
5956
6029
  if (!searchQuery) return true;
5957
6030
  const query = searchQuery.toLowerCase();
@@ -5963,10 +6036,21 @@ const ActivityLogDetail = (props) => {
5963
6036
  {
5964
6037
  title: props.title,
5965
6038
  subtitle: props.subtitle,
5966
- navigationAction: /* @__PURE__ */ jsxRuntime.jsx(index$1.Link, { tag: reactRouterDom.NavLink, to: `/plugins/${index.PLUGIN_ID}/activity-logs`, startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$57, {}), children: t2("activity_logs.back_to_list") })
6039
+ navigationAction: /* @__PURE__ */ jsxRuntime.jsx(index$1.Link, { tag: reactRouterDom.NavLink, to: `/plugins/${index.PLUGIN_ID}/activity-logs`, startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$57, {}), children: t2("activity_logs.back_to_list") }),
6040
+ primaryAction: /* @__PURE__ */ jsxRuntime.jsx(index$1.TooltipImpl, { label: t2("activity_logs.download_bundle_warning"), children: /* @__PURE__ */ jsxRuntime.jsx(
6041
+ index$1.Button,
6042
+ {
6043
+ variant: "secondary",
6044
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$3P, {}),
6045
+ onClick: onDownloadBundle,
6046
+ loading: isBuildingBundle,
6047
+ disabled: !session || isBuildingBundle,
6048
+ children: t2("activity_logs.download_bundle")
6049
+ }
6050
+ ) })
5967
6051
  }
5968
6052
  ),
5969
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
6053
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
5970
6054
  !isLoading && !session && /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "omega", children: t2("activity_logs.no_sessions") }) }),
5971
6055
  !isLoading && session && /* @__PURE__ */ jsxRuntime.jsxs(index$1.Box, { paddingRight: 10, paddingLeft: 10, children: [
5972
6056
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6063,6 +6147,10 @@ const App = () => {
6063
6147
  const { isLoggedIn, isFetchingIdentity } = FetchIdentity.useLocalazyIdentity();
6064
6148
  const headerTitle = useHeaderTitle();
6065
6149
  const headerSubtitle = useHeaderSubtitle();
6150
+ const {
6151
+ allowedActions: { canRead, canTransfer },
6152
+ isLoading: isLoadingPermissions
6153
+ } = admin.useRBAC([...index.PERMISSIONS.READ, ...index.PERMISSIONS.TRANSFER]);
6066
6154
  const normalizedPath = location2.pathname.replace(/\/+$/, "");
6067
6155
  const pluginRoot = `/plugins/${index.PLUGIN_ID}`;
6068
6156
  const isAtPluginRoot = normalizedPath === pluginRoot;
@@ -6084,10 +6172,23 @@ const App = () => {
6084
6172
  };
6085
6173
  void fetchData();
6086
6174
  }, [isLoggedIn, isFetchingIdentity, normalizedPath]);
6175
+ if (isLoadingPermissions) {
6176
+ return /* @__PURE__ */ jsxRuntime.jsxs(index$1.DesignSystemProvider, { theme: FetchIdentity.getDefaultTheme(), children: [
6177
+ /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.HeadingFixGlobalStyle, {}),
6178
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { background: "neutral100", children: /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}) }) })
6179
+ ] });
6180
+ }
6181
+ if (!canRead) {
6182
+ return /* @__PURE__ */ jsxRuntime.jsxs(index$1.DesignSystemProvider, { theme: FetchIdentity.getDefaultTheme(), children: [
6183
+ /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.HeadingFixGlobalStyle, {}),
6184
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { background: "neutral100", children: /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(admin.Page.NoPermissions, {}) }) })
6185
+ ] });
6186
+ }
6187
+ const transferElement = (page) => canTransfer ? page : /* @__PURE__ */ jsxRuntime.jsx(admin.Page.NoPermissions, {});
6087
6188
  return /* @__PURE__ */ jsxRuntime.jsxs(index$1.DesignSystemProvider, { theme: FetchIdentity.getDefaultTheme(), children: [
6088
6189
  /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.HeadingFixGlobalStyle, {}),
6089
6190
  /* @__PURE__ */ jsxRuntime.jsx(PluginErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { background: "neutral100", children: /* @__PURE__ */ jsxRuntime.jsxs(admin.Layouts.Root, { sideNav: isLoggedIn && /* @__PURE__ */ jsxRuntime.jsx(SideNav, {}), children: [
6090
- isFetchingIdentity && /* @__PURE__ */ jsxRuntime.jsx(PluginPageLoader, {}),
6191
+ isFetchingIdentity && /* @__PURE__ */ jsxRuntime.jsx(FetchIdentity.PluginPageLoader, {}),
6091
6192
  /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
6092
6193
  /* @__PURE__ */ jsxRuntime.jsx(
6093
6194
  reactRouterDom.Route,
@@ -6103,8 +6204,20 @@ const App = () => {
6103
6204
  element: /* @__PURE__ */ jsxRuntime.jsx(Overview, { title: headerTitle, subtitle: headerSubtitle, isLoadingProp: false })
6104
6205
  }
6105
6206
  ),
6106
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: `upload`, element: /* @__PURE__ */ jsxRuntime.jsx(Upload, { title: headerTitle, subtitle: headerSubtitle }) }),
6107
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: `download`, element: /* @__PURE__ */ jsxRuntime.jsx(Download, { title: headerTitle, subtitle: headerSubtitle }) }),
6207
+ /* @__PURE__ */ jsxRuntime.jsx(
6208
+ reactRouterDom.Route,
6209
+ {
6210
+ path: `upload`,
6211
+ element: transferElement(/* @__PURE__ */ jsxRuntime.jsx(Upload, { title: headerTitle, subtitle: headerSubtitle }))
6212
+ }
6213
+ ),
6214
+ /* @__PURE__ */ jsxRuntime.jsx(
6215
+ reactRouterDom.Route,
6216
+ {
6217
+ path: `download`,
6218
+ element: transferElement(/* @__PURE__ */ jsxRuntime.jsx(Download, { title: headerTitle, subtitle: headerSubtitle }))
6219
+ }
6220
+ ),
6108
6221
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: `activity-logs`, element: /* @__PURE__ */ jsxRuntime.jsx(ActivityLogs, { title: headerTitle, subtitle: headerSubtitle }) }),
6109
6222
  /* @__PURE__ */ jsxRuntime.jsx(
6110
6223
  reactRouterDom.Route,
@@ -1,14 +1,15 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { C as CheckboxImpl, B as Box, m as Accordion, c as Flex, n as SwitchImpl, T as Typography, e as Button, d as ForwardRef$4z, A as Alert, j as Divider, l as DesignSystemProvider } from "./index-CHjIMO9T.mjs";
2
+ import { C as CheckboxImpl, B as Box, m as Accordion, c as Flex, n as SwitchImpl, T as Typography, e as Button, d as ForwardRef$4z, A as Alert, j as Divider, l as DesignSystemProvider } from "./index-shryj0jT.mjs";
3
+ import { useRBAC, Layouts, Page } from "@strapi/strapi/admin";
3
4
  import { forwardRef, useState, useEffect } from "react";
4
- import { i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-Dzsu6UNS.mjs";
5
- import { s as set, n as keys, o as isArrayLike, p as arrayEach, l as isArray, q as isObject, P as PluginSettingsService, c as cloneDeep, g as getDefaultTheme, H as HeadingFixGlobalStyle, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-BJGoZPpM.mjs";
6
- import { Layouts } from "@strapi/strapi/admin";
7
- import { S as SUPPORTED_CONTENT_TYPE_FIELDS, a as SUPPORTED_CUSTOM_FIELD_PLUGINS, g as getContentTransferSetupKeysSets, b as get, f as findModelValueByKey, c as StrapiModelService, d as getModelsTree, h as hasModelChanged } from "./has-model-changed-FMGVcFHU.mjs";
5
+ import { s as set, i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-DNhTZZ_6.mjs";
6
+ import { r as keys, v as isArrayLike, w as arrayEach, l as isArray, n as isObject, P as PluginSettingsService, c as cloneDeep, g as getDefaultTheme, H as HeadingFixGlobalStyle, a as PluginPageLoader, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-Bm7bc5bS.mjs";
7
+ import { S as SUPPORTED_CONTENT_TYPE_FIELDS, a as SUPPORTED_CUSTOM_FIELD_PLUGINS, g as getContentTransferSetupKeysSets, b as get, f as findModelValueByKey, c as StrapiModelService, d as getModelsTree, h as hasModelChanged } from "./has-model-changed-CVJEuGxM.mjs";
8
8
  import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
9
9
  import styled from "styled-components";
10
10
  import { Trans } from "./index-BIbKC7-V.mjs";
11
- import "./i18n-QelOdIB2.mjs";
11
+ import { P as PERMISSIONS } from "./index-DP2ugzc_.mjs";
12
+ import "./i18n-76ox2llT.mjs";
12
13
  const getFilteredModelsSchemas = (models) => {
13
14
  if (!models) {
14
15
  return [];
@@ -763,12 +764,19 @@ const SvgX = (props, ref) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.
763
764
  )
764
765
  ] }) });
765
766
  forwardRef(SvgX);
766
- const TreeItem = ({ label, value, children, passedKey = "", onTreeItemClick }) => {
767
+ const TreeItem = ({
768
+ label,
769
+ value,
770
+ children,
771
+ passedKey = "",
772
+ onTreeItemClick,
773
+ disabled = false
774
+ }) => {
767
775
  const onChange = (key, currentValue) => {
768
776
  onTreeItemClick(key, currentValue);
769
777
  };
770
778
  return /* @__PURE__ */ jsxs(Fragment, { children: [
771
- typeof value === "boolean" && /* @__PURE__ */ jsx(CheckboxImpl, { checked: value, onCheckedChange: () => onChange([passedKey], value), children: label || "-" }),
779
+ typeof value === "boolean" && /* @__PURE__ */ jsx(CheckboxImpl, { checked: value, disabled, onCheckedChange: () => onChange([passedKey], value), children: label || "-" }),
772
780
  value === null && /* @__PURE__ */ jsx(CheckboxImpl, { checked: false, disabled: true, children: label || "-" }),
773
781
  children && /* @__PURE__ */ jsx("div", { children }, passedKey)
774
782
  ] });
@@ -831,7 +839,7 @@ function flattenObject(obj, delimiter = ".") {
831
839
  });
832
840
  return nobj;
833
841
  }
834
- const Tree = ({ objects, onTreeItemClick, initiallyExpanded = false }) => {
842
+ const Tree = ({ objects, onTreeItemClick, initiallyExpanded = false, disabled = false }) => {
835
843
  const { t } = useTranslation();
836
844
  const [, setIsExpanded] = useState(initiallyExpanded);
837
845
  useEffect(() => {
@@ -884,7 +892,7 @@ const Tree = ({ objects, onTreeItemClick, initiallyExpanded = false }) => {
884
892
  isSubbranchObject && /* @__PURE__ */ jsx(
885
893
  CheckboxImpl,
886
894
  {
887
- disabled: hasAllNullValue,
895
+ disabled: disabled || hasAllNullValue,
888
896
  checked: getCheckedState(hasTruthyValue, hasFalsyValue),
889
897
  onCheckedChange: () => onTreeItemClick(flattenedKeys, hasTruthyValue),
890
898
  children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", children: [
@@ -893,11 +901,21 @@ const Tree = ({ objects, onTreeItemClick, initiallyExpanded = false }) => {
893
901
  ] })
894
902
  }
895
903
  ),
896
- /* @__PURE__ */ jsx(TreeItem, { onTreeItemClick, passedKey, children: createTree(key, value, passedKey) })
904
+ /* @__PURE__ */ jsx(TreeItem, { onTreeItemClick, passedKey, disabled, children: createTree(key, value, passedKey) })
897
905
  ] }, passedKey);
898
906
  }) });
899
907
  }
900
- return /* @__PURE__ */ jsx(TreeItem, { onTreeItemClick, passedKey: path, label: name, value: branch }, path);
908
+ return /* @__PURE__ */ jsx(
909
+ TreeItem,
910
+ {
911
+ onTreeItemClick,
912
+ passedKey: path,
913
+ label: name,
914
+ value: branch,
915
+ disabled
916
+ },
917
+ path
918
+ );
901
919
  };
902
920
  return /* @__PURE__ */ jsx(Box, { children: Object.entries(objects).map(([key, value]) => {
903
921
  return value.__model__ !== void 0 && /* @__PURE__ */ jsx(Box, { borderColor: "neutral200", hasRadius: true, children: /* @__PURE__ */ jsx(Accordion.Root, { size: "S", children: /* @__PURE__ */ jsxs(Accordion.Item, { value: key, children: [
@@ -913,6 +931,7 @@ const Tree = ({ objects, onTreeItemClick, initiallyExpanded = false }) => {
913
931
  label: `switch_tree_${key}`,
914
932
  onCheckedChange: () => onTreeItemClick([`${key}.__model__`], value.__model__),
915
933
  checked: !!value.__model__,
934
+ disabled,
916
935
  style: { marginRight: "1rem" }
917
936
  }
918
937
  )
@@ -990,6 +1009,9 @@ function ContentTransferSetupEmpty() {
990
1009
  }
991
1010
  const ContentTransferSetup = () => {
992
1011
  const { t } = useTranslation();
1012
+ const {
1013
+ allowedActions: { canUpdate: canUpdateSettings }
1014
+ } = useRBAC(PERMISSIONS.SETTINGS_UPDATE);
993
1015
  const [isLoading, setIsLoading] = useState(true);
994
1016
  const [showAlert, setShowAlert] = useState(false);
995
1017
  const [showModalChangedAlert, setShowModalChangedAlert] = useState(false);
@@ -1087,12 +1109,12 @@ const ContentTransferSetup = () => {
1087
1109
  title: t("plugin_settings.content_transfer_setup"),
1088
1110
  subtitle: t("plugin_settings.content_transfer_setup_description"),
1089
1111
  primaryAction: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
1090
- /* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: !hasUnsavedChanges, onClick: onCancelClick, children: t("plugin_settings.cancel") }),
1112
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", disabled: !canUpdateSettings || !hasUnsavedChanges, onClick: onCancelClick, children: t("plugin_settings.cancel") }),
1091
1113
  /* @__PURE__ */ jsx(
1092
1114
  Button,
1093
1115
  {
1094
1116
  startIcon: /* @__PURE__ */ jsx(ForwardRef$4z, {}),
1095
- disabled: !hasUnsavedChanges,
1117
+ disabled: !canUpdateSettings || !hasUnsavedChanges,
1096
1118
  onClick: () => {
1097
1119
  void saveContentTransferSetup(formModel);
1098
1120
  },
@@ -1128,7 +1150,15 @@ const ContentTransferSetup = () => {
1128
1150
  !formModel.length && // empty state
1129
1151
  /* @__PURE__ */ jsx(ContentTransferSetupEmpty, {}),
1130
1152
  formModel.map((tree, index) => {
1131
- return /* @__PURE__ */ jsx(Box, { marginBottom: 3, children: /* @__PURE__ */ jsx(Tree, { onTreeItemClick, objects: tree, initiallyExpanded: index === 0 }) }, `box_tree_${index}`);
1153
+ return /* @__PURE__ */ jsx(Box, { marginBottom: 3, children: /* @__PURE__ */ jsx(
1154
+ Tree,
1155
+ {
1156
+ onTreeItemClick,
1157
+ objects: tree,
1158
+ initiallyExpanded: index === 0,
1159
+ disabled: !canUpdateSettings
1160
+ }
1161
+ ) }, `box_tree_${index}`);
1132
1162
  }),
1133
1163
  !!formModel.length && /* @__PURE__ */ jsxs(Box, { children: [
1134
1164
  /* @__PURE__ */ jsx(Box, { paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsx(Divider, {}) }),
@@ -1153,13 +1183,19 @@ const ContentTransferSetup = () => {
1153
1183
  ] })
1154
1184
  ] });
1155
1185
  };
1156
- const LocalazyContentTransferSetup = () => /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
1157
- /* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
1158
- /* @__PURE__ */ jsxs(LocalazyIdentityProvider, { children: [
1159
- /* @__PURE__ */ jsx(FetchIdentity, {}),
1160
- /* @__PURE__ */ jsx(RequireLocalazyAuth, { children: /* @__PURE__ */ jsx(ContentTransferSetup, {}) })
1161
- ] })
1162
- ] });
1186
+ const LocalazyContentTransferSetup = () => {
1187
+ const {
1188
+ allowedActions: { canRead: canReadSettings },
1189
+ isLoading: isLoadingPermissions
1190
+ } = useRBAC(PERMISSIONS.SETTINGS_READ);
1191
+ return /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
1192
+ /* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
1193
+ isLoadingPermissions ? /* @__PURE__ */ jsx(PluginPageLoader, {}) : !canReadSettings ? /* @__PURE__ */ jsx(Page.NoPermissions, {}) : /* @__PURE__ */ jsxs(LocalazyIdentityProvider, { children: [
1194
+ /* @__PURE__ */ jsx(FetchIdentity, {}),
1195
+ /* @__PURE__ */ jsx(RequireLocalazyAuth, { children: /* @__PURE__ */ jsx(ContentTransferSetup, {}) })
1196
+ ] })
1197
+ ] });
1198
+ };
1163
1199
  export {
1164
1200
  LocalazyContentTransferSetup as default
1165
1201
  };