@localazy/strapi-plugin 1.4.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-Cor4ooZv.mjs → FetchIdentity-Bm7bc5bS.mjs} +36 -44
- package/dist/_chunks/{FetchIdentity-BpFOT163.js → FetchIdentity-CcEjakiz.js} +24 -32
- package/dist/_chunks/{LanguagesSelector-BbrMKwQY.mjs → LanguagesSelector-B1rwN7-Y.mjs} +4 -3
- package/dist/_chunks/{LanguagesSelector-CC1ecWnc.js → LanguagesSelector-DejYCwBl.js} +3 -2
- package/dist/_chunks/{LocalazyApp-DpFR8p10.mjs → LocalazyApp-C4kbsnQh.mjs} +70 -34
- package/dist/_chunks/{LocalazyApp-D0JGRQeF.js → LocalazyApp-jPO7Yr1S.js} +75 -39
- package/dist/_chunks/{LocalazyContentTransferSetup-Dael1Q4w.mjs → LocalazyContentTransferSetup-C1wDD9hA.mjs} +58 -22
- package/dist/_chunks/{LocalazyContentTransferSetup-Cr7D-BUi.js → LocalazyContentTransferSetup-DZh4ZdSi.js} +62 -26
- package/dist/_chunks/{LocalazyGlobalSettings-D3nG4zl7.js → LocalazyGlobalSettings-D76it6rn.js} +56 -25
- package/dist/_chunks/{LocalazyGlobalSettings-DzBI5M-K.mjs → LocalazyGlobalSettings-DOW5rjLn.mjs} +56 -25
- package/dist/_chunks/{LocalazyPanel-W6j8N1WC.mjs → LocalazyPanel-C_Z4W49T.mjs} +12 -6
- package/dist/_chunks/{LocalazyPanel-KQPLxTDz.js → LocalazyPanel-D2LQpqii.js} +14 -8
- package/dist/_chunks/{LocalazyStatusColumn-CrhsCjgp.mjs → LocalazyStatusColumn-C_ZCd_s7.mjs} +10 -4
- package/dist/_chunks/{LocalazyStatusColumn-B7Q_U2Lu.js → LocalazyStatusColumn-Dy6N4_X6.js} +10 -4
- package/dist/_chunks/{RequireLocalazyAuth-D3GeZPDh.js → RequireLocalazyAuth-BVwF0bRC.js} +30 -3
- package/dist/_chunks/{RequireLocalazyAuth-BwoGRfJq.mjs → RequireLocalazyAuth-DNhTZZ_6.mjs} +32 -5
- package/dist/_chunks/{entry-exclusion-service-D7gaRHPE.mjs → entry-exclusion-service-CF_yNCly.mjs} +1 -1
- package/dist/_chunks/{entry-exclusion-service-Bwruvyce.js → entry-exclusion-service-CH3ZoJQN.js} +1 -1
- package/dist/_chunks/{has-model-changed-Dp2Vkwjw.mjs → has-model-changed-CVJEuGxM.mjs} +2 -2
- package/dist/_chunks/{has-model-changed-5IV9WI_-.js → has-model-changed-DdYbyv0v.js} +2 -2
- package/dist/_chunks/{i18n-o24yXf-j.mjs → i18n-76ox2llT.mjs} +4 -1
- package/dist/_chunks/{i18n-C_5tJvr0.js → i18n-C5ucROBh.js} +4 -1
- package/dist/_chunks/{index-jAg6jjCu.js → index-CEGaWWh3.js} +33 -11
- package/dist/_chunks/{index-C9hN3KbD.mjs → index-DP2ugzc_.mjs} +34 -12
- package/dist/_chunks/{index-BjL9XpRh.mjs → index-shryj0jT.mjs} +16 -16
- package/dist/_chunks/{strapi-api-base-IG3Pe5Sg.js → strapi-api-base-CCUuu7EY.js} +1 -1
- package/dist/_chunks/{strapi-api-base-CAzGcwF6.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/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 +157 -36
- package/dist/server/index.mjs +157 -36
- package/dist/server/src/bootstrap.d.ts +1 -1
- package/dist/server/src/constants/permissions.d.ts +38 -0
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/plugin-settings-controller.d.ts +1 -0
- package/dist/server/src/core/index.d.ts +3 -1
- package/dist/server/src/index.d.ts +57 -8
- package/dist/server/src/routes/activity-logs-routes.d.ts +20 -3
- package/dist/server/src/routes/debug-bundle-routes.d.ts +6 -1
- 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/index.d.ts +3 -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/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,36 @@ localazy: {
|
|
|
71
71
|
},
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
## 🔐 Access control (RBAC)
|
|
75
|
+
|
|
76
|
+
The plugin registers four Strapi permission actions, all visible under
|
|
77
|
+
**Settings → Administration Panel → Roles → Plugins → Localazy** (grouped
|
|
78
|
+
by `General` and `Settings` sub-categories):
|
|
79
|
+
|
|
80
|
+
| Action | Unlocks |
|
|
81
|
+
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `Localazy → Read` (`plugin::localazy.read`) | Localazy menu link, Overview, Activity Logs (list + detail), Content-Manager side panel & Localazy status column, read endpoints (identity, project, models, plugin settings, **content-transfer-setup**, sync cursor, activity logs, troubleshooting bundle, entry-exclusion state). |
|
|
83
|
+
| `Localazy → Transfer` (`plugin::localazy.transfer`) | Upload, Download, Entry Exclusion mutations (incl. Content-Manager bulk actions), Activity Log session clearing. Reading the content-transfer-setup is bundled under `Read` above so transfer-only roles can still open the Upload/Download pages. |
|
|
84
|
+
| `Localazy → Settings → Read` (`plugin::localazy.settings.read`) | Adds the Localazy Settings menu links (Global Settings, Content Transfer Setup) to the admin sidebar. Form controls render read-only — Save, Cancel, the Content Transfer Setup tree, and the webhook setup buttons are disabled without `Settings → Update`. |
|
|
85
|
+
| `Localazy → Settings → Update` (`plugin::localazy.settings.update`) | **Connecting / disconnecting the Localazy account**, webhook setup, updating Content Transfer Setup, and updating Global Settings. |
|
|
86
|
+
|
|
87
|
+
> **Note:** the **Webhook author** picker in _Localazy Settings → Global
|
|
88
|
+
> Settings_ populates from Strapi's core `/admin/users` endpoint, which is
|
|
89
|
+
> gated by Strapi's own `admin::users.read` permission — independent of the
|
|
90
|
+
> plugin's actions. A role with only the plugin's `Settings → Read` will
|
|
91
|
+
> still see the rest of the page; the author dropdown silently falls back
|
|
92
|
+
> to an empty list.
|
|
93
|
+
|
|
94
|
+
Server is the enforcement perimeter — all admin-typed plugin routes are
|
|
95
|
+
gated by `admin::hasPermissions`, so UI gates are convenience only.
|
|
96
|
+
|
|
97
|
+
### Upgrade note
|
|
98
|
+
|
|
99
|
+
Strapi grants new actions to the **Super Admin** role automatically. **Other
|
|
100
|
+
roles (Editor, Author, custom roles) keep no Localazy access until an admin
|
|
101
|
+
re-grants the actions** under _Settings → Administration Panel → Roles →
|
|
102
|
+
Plugins → Localazy_. Plan this step when upgrading from `<= 1.4.x`.
|
|
103
|
+
|
|
74
104
|
## 🛟 Support
|
|
75
105
|
|
|
76
106
|
If you encounter any issues or have questions, feel free to contact us through whichever channel suits you best:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-
|
|
2
|
-
import {
|
|
1
|
+
import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-IiMEtDoH.mjs";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { c as Flex, L as Loader, V as darkTheme, W as lightTheme } from "./index-shryj0jT.mjs";
|
|
4
|
+
import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
|
|
3
5
|
import { createGlobalStyle } from "styled-components";
|
|
4
6
|
import { useState, useMemo, createContext, useContext, useEffect } from "react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
const emptyIdentity = {
|
|
7
8
|
accessToken: "",
|
|
8
9
|
project: {
|
|
@@ -72,6 +73,17 @@ class PluginSettingsService {
|
|
|
72
73
|
throw e;
|
|
73
74
|
}
|
|
74
75
|
}
|
|
76
|
+
// Read-gated counterpart for per-user UI prefs (last visited route, sort
|
|
77
|
+
// prefs). Server filters the body to a fixed allowlist; sending anything else
|
|
78
|
+
// is silently dropped, so callers must only pass UI-pref fields here.
|
|
79
|
+
static async updatePluginSettingsUiPrefs(data) {
|
|
80
|
+
try {
|
|
81
|
+
const result = await axiosInstance.put(`${BASE_PATH$1}/ui-prefs`, data);
|
|
82
|
+
return result.data;
|
|
83
|
+
} catch (e) {
|
|
84
|
+
throw e;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
75
87
|
static async getSyncCursor() {
|
|
76
88
|
try {
|
|
77
89
|
const result = await axiosInstance.get(`${BASE_PATH$1}/sync-cursor`);
|
|
@@ -81,6 +93,10 @@ class PluginSettingsService {
|
|
|
81
93
|
}
|
|
82
94
|
}
|
|
83
95
|
}
|
|
96
|
+
function PluginPageLoader() {
|
|
97
|
+
const { t } = useTranslation();
|
|
98
|
+
return /* @__PURE__ */ jsx(Flex, { marginTop: 10, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx(Loader, { children: t("common.loading_content") }) });
|
|
99
|
+
}
|
|
84
100
|
const BASE_PATH = "/user";
|
|
85
101
|
const strapiApiInstance = createStrapiApiAxiosInstance();
|
|
86
102
|
class LocalazyUserService {
|
|
@@ -501,9 +517,9 @@ function cacheHas(cache, key) {
|
|
|
501
517
|
return cache.has(key);
|
|
502
518
|
}
|
|
503
519
|
var Set = getNative(root, "Set");
|
|
504
|
-
function setToArray(
|
|
505
|
-
var index = -1, result = Array(
|
|
506
|
-
|
|
520
|
+
function setToArray(set) {
|
|
521
|
+
var index = -1, result = Array(set.size);
|
|
522
|
+
set.forEach(function(value) {
|
|
507
523
|
result[++index] = value;
|
|
508
524
|
});
|
|
509
525
|
return result;
|
|
@@ -937,32 +953,6 @@ var CLONE_DEEP_FLAG = 1, CLONE_SYMBOLS_FLAG = 4;
|
|
|
937
953
|
function cloneDeep(value) {
|
|
938
954
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
|
939
955
|
}
|
|
940
|
-
function baseSet(object, path, value, customizer) {
|
|
941
|
-
if (!isObject(object)) {
|
|
942
|
-
return object;
|
|
943
|
-
}
|
|
944
|
-
path = castPath(path, object);
|
|
945
|
-
var index = -1, length = path.length, lastIndex = length - 1, nested = object;
|
|
946
|
-
while (nested != null && ++index < length) {
|
|
947
|
-
var key = toKey(path[index]), newValue = value;
|
|
948
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
949
|
-
return object;
|
|
950
|
-
}
|
|
951
|
-
if (index != lastIndex) {
|
|
952
|
-
var objValue = nested[key];
|
|
953
|
-
newValue = void 0;
|
|
954
|
-
if (newValue === void 0) {
|
|
955
|
-
newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {};
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
assignValue(nested, key, newValue);
|
|
959
|
-
nested = nested[key];
|
|
960
|
-
}
|
|
961
|
-
return object;
|
|
962
|
-
}
|
|
963
|
-
function set(object, path, value) {
|
|
964
|
-
return object == null ? object : baseSet(object, path, value);
|
|
965
|
-
}
|
|
966
956
|
const FetchIdentity = () => {
|
|
967
957
|
const { setIdentity, setIsFetchingIdentity } = useLocalazyIdentity();
|
|
968
958
|
useEffect(() => {
|
|
@@ -991,10 +981,10 @@ export {
|
|
|
991
981
|
PluginSettingsService as P,
|
|
992
982
|
SetCache as S,
|
|
993
983
|
Uint8Array as U,
|
|
994
|
-
|
|
995
|
-
|
|
984
|
+
PluginPageLoader as a,
|
|
985
|
+
cacheHas as b,
|
|
996
986
|
cloneDeep as c,
|
|
997
|
-
|
|
987
|
+
Symbol$1 as d,
|
|
998
988
|
eq as e,
|
|
999
989
|
getAllKeys as f,
|
|
1000
990
|
getDefaultTheme as g,
|
|
@@ -1004,15 +994,17 @@ export {
|
|
|
1004
994
|
isTypedArray as k,
|
|
1005
995
|
isArray as l,
|
|
1006
996
|
isObjectLike as m,
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
997
|
+
isObject as n,
|
|
998
|
+
castPath as o,
|
|
999
|
+
isIndex as p,
|
|
1000
|
+
assignValue as q,
|
|
1001
|
+
keys as r,
|
|
1002
|
+
setToArray as s,
|
|
1013
1003
|
toKey as t,
|
|
1014
1004
|
useLocalazyIdentity as u,
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1005
|
+
isArrayLike as v,
|
|
1006
|
+
arrayEach as w,
|
|
1007
|
+
Set as x,
|
|
1008
|
+
LocalazyUserService as y,
|
|
1009
|
+
emptyIdentity as z
|
|
1018
1010
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const strapiApiBase = require("./strapi-api-base-
|
|
2
|
+
const strapiApiBase = require("./strapi-api-base-CCUuu7EY.js");
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
4
|
const index = require("./index-CTkxoioB.js");
|
|
5
|
+
const useTranslation = require("./useTranslation-BdIl-aLe.js");
|
|
4
6
|
const styled = require("styled-components");
|
|
5
7
|
const React = require("react");
|
|
6
|
-
const jsxRuntime = require("react/jsx-runtime");
|
|
7
8
|
const emptyIdentity = {
|
|
8
9
|
accessToken: "",
|
|
9
10
|
project: {
|
|
@@ -73,6 +74,17 @@ class PluginSettingsService {
|
|
|
73
74
|
throw e;
|
|
74
75
|
}
|
|
75
76
|
}
|
|
77
|
+
// Read-gated counterpart for per-user UI prefs (last visited route, sort
|
|
78
|
+
// prefs). Server filters the body to a fixed allowlist; sending anything else
|
|
79
|
+
// is silently dropped, so callers must only pass UI-pref fields here.
|
|
80
|
+
static async updatePluginSettingsUiPrefs(data) {
|
|
81
|
+
try {
|
|
82
|
+
const result = await axiosInstance.put(`${BASE_PATH$1}/ui-prefs`, data);
|
|
83
|
+
return result.data;
|
|
84
|
+
} catch (e) {
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
76
88
|
static async getSyncCursor() {
|
|
77
89
|
try {
|
|
78
90
|
const result = await axiosInstance.get(`${BASE_PATH$1}/sync-cursor`);
|
|
@@ -82,6 +94,10 @@ class PluginSettingsService {
|
|
|
82
94
|
}
|
|
83
95
|
}
|
|
84
96
|
}
|
|
97
|
+
function PluginPageLoader() {
|
|
98
|
+
const { t } = useTranslation.useTranslation();
|
|
99
|
+
return /* @__PURE__ */ jsxRuntime.jsx(index.Flex, { marginTop: 10, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(index.Loader, { children: t("common.loading_content") }) });
|
|
100
|
+
}
|
|
85
101
|
const BASE_PATH = "/user";
|
|
86
102
|
const strapiApiInstance = strapiApiBase.createStrapiApiAxiosInstance();
|
|
87
103
|
class LocalazyUserService {
|
|
@@ -502,9 +518,9 @@ function cacheHas(cache, key) {
|
|
|
502
518
|
return cache.has(key);
|
|
503
519
|
}
|
|
504
520
|
var Set = getNative(root, "Set");
|
|
505
|
-
function setToArray(
|
|
506
|
-
var index2 = -1, result = Array(
|
|
507
|
-
|
|
521
|
+
function setToArray(set) {
|
|
522
|
+
var index2 = -1, result = Array(set.size);
|
|
523
|
+
set.forEach(function(value) {
|
|
508
524
|
result[++index2] = value;
|
|
509
525
|
});
|
|
510
526
|
return result;
|
|
@@ -938,32 +954,6 @@ var CLONE_DEEP_FLAG = 1, CLONE_SYMBOLS_FLAG = 4;
|
|
|
938
954
|
function cloneDeep(value) {
|
|
939
955
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
|
940
956
|
}
|
|
941
|
-
function baseSet(object, path, value, customizer) {
|
|
942
|
-
if (!isObject(object)) {
|
|
943
|
-
return object;
|
|
944
|
-
}
|
|
945
|
-
path = castPath(path, object);
|
|
946
|
-
var index2 = -1, length = path.length, lastIndex = length - 1, nested = object;
|
|
947
|
-
while (nested != null && ++index2 < length) {
|
|
948
|
-
var key = toKey(path[index2]), newValue = value;
|
|
949
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
950
|
-
return object;
|
|
951
|
-
}
|
|
952
|
-
if (index2 != lastIndex) {
|
|
953
|
-
var objValue = nested[key];
|
|
954
|
-
newValue = void 0;
|
|
955
|
-
if (newValue === void 0) {
|
|
956
|
-
newValue = isObject(objValue) ? objValue : isIndex(path[index2 + 1]) ? [] : {};
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
assignValue(nested, key, newValue);
|
|
960
|
-
nested = nested[key];
|
|
961
|
-
}
|
|
962
|
-
return object;
|
|
963
|
-
}
|
|
964
|
-
function set(object, path, value) {
|
|
965
|
-
return object == null ? object : baseSet(object, path, value);
|
|
966
|
-
}
|
|
967
957
|
const FetchIdentity = () => {
|
|
968
958
|
const { setIdentity, setIsFetchingIdentity } = useLocalazyIdentity();
|
|
969
959
|
React.useEffect(() => {
|
|
@@ -989,6 +979,7 @@ exports.FetchIdentity = FetchIdentity;
|
|
|
989
979
|
exports.HeadingFixGlobalStyle = HeadingFixGlobalStyle;
|
|
990
980
|
exports.LocalazyIdentityProvider = LocalazyIdentityProvider;
|
|
991
981
|
exports.LocalazyUserService = LocalazyUserService;
|
|
982
|
+
exports.PluginPageLoader = PluginPageLoader;
|
|
992
983
|
exports.PluginSettingsService = PluginSettingsService;
|
|
993
984
|
exports.Set = Set;
|
|
994
985
|
exports.SetCache = SetCache;
|
|
@@ -996,6 +987,7 @@ exports.Stack = Stack;
|
|
|
996
987
|
exports.Symbol = Symbol$1;
|
|
997
988
|
exports.Uint8Array = Uint8Array;
|
|
998
989
|
exports.arrayEach = arrayEach;
|
|
990
|
+
exports.assignValue = assignValue;
|
|
999
991
|
exports.cacheHas = cacheHas;
|
|
1000
992
|
exports.castPath = castPath;
|
|
1001
993
|
exports.cloneDeep = cloneDeep;
|
|
@@ -1006,11 +998,11 @@ exports.getDefaultTheme = getDefaultTheme;
|
|
|
1006
998
|
exports.isArray = isArray;
|
|
1007
999
|
exports.isArrayLike = isArrayLike;
|
|
1008
1000
|
exports.isBuffer = isBuffer;
|
|
1001
|
+
exports.isIndex = isIndex;
|
|
1009
1002
|
exports.isObject = isObject;
|
|
1010
1003
|
exports.isObjectLike = isObjectLike;
|
|
1011
1004
|
exports.isTypedArray = isTypedArray;
|
|
1012
1005
|
exports.keys = keys;
|
|
1013
|
-
exports.set = set;
|
|
1014
1006
|
exports.setToArray = setToArray;
|
|
1015
1007
|
exports.toKey = toKey;
|
|
1016
1008
|
exports.useLocalazyIdentity = useLocalazyIdentity;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-
|
|
1
|
+
import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-IiMEtDoH.mjs";
|
|
2
2
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect } from "react";
|
|
4
|
-
import { c as cloneDeep } from "./FetchIdentity-
|
|
5
|
-
import { F as Field, M as MultiSelect, b as MultiSelectOption } from "./index-
|
|
4
|
+
import { c as cloneDeep } from "./FetchIdentity-Bm7bc5bS.mjs";
|
|
5
|
+
import { F as Field, M as MultiSelect, b as MultiSelectOption } from "./index-shryj0jT.mjs";
|
|
6
6
|
import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
|
|
7
7
|
const strapiApiInstance = createStrapiApiAxiosInstance();
|
|
8
8
|
class ProjectService {
|
|
@@ -48,6 +48,7 @@ const LanguagesSelector = (props) => {
|
|
|
48
48
|
onClear: () => setSelectedLanguages([]),
|
|
49
49
|
value: selectedLanguages || [],
|
|
50
50
|
onChange: (values) => onChange(values),
|
|
51
|
+
disabled: props.disabled,
|
|
51
52
|
multi: true,
|
|
52
53
|
withTags: true,
|
|
53
54
|
children: props.projectLanguages.map((lang) => /* @__PURE__ */ jsx(MultiSelectOption, { value: lang.code, children: `${lang.name} (${lang.code})` }, lang.id))
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const strapiApiBase = require("./strapi-api-base-
|
|
2
|
+
const strapiApiBase = require("./strapi-api-base-CCUuu7EY.js");
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const React = require("react");
|
|
5
|
-
const FetchIdentity = require("./FetchIdentity-
|
|
5
|
+
const FetchIdentity = require("./FetchIdentity-CcEjakiz.js");
|
|
6
6
|
const index = require("./index-CTkxoioB.js");
|
|
7
7
|
const useTranslation = require("./useTranslation-BdIl-aLe.js");
|
|
8
8
|
const strapiApiInstance = strapiApiBase.createStrapiApiAxiosInstance();
|
|
@@ -49,6 +49,7 @@ const LanguagesSelector = (props) => {
|
|
|
49
49
|
onClear: () => setSelectedLanguages([]),
|
|
50
50
|
value: selectedLanguages || [],
|
|
51
51
|
onChange: (values) => onChange(values),
|
|
52
|
+
disabled: props.disabled,
|
|
52
53
|
multi: true,
|
|
53
54
|
withTags: true,
|
|
54
55
|
children: props.projectLanguages.map((lang) => /* @__PURE__ */ jsxRuntime.jsx(index.MultiSelectOption, { value: lang.code, children: `${lang.name} (${lang.code})` }, lang.id))
|
|
@@ -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
|
),
|
|
@@ -6136,6 +6143,10 @@ const App = () => {
|
|
|
6136
6143
|
const { isLoggedIn, isFetchingIdentity } = useLocalazyIdentity();
|
|
6137
6144
|
const headerTitle = useHeaderTitle();
|
|
6138
6145
|
const headerSubtitle = useHeaderSubtitle();
|
|
6146
|
+
const {
|
|
6147
|
+
allowedActions: { canRead, canTransfer },
|
|
6148
|
+
isLoading: isLoadingPermissions
|
|
6149
|
+
} = useRBAC([...PERMISSIONS.READ, ...PERMISSIONS.TRANSFER]);
|
|
6139
6150
|
const normalizedPath = location2.pathname.replace(/\/+$/, "");
|
|
6140
6151
|
const pluginRoot = `/plugins/${PLUGIN_ID}`;
|
|
6141
6152
|
const isAtPluginRoot = normalizedPath === pluginRoot;
|
|
@@ -6157,6 +6168,19 @@ const App = () => {
|
|
|
6157
6168
|
};
|
|
6158
6169
|
void fetchData();
|
|
6159
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, {});
|
|
6160
6184
|
return /* @__PURE__ */ jsxs(DesignSystemProvider, { theme: getDefaultTheme(), children: [
|
|
6161
6185
|
/* @__PURE__ */ jsx(HeadingFixGlobalStyle, {}),
|
|
6162
6186
|
/* @__PURE__ */ jsx(PluginErrorBoundary, { children: /* @__PURE__ */ jsx(Box, { background: "neutral100", children: /* @__PURE__ */ jsxs(Layouts.Root, { sideNav: isLoggedIn && /* @__PURE__ */ jsx(SideNav, {}), children: [
|
|
@@ -6176,8 +6200,20 @@ const App = () => {
|
|
|
6176
6200
|
element: /* @__PURE__ */ jsx(Overview, { title: headerTitle, subtitle: headerSubtitle, isLoadingProp: false })
|
|
6177
6201
|
}
|
|
6178
6202
|
),
|
|
6179
|
-
/* @__PURE__ */ jsx(
|
|
6180
|
-
|
|
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
|
+
),
|
|
6181
6217
|
/* @__PURE__ */ jsx(Route, { path: `activity-logs`, element: /* @__PURE__ */ jsx(ActivityLogs, { title: headerTitle, subtitle: headerSubtitle }) }),
|
|
6182
6218
|
/* @__PURE__ */ jsx(
|
|
6183
6219
|
Route,
|