@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.
- package/README.md +30 -0
- package/dist/_chunks/{FetchIdentity-BJGoZPpM.mjs → FetchIdentity-Bm7bc5bS.mjs} +36 -44
- package/dist/_chunks/{FetchIdentity-CtBRO-Cn.js → FetchIdentity-CcEjakiz.js} +25 -33
- package/dist/_chunks/{LanguagesSelector-DJxgCwgM.mjs → LanguagesSelector-B1rwN7-Y.mjs} +4 -3
- package/dist/_chunks/{LanguagesSelector-CNaKrS-m.js → LanguagesSelector-DejYCwBl.js} +4 -3
- package/dist/_chunks/{LocalazyApp-CJRpsTKr.mjs → LocalazyApp-C4kbsnQh.mjs} +148 -35
- package/dist/_chunks/{LocalazyApp-B1qCCEPe.js → LocalazyApp-jPO7Yr1S.js} +154 -41
- package/dist/_chunks/{LocalazyContentTransferSetup-CLAWn95U.mjs → LocalazyContentTransferSetup-C1wDD9hA.mjs} +58 -22
- package/dist/_chunks/{LocalazyContentTransferSetup-CCxiLHdG.js → LocalazyContentTransferSetup-DZh4ZdSi.js} +63 -27
- package/dist/_chunks/{LocalazyGlobalSettings-BJ5qfFfK.js → LocalazyGlobalSettings-D76it6rn.js} +57 -26
- package/dist/_chunks/{LocalazyGlobalSettings-Z-4Ykc_J.mjs → LocalazyGlobalSettings-DOW5rjLn.mjs} +56 -25
- package/dist/_chunks/{LocalazyPanel-CL_mzzfD.mjs → LocalazyPanel-C_Z4W49T.mjs} +12 -6
- package/dist/_chunks/{LocalazyPanel-DE3TtHOQ.js → LocalazyPanel-D2LQpqii.js} +14 -8
- package/dist/_chunks/{LocalazyStatusColumn-R5n6q_cx.mjs → LocalazyStatusColumn-C_ZCd_s7.mjs} +10 -4
- package/dist/_chunks/{LocalazyStatusColumn-BMLcklG-.js → LocalazyStatusColumn-Dy6N4_X6.js} +10 -4
- package/dist/_chunks/{RequireLocalazyAuth-WKKFdQlR.js → RequireLocalazyAuth-BVwF0bRC.js} +31 -4
- package/dist/_chunks/{RequireLocalazyAuth-Dzsu6UNS.mjs → RequireLocalazyAuth-DNhTZZ_6.mjs} +32 -5
- package/dist/_chunks/{entry-exclusion-service-DxqTlZFR.mjs → entry-exclusion-service-CF_yNCly.mjs} +1 -1
- package/dist/_chunks/{entry-exclusion-service-CggmAKxq.js → entry-exclusion-service-CH3ZoJQN.js} +1 -1
- package/dist/_chunks/{has-model-changed-FMGVcFHU.mjs → has-model-changed-CVJEuGxM.mjs} +2 -2
- package/dist/_chunks/{has-model-changed-BR53L6pA.js → has-model-changed-DdYbyv0v.js} +2 -2
- package/dist/_chunks/{i18n-QelOdIB2.mjs → i18n-76ox2llT.mjs} +9 -2
- package/dist/_chunks/{i18n-CAsbU4pi.js → i18n-C5ucROBh.js} +9 -2
- package/dist/_chunks/{index-BmxGKspv.js → index-CEGaWWh3.js} +33 -11
- package/dist/_chunks/{index-BK7lmZSN.js → index-CTkxoioB.js} +1 -0
- package/dist/_chunks/{index-toauQlIK.mjs → index-DP2ugzc_.mjs} +34 -12
- package/dist/_chunks/{index-CHjIMO9T.mjs → index-shryj0jT.mjs} +19 -18
- package/dist/_chunks/{strapi-api-base-CT9lknwW.js → strapi-api-base-CCUuu7EY.js} +1 -1
- package/dist/_chunks/{strapi-api-base-BflplVsH.mjs → strapi-api-base-IiMEtDoH.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/LocalazyStatusColumn.d.ts +1 -1
- package/dist/admin/src/constants/permissions.d.ts +29 -0
- package/dist/admin/src/modules/@common/components/LanguagesSelector.d.ts +1 -0
- package/dist/admin/src/modules/activity-logs/locale/en.d.ts +4 -0
- package/dist/admin/src/modules/activity-logs/services/debug-bundle-service.d.ts +10 -0
- package/dist/admin/src/modules/login/locale/en.d.ts +1 -0
- package/dist/admin/src/modules/plugin-settings/components/Tree.d.ts +1 -0
- package/dist/admin/src/modules/plugin-settings/components/TreeItem.d.ts +1 -0
- package/dist/admin/src/modules/plugin-settings/components/WebhookSetup.d.ts +4 -1
- package/dist/admin/src/modules/plugin-settings/locale/en.d.ts +2 -0
- package/dist/admin/src/modules/plugin-settings/services/plugin-settings-service.d.ts +4 -0
- package/dist/server/index.js +665 -38
- package/dist/server/index.mjs +665 -39
- package/dist/server/src/bootstrap.d.ts +1 -1
- package/dist/server/src/constants/permissions.d.ts +38 -0
- package/dist/server/src/controllers/debug-bundle-controller.d.ts +7 -0
- package/dist/server/src/controllers/index.d.ts +6 -0
- package/dist/server/src/controllers/plugin-settings-controller.d.ts +1 -0
- package/dist/server/src/core/index.d.ts +5 -1
- package/dist/server/src/db/model/activity-logs.d.ts +10 -0
- package/dist/server/src/index.d.ts +64 -8
- package/dist/server/src/routes/activity-logs-routes.d.ts +20 -3
- package/dist/server/src/routes/debug-bundle-routes.d.ts +14 -0
- package/dist/server/src/routes/entry-exclusion-routes.d.ts +20 -3
- package/dist/server/src/routes/index.d.ts +52 -6
- package/dist/server/src/routes/localazy-auth-routes.d.ts +6 -1
- package/dist/server/src/routes/localazy-project-routes.d.ts +20 -3
- package/dist/server/src/routes/localazy-transfer-routes.d.ts +6 -1
- package/dist/server/src/routes/localazy-user-routes.d.ts +20 -3
- package/dist/server/src/routes/plugin-settings-routes.d.ts +20 -3
- package/dist/server/src/routes/strapi-routes.d.ts +20 -3
- package/dist/server/src/services/activity-logs-service.d.ts +3 -1
- package/dist/server/src/services/index.d.ts +5 -1
- package/dist/server/src/services/localazy-transfer-download-service.d.ts +2 -1
- package/dist/server/src/services/plugin-settings-service.d.ts +4 -0
- package/dist/server/src/utils/build-debug-bundle.d.ts +68 -0
- package/dist/server/src/utils/sanitize-debug-bundle.d.ts +25 -0
- package/package.json +2 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useNavigate, useLocation, NavLink, useParams, Routes, Route } from "react-router-dom";
|
|
3
|
-
import { o as ForwardRef$2H, p as ForwardRef$d, q as ForwardRef$3P, r as ForwardRef$4j,
|
|
3
|
+
import { o as ForwardRef$2H, p as ForwardRef$d, q as ForwardRef$3P, r as ForwardRef$4j, e as Button, s as TooltipImpl, B as Box, T as Typography, g as Link, t as SubNav, u as SubNavHeader, v as SubNavSections, w as SubNavSection, x as SubNavLink, y as ForwardRef$L, G as Grid, j as Divider, c as Flex, f as ForwardRef$3, A as Alert, D as Dialog, z as ForwardRef$4L, E as ForwardRef$4N, P as Pagination, H as PreviousLink, I as PageLink, J as Dots, N as NextLink, K as lodashExports, O as ForwardRef$j, i as ForwardRef$2x, F as Field, Q as DatePicker$1, R as Tabs, U as ForwardRef$57, l as DesignSystemProvider } from "./index-shryj0jT.mjs";
|
|
4
4
|
import React__default, { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
|
5
|
-
import { u as useLocalazyIdentity,
|
|
6
|
-
import {
|
|
5
|
+
import { u as useLocalazyIdentity, a as PluginPageLoader, y as LocalazyUserService, z as emptyIdentity, P as PluginSettingsService, g as getDefaultTheme, H as HeadingFixGlobalStyle, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-Bm7bc5bS.mjs";
|
|
6
|
+
import { a as PLUGIN_ID, P as PERMISSIONS } from "./index-DP2ugzc_.mjs";
|
|
7
7
|
import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
|
|
8
8
|
import { g as getDefaultExportFromCjs } from "./_commonjsHelpers-DWwsNxpa.mjs";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import "./i18n-
|
|
13
|
-
import { h as hasModelChanged } from "./has-model-changed-
|
|
9
|
+
import { useRBAC, Layouts, useAuth, useNotification, Page } from "@strapi/strapi/admin";
|
|
10
|
+
import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-IiMEtDoH.mjs";
|
|
11
|
+
import { P as ProjectService, L as LanguagesSelector } from "./LanguagesSelector-B1rwN7-Y.mjs";
|
|
12
|
+
import "./i18n-76ox2llT.mjs";
|
|
13
|
+
import { h as hasModelChanged } from "./has-model-changed-CVJEuGxM.mjs";
|
|
14
14
|
import { useTheme } from "styled-components";
|
|
15
15
|
var PLUGIN_ROUTES = /* @__PURE__ */ ((PLUGIN_ROUTES2) => {
|
|
16
16
|
PLUGIN_ROUTES2["ROOT"] = "";
|
|
@@ -98,10 +98,6 @@ const useHeaderSubtitle = () => {
|
|
|
98
98
|
const currentNavItem = navigation.find((navItem) => pluginSegment.includes(navItem.id));
|
|
99
99
|
return currentNavItem?.description || "";
|
|
100
100
|
};
|
|
101
|
-
function PluginPageLoader() {
|
|
102
|
-
const { t: t2 } = useTranslation();
|
|
103
|
-
return /* @__PURE__ */ jsx(Flex, { marginTop: 10, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx(Loader, { children: t2("common.loading_content") }) });
|
|
104
|
-
}
|
|
105
101
|
var propTypes = { exports: {} };
|
|
106
102
|
var reactIs = { exports: {} };
|
|
107
103
|
var reactIs_production_min = {};
|
|
@@ -1258,6 +1254,8 @@ if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development") {
|
|
|
1258
1254
|
}
|
|
1259
1255
|
const LoginButton = (props) => {
|
|
1260
1256
|
const { t: t2 } = useTranslation();
|
|
1257
|
+
const { allowedActions } = useRBAC(PERMISSIONS.SETTINGS_UPDATE);
|
|
1258
|
+
const canConnect = !!allowedActions.canUpdate;
|
|
1261
1259
|
const [isLoading, setIsLoading] = useState(false);
|
|
1262
1260
|
const login = async () => {
|
|
1263
1261
|
setIsLoading(true);
|
|
@@ -1278,7 +1276,8 @@ const LoginButton = (props) => {
|
|
|
1278
1276
|
setIsLoading(false);
|
|
1279
1277
|
props.onResultFetched(pollResult);
|
|
1280
1278
|
};
|
|
1281
|
-
|
|
1279
|
+
const button = /* @__PURE__ */ jsx(Button, { variant: "default", size: "L", loading: isLoading, onClick: login, disabled: !canConnect, children: t2("login.login_with_localazy") });
|
|
1280
|
+
return /* @__PURE__ */ jsx("div", { children: canConnect ? button : /* @__PURE__ */ jsx(TooltipImpl, { label: t2("login.requires_settings_update_permission"), children: /* @__PURE__ */ jsx("span", { children: button }) }) });
|
|
1282
1281
|
};
|
|
1283
1282
|
LoginButton.propTypes = {
|
|
1284
1283
|
onResultFetched: PropTypes.func.isRequired
|
|
@@ -1436,6 +1435,8 @@ const LogoutButton = (props) => {
|
|
|
1436
1435
|
const { t: t2 } = useTranslation();
|
|
1437
1436
|
const [isLoading, setIsLoading] = useState(false);
|
|
1438
1437
|
const { setIdentity } = useLocalazyIdentity();
|
|
1438
|
+
const { allowedActions } = useRBAC(PERMISSIONS.SETTINGS_UPDATE);
|
|
1439
|
+
const canDisconnect = !!allowedActions.canUpdate;
|
|
1439
1440
|
const logout = async () => {
|
|
1440
1441
|
setIsLoading(true);
|
|
1441
1442
|
void LocalazyUserService.deleteIdentity();
|
|
@@ -1443,7 +1444,8 @@ const LogoutButton = (props) => {
|
|
|
1443
1444
|
setIsLoading(false);
|
|
1444
1445
|
props.onResultFetched();
|
|
1445
1446
|
};
|
|
1446
|
-
|
|
1447
|
+
const button = /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(ForwardRef$L, {}), variant: "secondary", loading: isLoading, onClick: logout, disabled: !canDisconnect, children: t2("login.logout_from_localazy") });
|
|
1448
|
+
return /* @__PURE__ */ jsx("div", { children: canDisconnect ? button : /* @__PURE__ */ jsx(TooltipImpl, { label: t2("login.requires_settings_update_permission"), children: /* @__PURE__ */ jsx("span", { children: button }) }) });
|
|
1447
1449
|
};
|
|
1448
1450
|
const OverviewItem = (props) => {
|
|
1449
1451
|
return /* @__PURE__ */ jsxs(Grid.Root, { padding: 1, col: 6, s: 12, children: [
|
|
@@ -1474,7 +1476,7 @@ const Overview = ({ title, subtitle, isLoadingProp = false }) => {
|
|
|
1474
1476
|
setIsLoading(true);
|
|
1475
1477
|
const project = await ProjectService.getConnectedProject();
|
|
1476
1478
|
setConnectedProject(project);
|
|
1477
|
-
void PluginSettingsService.
|
|
1479
|
+
void PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.OVERVIEW });
|
|
1478
1480
|
setIsLoading(false);
|
|
1479
1481
|
}
|
|
1480
1482
|
void initComponent();
|
|
@@ -5061,7 +5063,7 @@ const Upload = (props) => {
|
|
|
5061
5063
|
setLocalazySourceLanguage(sourceLanguage);
|
|
5062
5064
|
setModelChanged(modelChangedResult);
|
|
5063
5065
|
setLocalesIncompatible(!localesCompatibleResult);
|
|
5064
|
-
void PluginSettingsService.
|
|
5066
|
+
void PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.UPLOAD });
|
|
5065
5067
|
setIsLoading(false);
|
|
5066
5068
|
}
|
|
5067
5069
|
void initComponent();
|
|
@@ -5194,16 +5196,9 @@ const Download = (props) => {
|
|
|
5194
5196
|
window.open(identity.project.url, "_blank");
|
|
5195
5197
|
};
|
|
5196
5198
|
const [projectLanguages, setProjectLanguages] = useState([]);
|
|
5197
|
-
const [
|
|
5199
|
+
const [uiLanguages, setUiLanguages] = useState([]);
|
|
5198
5200
|
const onDownloadLanguagesChange = (languages) => {
|
|
5199
|
-
|
|
5200
|
-
set(newFormModel, "download.uiLanguages", languages);
|
|
5201
|
-
setFormModel(newFormModel);
|
|
5202
|
-
try {
|
|
5203
|
-
void PluginSettingsService.updatePluginSettings(newFormModel);
|
|
5204
|
-
} catch (e2) {
|
|
5205
|
-
console.error(e2.message);
|
|
5206
|
-
}
|
|
5201
|
+
setUiLanguages(languages);
|
|
5207
5202
|
};
|
|
5208
5203
|
const onDownloadClick = async (fullSync = false) => {
|
|
5209
5204
|
setIsDownloading(true);
|
|
@@ -5212,7 +5207,7 @@ const Download = (props) => {
|
|
|
5212
5207
|
success: false,
|
|
5213
5208
|
report: []
|
|
5214
5209
|
});
|
|
5215
|
-
const result = await LocalazyDownloadService.download({ fullSync });
|
|
5210
|
+
const result = await LocalazyDownloadService.download({ fullSync, uiLanguages });
|
|
5216
5211
|
const { streamIdentifier } = result;
|
|
5217
5212
|
downloadAlertsService.setStreamIdentifier(streamIdentifier);
|
|
5218
5213
|
downloadAlertsService.onDownload((data) => {
|
|
@@ -5253,8 +5248,8 @@ const Download = (props) => {
|
|
|
5253
5248
|
setHasSyncCursor(syncCursor?.processedKeys !== void 0 && Object.keys(syncCursor.processedKeys).length > 0);
|
|
5254
5249
|
const projectLanguagesWithoutDefaultLanguage = project?.languages?.filter((language) => language.id !== project.sourceLanguage) || [];
|
|
5255
5250
|
setProjectLanguages(projectLanguagesWithoutDefaultLanguage);
|
|
5256
|
-
|
|
5257
|
-
void PluginSettingsService.
|
|
5251
|
+
setUiLanguages(Array.isArray(globalSettings?.download?.uiLanguages) ? globalSettings.download.uiLanguages : []);
|
|
5252
|
+
void PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.DOWNLOAD });
|
|
5258
5253
|
setIsLoading(false);
|
|
5259
5254
|
}
|
|
5260
5255
|
void initComponent();
|
|
@@ -5312,7 +5307,7 @@ const Download = (props) => {
|
|
|
5312
5307
|
/* @__PURE__ */ jsx(Box, { paddingTop: 6, children: /* @__PURE__ */ jsx(
|
|
5313
5308
|
LanguagesSelector,
|
|
5314
5309
|
{
|
|
5315
|
-
preselectedLanguages:
|
|
5310
|
+
preselectedLanguages: uiLanguages,
|
|
5316
5311
|
projectLanguages,
|
|
5317
5312
|
onChange: (languages) => onDownloadLanguagesChange(languages),
|
|
5318
5313
|
label: t2("download.ui_languages"),
|
|
@@ -5689,6 +5684,9 @@ const useDebouncedSearch = () => {
|
|
|
5689
5684
|
const ActivityLogs = (props) => {
|
|
5690
5685
|
const { t: t2 } = useTranslation();
|
|
5691
5686
|
const navigate = useNavigate();
|
|
5687
|
+
const {
|
|
5688
|
+
allowedActions: { canTransfer }
|
|
5689
|
+
} = useRBAC(PERMISSIONS.TRANSFER);
|
|
5692
5690
|
const [isLoading, setIsLoading] = useState(true);
|
|
5693
5691
|
const [sessions, setSessions] = useState([]);
|
|
5694
5692
|
const [activeTab, setActiveTab] = useState("upload");
|
|
@@ -5702,7 +5700,7 @@ const ActivityLogs = (props) => {
|
|
|
5702
5700
|
const debouncedSaveSortPrefs = useCallback((prefs) => {
|
|
5703
5701
|
if (saveSortTimerRef.current) clearTimeout(saveSortTimerRef.current);
|
|
5704
5702
|
saveSortTimerRef.current = setTimeout(() => {
|
|
5705
|
-
void PluginSettingsService.
|
|
5703
|
+
void PluginSettingsService.updatePluginSettingsUiPrefs({ activityLogsSort: prefs });
|
|
5706
5704
|
}, 1e3);
|
|
5707
5705
|
}, []);
|
|
5708
5706
|
const onSortChange = (eventType, key, direction) => {
|
|
@@ -5758,7 +5756,7 @@ const ActivityLogs = (props) => {
|
|
|
5758
5756
|
void fetchSessions("upload");
|
|
5759
5757
|
};
|
|
5760
5758
|
void init();
|
|
5761
|
-
void PluginSettingsService.
|
|
5759
|
+
void PluginSettingsService.updatePluginSettingsUiPrefs({ defaultRoute: PLUGIN_ROUTES.ACTIVITY_LOGS });
|
|
5762
5760
|
}, []);
|
|
5763
5761
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5764
5762
|
/* @__PURE__ */ jsx(
|
|
@@ -5768,7 +5766,16 @@ const ActivityLogs = (props) => {
|
|
|
5768
5766
|
subtitle: props.subtitle,
|
|
5769
5767
|
primaryAction: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
5770
5768
|
/* @__PURE__ */ jsx(Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsx(ForwardRef$3P, {}), onClick: onExportLogs, children: t2("activity_logs.export_logs") }),
|
|
5771
|
-
/* @__PURE__ */ jsx(
|
|
5769
|
+
/* @__PURE__ */ jsx(
|
|
5770
|
+
Button,
|
|
5771
|
+
{
|
|
5772
|
+
variant: "danger-light",
|
|
5773
|
+
startIcon: /* @__PURE__ */ jsx(ForwardRef$j, {}),
|
|
5774
|
+
disabled: !canTransfer,
|
|
5775
|
+
onClick: () => setShowClearConfirm(true),
|
|
5776
|
+
children: t2("activity_logs.clear_logs")
|
|
5777
|
+
}
|
|
5778
|
+
)
|
|
5772
5779
|
] })
|
|
5773
5780
|
}
|
|
5774
5781
|
),
|
|
@@ -5897,6 +5904,45 @@ const ActivityLogs = (props) => {
|
|
|
5897
5904
|
] }) })
|
|
5898
5905
|
] });
|
|
5899
5906
|
};
|
|
5907
|
+
const LOCALAZY_HEADER = { "X-Localazy-Initiated-By": "strapi-plugin-localazy" };
|
|
5908
|
+
const fallbackFilename = (sessionId) => `localazy-debug-bundle-${sessionId.slice(0, 8)}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.zip`;
|
|
5909
|
+
const parseFilenameFromContentDisposition = (header) => {
|
|
5910
|
+
if (!header) return null;
|
|
5911
|
+
const match = /filename="?([^";]+)"?/i.exec(header);
|
|
5912
|
+
return match ? match[1] : null;
|
|
5913
|
+
};
|
|
5914
|
+
const triggerBrowserDownload = (blob, filename) => {
|
|
5915
|
+
const url2 = URL.createObjectURL(blob);
|
|
5916
|
+
const a2 = document.createElement("a");
|
|
5917
|
+
a2.href = url2;
|
|
5918
|
+
a2.download = filename;
|
|
5919
|
+
document.body.appendChild(a2);
|
|
5920
|
+
a2.click();
|
|
5921
|
+
document.body.removeChild(a2);
|
|
5922
|
+
setTimeout(() => URL.revokeObjectURL(url2), 3e4);
|
|
5923
|
+
};
|
|
5924
|
+
const downloadDebugBundle = async (sessionId, token, browserInfo) => {
|
|
5925
|
+
const backendURL = window.strapi?.backendURL ?? "";
|
|
5926
|
+
const encodedBrowser = btoa(unescape(encodeURIComponent(JSON.stringify(browserInfo))));
|
|
5927
|
+
const url2 = `${backendURL}/${PLUGIN_ID}/activity-logs/${encodeURIComponent(sessionId)}/bundle?browser=${encodeURIComponent(encodedBrowser)}`;
|
|
5928
|
+
const headers = { ...LOCALAZY_HEADER };
|
|
5929
|
+
if (token) {
|
|
5930
|
+
headers.Authorization = `Bearer ${token}`;
|
|
5931
|
+
}
|
|
5932
|
+
const response = await fetch(url2, { method: "GET", headers });
|
|
5933
|
+
if (!response.ok) {
|
|
5934
|
+
let detail = `${response.status} ${response.statusText}`;
|
|
5935
|
+
try {
|
|
5936
|
+
const text = await response.text();
|
|
5937
|
+
if (text) detail = `${detail} — ${text.slice(0, 200)}`;
|
|
5938
|
+
} catch {
|
|
5939
|
+
}
|
|
5940
|
+
throw new Error(`Failed to download debug bundle: ${detail}`);
|
|
5941
|
+
}
|
|
5942
|
+
const blob = await response.blob();
|
|
5943
|
+
const filename = parseFilenameFromContentDisposition(response.headers.get("content-disposition")) ?? fallbackFilename(sessionId);
|
|
5944
|
+
triggerBrowserDownload(blob, filename);
|
|
5945
|
+
};
|
|
5900
5946
|
const SessionMetadata = ({ session, showEntryCount }) => {
|
|
5901
5947
|
const { t: t2 } = useTranslation();
|
|
5902
5948
|
return /* @__PURE__ */ jsxs(Flex, { gap: 6, wrap: "wrap", children: [
|
|
@@ -5931,8 +5977,11 @@ const ActivityLogDetail = (props) => {
|
|
|
5931
5977
|
const { t: t2 } = useTranslation();
|
|
5932
5978
|
const theme = useTheme();
|
|
5933
5979
|
const { sessionId } = useParams();
|
|
5980
|
+
const token = useAuth("ActivityLogDetail", (state) => state.token);
|
|
5981
|
+
const { toggleNotification } = useNotification();
|
|
5934
5982
|
const [isLoading, setIsLoading] = useState(true);
|
|
5935
5983
|
const [session, setSession] = useState(null);
|
|
5984
|
+
const [isBuildingBundle, setIsBuildingBundle] = useState(false);
|
|
5936
5985
|
const { searchInput, searchQuery, onSearchChange } = useDebouncedSearch();
|
|
5937
5986
|
useEffect(() => {
|
|
5938
5987
|
const fetchSession = async () => {
|
|
@@ -5948,6 +5997,30 @@ const ActivityLogDetail = (props) => {
|
|
|
5948
5997
|
};
|
|
5949
5998
|
void fetchSession();
|
|
5950
5999
|
}, [sessionId]);
|
|
6000
|
+
const onDownloadBundle = async () => {
|
|
6001
|
+
if (!sessionId || isBuildingBundle) return;
|
|
6002
|
+
setIsBuildingBundle(true);
|
|
6003
|
+
try {
|
|
6004
|
+
await downloadDebugBundle(sessionId, token, {
|
|
6005
|
+
userAgent: navigator.userAgent,
|
|
6006
|
+
language: navigator.language,
|
|
6007
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
6008
|
+
});
|
|
6009
|
+
toggleNotification({
|
|
6010
|
+
type: "success",
|
|
6011
|
+
message: t2("activity_logs.download_bundle_success"),
|
|
6012
|
+
timeout: 5e3
|
|
6013
|
+
});
|
|
6014
|
+
} catch (e2) {
|
|
6015
|
+
console.error("Failed to build debug bundle:", e2);
|
|
6016
|
+
toggleNotification({
|
|
6017
|
+
type: "danger",
|
|
6018
|
+
message: t2("activity_logs.download_bundle_error")
|
|
6019
|
+
});
|
|
6020
|
+
} finally {
|
|
6021
|
+
setIsBuildingBundle(false);
|
|
6022
|
+
}
|
|
6023
|
+
};
|
|
5951
6024
|
const filteredEntries = (session?.entries || []).filter((entry) => {
|
|
5952
6025
|
if (!searchQuery) return true;
|
|
5953
6026
|
const query = searchQuery.toLowerCase();
|
|
@@ -5959,7 +6032,18 @@ const ActivityLogDetail = (props) => {
|
|
|
5959
6032
|
{
|
|
5960
6033
|
title: props.title,
|
|
5961
6034
|
subtitle: props.subtitle,
|
|
5962
|
-
navigationAction: /* @__PURE__ */ jsx(Link, { tag: NavLink, to: `/plugins/${PLUGIN_ID}/activity-logs`, startIcon: /* @__PURE__ */ jsx(ForwardRef$57, {}), children: t2("activity_logs.back_to_list") })
|
|
6035
|
+
navigationAction: /* @__PURE__ */ jsx(Link, { tag: NavLink, to: `/plugins/${PLUGIN_ID}/activity-logs`, startIcon: /* @__PURE__ */ jsx(ForwardRef$57, {}), children: t2("activity_logs.back_to_list") }),
|
|
6036
|
+
primaryAction: /* @__PURE__ */ jsx(TooltipImpl, { label: t2("activity_logs.download_bundle_warning"), children: /* @__PURE__ */ jsx(
|
|
6037
|
+
Button,
|
|
6038
|
+
{
|
|
6039
|
+
variant: "secondary",
|
|
6040
|
+
startIcon: /* @__PURE__ */ jsx(ForwardRef$3P, {}),
|
|
6041
|
+
onClick: onDownloadBundle,
|
|
6042
|
+
loading: isBuildingBundle,
|
|
6043
|
+
disabled: !session || isBuildingBundle,
|
|
6044
|
+
children: t2("activity_logs.download_bundle")
|
|
6045
|
+
}
|
|
6046
|
+
) })
|
|
5963
6047
|
}
|
|
5964
6048
|
),
|
|
5965
6049
|
isLoading && /* @__PURE__ */ jsx(PluginPageLoader, {}),
|
|
@@ -6059,6 +6143,10 @@ const App = () => {
|
|
|
6059
6143
|
const { isLoggedIn, isFetchingIdentity } = useLocalazyIdentity();
|
|
6060
6144
|
const headerTitle = useHeaderTitle();
|
|
6061
6145
|
const headerSubtitle = useHeaderSubtitle();
|
|
6146
|
+
const {
|
|
6147
|
+
allowedActions: { canRead, canTransfer },
|
|
6148
|
+
isLoading: isLoadingPermissions
|
|
6149
|
+
} = useRBAC([...PERMISSIONS.READ, ...PERMISSIONS.TRANSFER]);
|
|
6062
6150
|
const normalizedPath = location2.pathname.replace(/\/+$/, "");
|
|
6063
6151
|
const pluginRoot = `/plugins/${PLUGIN_ID}`;
|
|
6064
6152
|
const isAtPluginRoot = normalizedPath === pluginRoot;
|
|
@@ -6080,6 +6168,19 @@ const App = () => {
|
|
|
6080
6168
|
};
|
|
6081
6169
|
void fetchData();
|
|
6082
6170
|
}, [isLoggedIn, isFetchingIdentity, normalizedPath]);
|
|
6171
|
+
if (isLoadingPermissions) {
|
|
6172
|
+
return /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
|
|
6173
|
+
/* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
|
|
6174
|
+
/* @__PURE__ */ jsx(Box, { background: "neutral100", children: /* @__PURE__ */ jsx(Layouts.Root, { children: /* @__PURE__ */ jsx(PluginPageLoader, {}) }) })
|
|
6175
|
+
] });
|
|
6176
|
+
}
|
|
6177
|
+
if (!canRead) {
|
|
6178
|
+
return /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
|
|
6179
|
+
/* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
|
|
6180
|
+
/* @__PURE__ */ jsx(Box, { background: "neutral100", children: /* @__PURE__ */ jsx(Layouts.Root, { children: /* @__PURE__ */ jsx(Page.NoPermissions, {}) }) })
|
|
6181
|
+
] });
|
|
6182
|
+
}
|
|
6183
|
+
const transferElement = (page) => canTransfer ? page : /* @__PURE__ */ jsx(Page.NoPermissions, {});
|
|
6083
6184
|
return /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
|
|
6084
6185
|
/* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
|
|
6085
6186
|
/* @__PURE__ */ jsx(PluginErrorBoundary, { children: /* @__PURE__ */ jsx(Box, { background: "neutral100", children: /* @__PURE__ */ jsxs(Layouts.Root, { sideNav: isLoggedIn && /* @__PURE__ */ jsx(SideNav, {}), children: [
|
|
@@ -6099,8 +6200,20 @@ const App = () => {
|
|
|
6099
6200
|
element: /* @__PURE__ */ jsx(Overview, { title: headerTitle, subtitle: headerSubtitle, isLoadingProp: false })
|
|
6100
6201
|
}
|
|
6101
6202
|
),
|
|
6102
|
-
/* @__PURE__ */ jsx(
|
|
6103
|
-
|
|
6203
|
+
/* @__PURE__ */ jsx(
|
|
6204
|
+
Route,
|
|
6205
|
+
{
|
|
6206
|
+
path: `upload`,
|
|
6207
|
+
element: transferElement(/* @__PURE__ */ jsx(Upload, { title: headerTitle, subtitle: headerSubtitle }))
|
|
6208
|
+
}
|
|
6209
|
+
),
|
|
6210
|
+
/* @__PURE__ */ jsx(
|
|
6211
|
+
Route,
|
|
6212
|
+
{
|
|
6213
|
+
path: `download`,
|
|
6214
|
+
element: transferElement(/* @__PURE__ */ jsx(Download, { title: headerTitle, subtitle: headerSubtitle }))
|
|
6215
|
+
}
|
|
6216
|
+
),
|
|
6104
6217
|
/* @__PURE__ */ jsx(Route, { path: `activity-logs`, element: /* @__PURE__ */ jsx(ActivityLogs, { title: headerTitle, subtitle: headerSubtitle }) }),
|
|
6105
6218
|
/* @__PURE__ */ jsx(
|
|
6106
6219
|
Route,
|