@localazy/strapi-plugin 1.0.10 → 1.1.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 (56) hide show
  1. package/dist/_chunks/{FetchIdentity-W-xq7F8q.js → FetchIdentity-DfV1OWMB.js} +9 -1
  2. package/dist/_chunks/{FetchIdentity-B9hYlR1E.mjs → FetchIdentity-lkoWjYjn.mjs} +9 -1
  3. package/dist/_chunks/{LanguagesSelector-Cq9JuASq.js → LanguagesSelector-BmWfSZq6.js} +3 -3
  4. package/dist/_chunks/{LanguagesSelector-zGN0icsS.mjs → LanguagesSelector-vSZvVGUT.mjs} +3 -3
  5. package/dist/_chunks/{LocalazyApp-CTMwUa44.js → LocalazyApp-BUfYt7UL.js} +91 -27
  6. package/dist/_chunks/{LocalazyApp-CxQTCwbi.mjs → LocalazyApp-st8mwIbM.mjs} +91 -27
  7. package/dist/_chunks/{LocalazyContentTransferSetup-DhSv2HJo.js → LocalazyContentTransferSetup-BjLBgqFO.js} +5 -5
  8. package/dist/_chunks/{LocalazyContentTransferSetup-DOHIserI.mjs → LocalazyContentTransferSetup-D2YvBYs_.mjs} +5 -5
  9. package/dist/_chunks/{LocalazyGlobalSettings-DCFs8AA1.mjs → LocalazyGlobalSettings-DHCU2_RH.mjs} +22 -7
  10. package/dist/_chunks/{LocalazyGlobalSettings-D7fyS9ih.js → LocalazyGlobalSettings-Do5tOyhB.js} +22 -7
  11. package/dist/_chunks/{LocalazyPanel-CDgAmxqx.js → LocalazyPanel-BDxUI_RH.js} +3 -3
  12. package/dist/_chunks/{LocalazyPanel-N7__R7p9.mjs → LocalazyPanel-CulgT97p.mjs} +3 -3
  13. package/dist/_chunks/{LocalazyStatusColumn-CuGDwwZ8.mjs → LocalazyStatusColumn-DoTWD2eL.mjs} +2 -2
  14. package/dist/_chunks/{LocalazyStatusColumn-CTjBaBqb.js → LocalazyStatusColumn-Dpwoc5Ig.js} +2 -2
  15. package/dist/_chunks/{RequireLocalazyAuth-BDtwyPLH.js → RequireLocalazyAuth-BzM7C6Yw.js} +12 -5
  16. package/dist/_chunks/{RequireLocalazyAuth-BmimcHYI.mjs → RequireLocalazyAuth-CqHrZ1Ah.mjs} +12 -5
  17. package/dist/_chunks/{entry-exclusion-service-BZkbrd3B.js → entry-exclusion-service-Cvu8PQUI.js} +1 -1
  18. package/dist/_chunks/{entry-exclusion-service-COp5ZXUY.mjs → entry-exclusion-service-DWFMKgkA.mjs} +1 -1
  19. package/dist/_chunks/{has-model-changed-K3Z8BNhV.mjs → has-model-changed-CWdMNRB1.mjs} +2 -2
  20. package/dist/_chunks/{has-model-changed-BXqyvCRA.js → has-model-changed-D1f6is8z.js} +2 -2
  21. package/dist/_chunks/{i18n-RoETLXdU.mjs → i18n-Bga-GG_Z.mjs} +8 -1
  22. package/dist/_chunks/{i18n-0dV2P-Hm.js → i18n-DaBjUC3Y.js} +8 -1
  23. package/dist/_chunks/{index-CgI_aKe_.mjs → index-BIHAiJnE.mjs} +60 -8
  24. package/dist/_chunks/{index-CaY3BYnQ.js → index-BSNW1ypR.js} +59 -7
  25. package/dist/_chunks/{index-BtofOkFA.js → index-BgPI2yQD.js} +8 -8
  26. package/dist/_chunks/{index-B_KJR1Xk.mjs → index-CtvR-R3c.mjs} +8 -8
  27. package/dist/_chunks/{strapi-api-base-S2_cFlNu.js → strapi-api-base-CN6q5tPh.js} +1 -1
  28. package/dist/_chunks/{strapi-api-base-BfIxEUh2.mjs → strapi-api-base-CturxOqD.mjs} +1 -1
  29. package/dist/admin/index.js +1 -1
  30. package/dist/admin/index.mjs +1 -1
  31. package/dist/admin/src/modules/@common/components/TransferReport.d.ts +8 -1
  32. package/dist/admin/src/modules/@common/services/product-analytics-service.d.ts +1 -0
  33. package/dist/admin/src/modules/localazy-download/locale/en.d.ts +5 -0
  34. package/dist/admin/src/modules/plugin-settings/locale/en.d.ts +2 -0
  35. package/dist/admin/src/modules/plugin-settings/services/plugin-settings-service.d.ts +1 -0
  36. package/dist/server/index.js +4643 -4394
  37. package/dist/server/index.mjs +4642 -4393
  38. package/dist/server/src/controllers/index.d.ts +5 -4
  39. package/dist/server/src/controllers/localazy-auth-controller.d.ts +1 -1
  40. package/dist/server/src/controllers/localazy-project-controller.d.ts +1 -1
  41. package/dist/server/src/controllers/localazy-user-controller.d.ts +1 -1
  42. package/dist/server/src/controllers/plugin-settings-controller.d.ts +2 -1
  43. package/dist/server/src/core/index.d.ts +9 -5
  44. package/dist/server/src/db/model/sync-cursor.d.ts +9 -0
  45. package/dist/server/src/destroy.d.ts +1 -1
  46. package/dist/server/src/index.d.ts +15 -10
  47. package/dist/server/src/services/helpers/plugin-settings-service-helper.d.ts +1 -0
  48. package/dist/server/src/services/index.d.ts +9 -5
  49. package/dist/server/src/services/localazy-transfer-download-service.d.ts +2 -1
  50. package/dist/server/src/services/plugin-settings-service.d.ts +3 -0
  51. package/dist/server/src/services/strapi-i18n-service.d.ts +2 -2
  52. package/dist/server/src/services/strapi-localazy-i18n-service.d.ts +2 -2
  53. package/dist/server/src/services/strapi-service.d.ts +1 -0
  54. package/dist/server/src/utils/get-character-limits-metadata.d.ts +13 -0
  55. package/dist/server/src/utils/get-picked-flatten-keys-for-hook-entry.d.ts +3 -1
  56. package/package.json +6 -5
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const strapiApiBase = require("./strapi-api-base-S2_cFlNu.js");
2
+ const strapiApiBase = require("./strapi-api-base-CN6q5tPh.js");
3
3
  const React = require("react");
4
4
  const jsxRuntime = require("react/jsx-runtime");
5
5
  const emptyIdentity = {
@@ -71,6 +71,14 @@ class PluginSettingsService {
71
71
  throw e;
72
72
  }
73
73
  }
74
+ static async getSyncCursor() {
75
+ try {
76
+ const result = await axiosInstance.get(`${BASE_PATH$1}/sync-cursor`);
77
+ return result.data;
78
+ } catch (e) {
79
+ throw e;
80
+ }
81
+ }
74
82
  }
75
83
  const BASE_PATH = "/user";
76
84
  const strapiApiInstance = strapiApiBase.createStrapiApiAxiosInstance();
@@ -1,4 +1,4 @@
1
- import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-BfIxEUh2.mjs";
1
+ import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-CturxOqD.mjs";
2
2
  import { useState, useMemo, createContext, useContext, useEffect } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  const emptyIdentity = {
@@ -70,6 +70,14 @@ class PluginSettingsService {
70
70
  throw e;
71
71
  }
72
72
  }
73
+ static async getSyncCursor() {
74
+ try {
75
+ const result = await axiosInstance.get(`${BASE_PATH$1}/sync-cursor`);
76
+ return result.data;
77
+ } catch (e) {
78
+ throw e;
79
+ }
80
+ }
73
81
  }
74
82
  const BASE_PATH = "/user";
75
83
  const strapiApiInstance = createStrapiApiAxiosInstance();
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- const strapiApiBase = require("./strapi-api-base-S2_cFlNu.js");
2
+ const strapiApiBase = require("./strapi-api-base-CN6q5tPh.js");
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const FetchIdentity = require("./FetchIdentity-W-xq7F8q.js");
6
- const index = require("./index-CaY3BYnQ.js");
5
+ const FetchIdentity = require("./FetchIdentity-DfV1OWMB.js");
6
+ const index = require("./index-BSNW1ypR.js");
7
7
  const useTranslation = require("./useTranslation-BdIl-aLe.js");
8
8
  const strapiApiInstance = strapiApiBase.createStrapiApiAxiosInstance();
9
9
  class ProjectService {
@@ -1,8 +1,8 @@
1
- import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-BfIxEUh2.mjs";
1
+ import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-CturxOqD.mjs";
2
2
  import { jsxs, jsx } from "react/jsx-runtime";
3
3
  import { useState, useEffect } from "react";
4
- import { c as cloneDeep } from "./FetchIdentity-B9hYlR1E.mjs";
5
- import { F as Field, M as MultiSelect, b as MultiSelectOption } from "./index-CgI_aKe_.mjs";
4
+ import { c as cloneDeep } from "./FetchIdentity-lkoWjYjn.mjs";
5
+ import { F as Field, M as MultiSelect, b as MultiSelectOption } from "./index-BIHAiJnE.mjs";
6
6
  import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
7
7
  const strapiApiInstance = createStrapiApiAxiosInstance();
8
8
  class ProjectService {
@@ -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-CaY3BYnQ.js");
5
+ const index$1 = require("./index-BSNW1ypR.js");
6
6
  const React = require("react");
7
- const FetchIdentity = require("./FetchIdentity-W-xq7F8q.js");
8
- const index = require("./index-BtofOkFA.js");
7
+ const FetchIdentity = require("./FetchIdentity-DfV1OWMB.js");
8
+ const index = require("./index-BgPI2yQD.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-S2_cFlNu.js");
12
- const LanguagesSelector = require("./LanguagesSelector-Cq9JuASq.js");
11
+ const strapiApiBase = require("./strapi-api-base-CN6q5tPh.js");
12
+ const LanguagesSelector = require("./LanguagesSelector-BmWfSZq6.js");
13
13
  const admin = require("@strapi/strapi/admin");
14
- require("./i18n-0dV2P-Hm.js");
15
- const hasModelChanged = require("./has-model-changed-BXqyvCRA.js");
14
+ require("./i18n-DaBjUC3Y.js");
15
+ const hasModelChanged = require("./has-model-changed-D1f6is8z.js");
16
16
  var PLUGIN_ROUTES = /* @__PURE__ */ ((PLUGIN_ROUTES2) => {
17
17
  PLUGIN_ROUTES2["ROOT"] = "";
18
18
  PLUGIN_ROUTES2["LOGIN"] = "login";
@@ -1356,13 +1356,14 @@ class ProductAnalyticsService {
1356
1356
  }
1357
1357
  }
1358
1358
  static async buildData(event, project, params) {
1359
- const { version } = await PluginService.getPluginVersion();
1359
+ const { version, versionStrapi } = await PluginService.getPluginVersion();
1360
1360
  return {
1361
1361
  event,
1362
1362
  data: {
1363
1363
  "Project Id": project.id,
1364
1364
  "Project Name": project.name,
1365
1365
  version,
1366
+ versionStrapi,
1366
1367
  ...params
1367
1368
  }
1368
1369
  };
@@ -1576,6 +1577,19 @@ const areLocalesCompatible = async (defaultLocale = null, sourceLanguage = null)
1576
1577
  return false;
1577
1578
  }
1578
1579
  };
1580
+ const TransferReportItem = ({ item }) => {
1581
+ if (typeof item === "string") {
1582
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: item });
1583
+ }
1584
+ const { message, links } = item;
1585
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1586
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "omega", children: message }),
1587
+ links && /* @__PURE__ */ jsxRuntime.jsxs(index$1.Box, { paddingTop: 2, children: [
1588
+ links.strapi && /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "pi", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: links.strapi, target: "_blank", rel: "noopener noreferrer", style: { marginRight: "12px" }, children: "Open in Strapi" }) }),
1589
+ links.localazy && /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "pi", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: links.localazy, target: "_blank", rel: "noopener noreferrer", children: "View in Localazy" }) })
1590
+ ] })
1591
+ ] });
1592
+ };
1579
1593
  const TransferReport = (props) => {
1580
1594
  const { t: t2 } = useTranslation.useTranslation();
1581
1595
  const [reportLocal, setReportLocal] = React.useState(props.report);
@@ -1591,7 +1605,17 @@ const TransferReport = (props) => {
1591
1605
  return null;
1592
1606
  }
1593
1607
  return reportLocal.map((item, index2) => {
1594
- return /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Alert, { onClose: () => onCloseItem(index2), closeLabel: t2("upload.close"), variant: "default", children: item }, index2) }, index2);
1608
+ const hasLinks = typeof item !== "string" && item.links;
1609
+ return /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
1610
+ index$1.Alert,
1611
+ {
1612
+ onClose: () => onCloseItem(index2),
1613
+ closeLabel: t2("upload.close"),
1614
+ variant: hasLinks ? "danger" : "default",
1615
+ children: /* @__PURE__ */ jsxRuntime.jsx(TransferReportItem, { item })
1616
+ },
1617
+ index2
1618
+ ) }, index2);
1595
1619
  });
1596
1620
  };
1597
1621
  const ReadDocsButton = () => {
@@ -5123,6 +5147,8 @@ const Download = (props) => {
5123
5147
  report: []
5124
5148
  });
5125
5149
  const [isDownloading, setIsDownloading] = React.useState(false);
5150
+ const [hasSyncCursor, setHasSyncCursor] = React.useState(false);
5151
+ const [showFullSyncConfirm, setShowFullSyncConfirm] = React.useState(false);
5126
5152
  const onTranslateInLocalazyClick = () => {
5127
5153
  window.open(identity.project.url, "_blank");
5128
5154
  };
@@ -5138,29 +5164,34 @@ const Download = (props) => {
5138
5164
  console.error(e2.message);
5139
5165
  }
5140
5166
  };
5141
- const onDownloadClick = async () => {
5167
+ const onDownloadClick = async (fullSync = false) => {
5142
5168
  setIsDownloading(true);
5143
5169
  setshowDownloadFinishedModal(false);
5144
5170
  setDownloadResult({
5145
5171
  success: false,
5146
5172
  report: []
5147
5173
  });
5148
- const result = await LocalazyDownloadService.download();
5174
+ const result = await LocalazyDownloadService.download({ fullSync });
5149
5175
  const { streamIdentifier } = result;
5150
5176
  downloadAlertsService.setStreamIdentifier(streamIdentifier);
5151
5177
  downloadAlertsService.onDownload((data) => {
5152
5178
  setDownloadResult((old) => ({
5153
5179
  success: data.success,
5154
- report: [...old.report || [], data.message]
5180
+ report: [...old.report || [], { message: data.message, links: data.links }]
5155
5181
  }));
5156
5182
  });
5157
- downloadAlertsService.onDownloadFinished((data) => {
5183
+ downloadAlertsService.onDownloadFinished(async (data) => {
5158
5184
  setDownloadResult((old) => ({
5159
5185
  success: data.success,
5160
- report: [...old.report || [], data.message]
5186
+ report: [...old.report || [], { message: data.message, links: data.links }]
5161
5187
  }));
5162
5188
  setIsDownloading(false);
5163
5189
  setshowDownloadFinishedModal(true);
5190
+ try {
5191
+ const cursor = await FetchIdentity.PluginSettingsService.getSyncCursor();
5192
+ setHasSyncCursor(cursor?.processedKeys !== void 0 && Object.keys(cursor.processedKeys).length > 0);
5193
+ } catch {
5194
+ }
5164
5195
  });
5165
5196
  ProductAnalyticsService.trackDownloadToStrapi(identity.user.id, identity.project, {
5166
5197
  "Target Languages Codes": "all"
@@ -5169,14 +5200,16 @@ const Download = (props) => {
5169
5200
  React.useEffect(() => {
5170
5201
  async function initComponent() {
5171
5202
  setIsLoading(true);
5172
- const [modelChangedResult, localesCompatibleResult, project, globalSettings] = await Promise.all([
5203
+ const [modelChangedResult, localesCompatibleResult, project, globalSettings, syncCursor] = await Promise.all([
5173
5204
  hasModelChanged.hasModelChanged(),
5174
5205
  areLocalesCompatible(),
5175
5206
  LanguagesSelector.ProjectService.getConnectedProject(),
5176
- FetchIdentity.PluginSettingsService.getPluginSettings()
5207
+ FetchIdentity.PluginSettingsService.getPluginSettings(),
5208
+ FetchIdentity.PluginSettingsService.getSyncCursor()
5177
5209
  ]);
5178
5210
  setModelChanged(modelChangedResult);
5179
5211
  setLocalesIncompatible(!localesCompatibleResult);
5212
+ setHasSyncCursor(syncCursor?.processedKeys !== void 0 && Object.keys(syncCursor.processedKeys).length > 0);
5180
5213
  const projectLanguagesWithoutDefaultLanguage = project?.languages?.filter((language) => language.id !== project.sourceLanguage) || [];
5181
5214
  setProjectLanguages(projectLanguagesWithoutDefaultLanguage);
5182
5215
  setFormModel(globalSettings);
@@ -5191,16 +5224,28 @@ const Download = (props) => {
5191
5224
  {
5192
5225
  title: props.title,
5193
5226
  subtitle: props.subtitle,
5194
- primaryAction: /* @__PURE__ */ jsxRuntime.jsx(
5195
- index$1.Button,
5196
- {
5197
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$3P, {}),
5198
- disabled: isLoading || modelChanged || localesIncompatible,
5199
- loading: isDownloading,
5200
- onClick: onDownloadClick,
5201
- children: t2("download.download_to_strapi")
5202
- }
5203
- ),
5227
+ primaryAction: /* @__PURE__ */ jsxRuntime.jsxs(index$1.Flex, { gap: 2, children: [
5228
+ /* @__PURE__ */ jsxRuntime.jsx(
5229
+ index$1.Button,
5230
+ {
5231
+ variant: "secondary",
5232
+ disabled: isLoading || modelChanged || localesIncompatible,
5233
+ loading: isDownloading,
5234
+ onClick: () => setShowFullSyncConfirm(true),
5235
+ children: t2("download.full_sync")
5236
+ }
5237
+ ),
5238
+ /* @__PURE__ */ jsxRuntime.jsx(
5239
+ index$1.Button,
5240
+ {
5241
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(index$1.ForwardRef$3P, {}),
5242
+ disabled: isLoading || modelChanged || localesIncompatible || !hasSyncCursor,
5243
+ loading: isDownloading,
5244
+ onClick: () => onDownloadClick(false),
5245
+ children: t2("download.incremental_download")
5246
+ }
5247
+ )
5248
+ ] }),
5204
5249
  as: "h2"
5205
5250
  }
5206
5251
  ),
@@ -5274,8 +5319,27 @@ const Download = (props) => {
5274
5319
  children: t2("download.please_update_your_content")
5275
5320
  }
5276
5321
  ) }),
5322
+ !hasSyncCursor && /* @__PURE__ */ jsxRuntime.jsx(index$1.Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Alert, { title: t2("download.incremental_disabled_hint"), variant: "default", children: t2("download.incremental_disabled_hint") }) }),
5277
5323
  downloadResult.report && downloadResult.report.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(TransferReport, { report: downloadResult.report })
5278
- ] })
5324
+ ] }),
5325
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Dialog.Root, { open: showFullSyncConfirm, onOpenChange: setShowFullSyncConfirm, children: /* @__PURE__ */ jsxRuntime.jsxs(index$1.Dialog.Content, { children: [
5326
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Dialog.Header, { children: t2("download.full_sync_confirm_title") }),
5327
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "omega", children: t2("download.full_sync_confirm_message") }) }),
5328
+ /* @__PURE__ */ jsxRuntime.jsxs(index$1.Dialog.Footer, { children: [
5329
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(index$1.Button, { variant: "tertiary", children: t2("download.close") }) }),
5330
+ /* @__PURE__ */ jsxRuntime.jsx(index$1.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(
5331
+ index$1.Button,
5332
+ {
5333
+ variant: "danger-light",
5334
+ onClick: () => {
5335
+ setShowFullSyncConfirm(false);
5336
+ onDownloadClick(true);
5337
+ },
5338
+ children: t2("download.full_sync")
5339
+ }
5340
+ ) })
5341
+ ] })
5342
+ ] }) })
5279
5343
  ] });
5280
5344
  };
5281
5345
  const App = () => {
@@ -1,16 +1,16 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useNavigate, useLocation, NavLink, Routes, Route } from "react-router-dom";
3
- import { i as ForwardRef$2H, j as ForwardRef$d, k as ForwardRef$3P, c as Flex, L as Loader, B as Button, e as Box, T as Typography, l as Link, m as SubNav, n as SubNavHeader, o as SubNavSections, p as SubNavSection, q as SubNavLink, r as ForwardRef$L, G as Grid, D as Divider, s as darkTheme, t as lightTheme, A as Alert, u as DesignSystemProvider } from "./index-CgI_aKe_.mjs";
3
+ import { i as ForwardRef$2H, j as ForwardRef$d, k as ForwardRef$3P, c as Flex, L as Loader, B as Button, e as Box, T as Typography, l as Link, m as SubNav, n as SubNavHeader, o as SubNavSections, p as SubNavSection, q as SubNavLink, r as ForwardRef$L, G as Grid, D as Divider, s as darkTheme, t as lightTheme, A as Alert, u as Dialog, v as DesignSystemProvider } from "./index-BIHAiJnE.mjs";
4
4
  import { useState, useEffect } from "react";
5
- import { u as useLocalazyIdentity, v as LocalazyUserService, w as emptyIdentity, P as PluginSettingsService, c as cloneDeep, s as set, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-B9hYlR1E.mjs";
6
- import { P as PLUGIN_ID } from "./index-B_KJR1Xk.mjs";
5
+ import { u as useLocalazyIdentity, v as LocalazyUserService, w as emptyIdentity, P as PluginSettingsService, c as cloneDeep, s as set, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-lkoWjYjn.mjs";
6
+ import { P as PLUGIN_ID } from "./index-CtvR-R3c.mjs";
7
7
  import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
8
8
  import { g as getDefaultExportFromCjs } from "./_commonjsHelpers-DWwsNxpa.mjs";
9
- import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-BfIxEUh2.mjs";
10
- import { P as ProjectService, L as LanguagesSelector } from "./LanguagesSelector-zGN0icsS.mjs";
9
+ import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-CturxOqD.mjs";
10
+ import { P as ProjectService, L as LanguagesSelector } from "./LanguagesSelector-vSZvVGUT.mjs";
11
11
  import { Layouts, Page } from "@strapi/strapi/admin";
12
- import "./i18n-RoETLXdU.mjs";
13
- import { h as hasModelChanged } from "./has-model-changed-K3Z8BNhV.mjs";
12
+ import "./i18n-Bga-GG_Z.mjs";
13
+ import { h as hasModelChanged } from "./has-model-changed-CWdMNRB1.mjs";
14
14
  var PLUGIN_ROUTES = /* @__PURE__ */ ((PLUGIN_ROUTES2) => {
15
15
  PLUGIN_ROUTES2["ROOT"] = "";
16
16
  PLUGIN_ROUTES2["LOGIN"] = "login";
@@ -1354,13 +1354,14 @@ class ProductAnalyticsService {
1354
1354
  }
1355
1355
  }
1356
1356
  static async buildData(event, project, params) {
1357
- const { version } = await PluginService.getPluginVersion();
1357
+ const { version, versionStrapi } = await PluginService.getPluginVersion();
1358
1358
  return {
1359
1359
  event,
1360
1360
  data: {
1361
1361
  "Project Id": project.id,
1362
1362
  "Project Name": project.name,
1363
1363
  version,
1364
+ versionStrapi,
1364
1365
  ...params
1365
1366
  }
1366
1367
  };
@@ -1574,6 +1575,19 @@ const areLocalesCompatible = async (defaultLocale = null, sourceLanguage = null)
1574
1575
  return false;
1575
1576
  }
1576
1577
  };
1578
+ const TransferReportItem = ({ item }) => {
1579
+ if (typeof item === "string") {
1580
+ return /* @__PURE__ */ jsx(Fragment, { children: item });
1581
+ }
1582
+ const { message, links } = item;
1583
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1584
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: message }),
1585
+ links && /* @__PURE__ */ jsxs(Box, { paddingTop: 2, children: [
1586
+ links.strapi && /* @__PURE__ */ jsx(Typography, { variant: "pi", children: /* @__PURE__ */ jsx("a", { href: links.strapi, target: "_blank", rel: "noopener noreferrer", style: { marginRight: "12px" }, children: "Open in Strapi" }) }),
1587
+ links.localazy && /* @__PURE__ */ jsx(Typography, { variant: "pi", children: /* @__PURE__ */ jsx("a", { href: links.localazy, target: "_blank", rel: "noopener noreferrer", children: "View in Localazy" }) })
1588
+ ] })
1589
+ ] });
1590
+ };
1577
1591
  const TransferReport = (props) => {
1578
1592
  const { t: t2 } = useTranslation();
1579
1593
  const [reportLocal, setReportLocal] = useState(props.report);
@@ -1589,7 +1603,17 @@ const TransferReport = (props) => {
1589
1603
  return null;
1590
1604
  }
1591
1605
  return reportLocal.map((item, index) => {
1592
- return /* @__PURE__ */ jsx(Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsx(Alert, { onClose: () => onCloseItem(index), closeLabel: t2("upload.close"), variant: "default", children: item }, index) }, index);
1606
+ const hasLinks = typeof item !== "string" && item.links;
1607
+ return /* @__PURE__ */ jsx(Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsx(
1608
+ Alert,
1609
+ {
1610
+ onClose: () => onCloseItem(index),
1611
+ closeLabel: t2("upload.close"),
1612
+ variant: hasLinks ? "danger" : "default",
1613
+ children: /* @__PURE__ */ jsx(TransferReportItem, { item })
1614
+ },
1615
+ index
1616
+ ) }, index);
1593
1617
  });
1594
1618
  };
1595
1619
  const ReadDocsButton = () => {
@@ -5121,6 +5145,8 @@ const Download = (props) => {
5121
5145
  report: []
5122
5146
  });
5123
5147
  const [isDownloading, setIsDownloading] = useState(false);
5148
+ const [hasSyncCursor, setHasSyncCursor] = useState(false);
5149
+ const [showFullSyncConfirm, setShowFullSyncConfirm] = useState(false);
5124
5150
  const onTranslateInLocalazyClick = () => {
5125
5151
  window.open(identity.project.url, "_blank");
5126
5152
  };
@@ -5136,29 +5162,34 @@ const Download = (props) => {
5136
5162
  console.error(e2.message);
5137
5163
  }
5138
5164
  };
5139
- const onDownloadClick = async () => {
5165
+ const onDownloadClick = async (fullSync = false) => {
5140
5166
  setIsDownloading(true);
5141
5167
  setshowDownloadFinishedModal(false);
5142
5168
  setDownloadResult({
5143
5169
  success: false,
5144
5170
  report: []
5145
5171
  });
5146
- const result = await LocalazyDownloadService.download();
5172
+ const result = await LocalazyDownloadService.download({ fullSync });
5147
5173
  const { streamIdentifier } = result;
5148
5174
  downloadAlertsService.setStreamIdentifier(streamIdentifier);
5149
5175
  downloadAlertsService.onDownload((data) => {
5150
5176
  setDownloadResult((old) => ({
5151
5177
  success: data.success,
5152
- report: [...old.report || [], data.message]
5178
+ report: [...old.report || [], { message: data.message, links: data.links }]
5153
5179
  }));
5154
5180
  });
5155
- downloadAlertsService.onDownloadFinished((data) => {
5181
+ downloadAlertsService.onDownloadFinished(async (data) => {
5156
5182
  setDownloadResult((old) => ({
5157
5183
  success: data.success,
5158
- report: [...old.report || [], data.message]
5184
+ report: [...old.report || [], { message: data.message, links: data.links }]
5159
5185
  }));
5160
5186
  setIsDownloading(false);
5161
5187
  setshowDownloadFinishedModal(true);
5188
+ try {
5189
+ const cursor = await PluginSettingsService.getSyncCursor();
5190
+ setHasSyncCursor(cursor?.processedKeys !== void 0 && Object.keys(cursor.processedKeys).length > 0);
5191
+ } catch {
5192
+ }
5162
5193
  });
5163
5194
  ProductAnalyticsService.trackDownloadToStrapi(identity.user.id, identity.project, {
5164
5195
  "Target Languages Codes": "all"
@@ -5167,14 +5198,16 @@ const Download = (props) => {
5167
5198
  useEffect(() => {
5168
5199
  async function initComponent() {
5169
5200
  setIsLoading(true);
5170
- const [modelChangedResult, localesCompatibleResult, project, globalSettings] = await Promise.all([
5201
+ const [modelChangedResult, localesCompatibleResult, project, globalSettings, syncCursor] = await Promise.all([
5171
5202
  hasModelChanged(),
5172
5203
  areLocalesCompatible(),
5173
5204
  ProjectService.getConnectedProject(),
5174
- PluginSettingsService.getPluginSettings()
5205
+ PluginSettingsService.getPluginSettings(),
5206
+ PluginSettingsService.getSyncCursor()
5175
5207
  ]);
5176
5208
  setModelChanged(modelChangedResult);
5177
5209
  setLocalesIncompatible(!localesCompatibleResult);
5210
+ setHasSyncCursor(syncCursor?.processedKeys !== void 0 && Object.keys(syncCursor.processedKeys).length > 0);
5178
5211
  const projectLanguagesWithoutDefaultLanguage = project?.languages?.filter((language) => language.id !== project.sourceLanguage) || [];
5179
5212
  setProjectLanguages(projectLanguagesWithoutDefaultLanguage);
5180
5213
  setFormModel(globalSettings);
@@ -5189,16 +5222,28 @@ const Download = (props) => {
5189
5222
  {
5190
5223
  title: props.title,
5191
5224
  subtitle: props.subtitle,
5192
- primaryAction: /* @__PURE__ */ jsx(
5193
- Button,
5194
- {
5195
- startIcon: /* @__PURE__ */ jsx(ForwardRef$3P, {}),
5196
- disabled: isLoading || modelChanged || localesIncompatible,
5197
- loading: isDownloading,
5198
- onClick: onDownloadClick,
5199
- children: t2("download.download_to_strapi")
5200
- }
5201
- ),
5225
+ primaryAction: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
5226
+ /* @__PURE__ */ jsx(
5227
+ Button,
5228
+ {
5229
+ variant: "secondary",
5230
+ disabled: isLoading || modelChanged || localesIncompatible,
5231
+ loading: isDownloading,
5232
+ onClick: () => setShowFullSyncConfirm(true),
5233
+ children: t2("download.full_sync")
5234
+ }
5235
+ ),
5236
+ /* @__PURE__ */ jsx(
5237
+ Button,
5238
+ {
5239
+ startIcon: /* @__PURE__ */ jsx(ForwardRef$3P, {}),
5240
+ disabled: isLoading || modelChanged || localesIncompatible || !hasSyncCursor,
5241
+ loading: isDownloading,
5242
+ onClick: () => onDownloadClick(false),
5243
+ children: t2("download.incremental_download")
5244
+ }
5245
+ )
5246
+ ] }),
5202
5247
  as: "h2"
5203
5248
  }
5204
5249
  ),
@@ -5272,8 +5317,27 @@ const Download = (props) => {
5272
5317
  children: t2("download.please_update_your_content")
5273
5318
  }
5274
5319
  ) }),
5320
+ !hasSyncCursor && /* @__PURE__ */ jsx(Box, { marginTop: 4, marginBottom: 4, children: /* @__PURE__ */ jsx(Alert, { title: t2("download.incremental_disabled_hint"), variant: "default", children: t2("download.incremental_disabled_hint") }) }),
5275
5321
  downloadResult.report && downloadResult.report.length > 0 && /* @__PURE__ */ jsx(TransferReport, { report: downloadResult.report })
5276
- ] })
5322
+ ] }),
5323
+ /* @__PURE__ */ jsx(Dialog.Root, { open: showFullSyncConfirm, onOpenChange: setShowFullSyncConfirm, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
5324
+ /* @__PURE__ */ jsx(Dialog.Header, { children: t2("download.full_sync_confirm_title") }),
5325
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: t2("download.full_sync_confirm_message") }) }),
5326
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
5327
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: t2("download.close") }) }),
5328
+ /* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(
5329
+ Button,
5330
+ {
5331
+ variant: "danger-light",
5332
+ onClick: () => {
5333
+ setShowFullSyncConfirm(false);
5334
+ onDownloadClick(true);
5335
+ },
5336
+ children: t2("download.full_sync")
5337
+ }
5338
+ ) })
5339
+ ] })
5340
+ ] }) })
5277
5341
  ] });
5278
5342
  };
5279
5343
  const App = () => {
@@ -2,15 +2,15 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const RequireLocalazyAuth = require("./RequireLocalazyAuth-BDtwyPLH.js");
6
- const FetchIdentity = require("./FetchIdentity-W-xq7F8q.js");
5
+ const RequireLocalazyAuth = require("./RequireLocalazyAuth-BzM7C6Yw.js");
6
+ const FetchIdentity = require("./FetchIdentity-DfV1OWMB.js");
7
7
  const admin = require("@strapi/strapi/admin");
8
- const index = require("./index-CaY3BYnQ.js");
9
- const hasModelChanged = require("./has-model-changed-BXqyvCRA.js");
8
+ const index = require("./index-BSNW1ypR.js");
9
+ const hasModelChanged = require("./has-model-changed-D1f6is8z.js");
10
10
  const useTranslation = require("./useTranslation-BdIl-aLe.js");
11
11
  const styled = require("styled-components");
12
12
  const index$1 = require("./index-1he9s_bs.js");
13
- require("./i18n-0dV2P-Hm.js");
13
+ require("./i18n-DaBjUC3Y.js");
14
14
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
15
15
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
16
16
  const getFilteredModelsSchemas = (models) => {
@@ -1,14 +1,14 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { forwardRef, useState, useEffect } from "react";
3
- import { i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-BmimcHYI.mjs";
4
- import { s as set, m as keys, n as isArrayLike, o as arrayEach, k as isArray, p as isObject, P as PluginSettingsService, c as cloneDeep, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-B9hYlR1E.mjs";
3
+ import { i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-CqHrZ1Ah.mjs";
4
+ import { s as set, m as keys, n as isArrayLike, o as arrayEach, k as isArray, p as isObject, P as PluginSettingsService, c as cloneDeep, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-lkoWjYjn.mjs";
5
5
  import { Layouts } from "@strapi/strapi/admin";
6
- import { C as CheckboxImpl, e as Box, g as Accordion, c as Flex, h as SwitchImpl, T as Typography, B as Button, d as ForwardRef$4z, A as Alert, D as Divider } from "./index-CgI_aKe_.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-K3Z8BNhV.mjs";
6
+ import { C as CheckboxImpl, e as Box, g as Accordion, c as Flex, h as SwitchImpl, T as Typography, B as Button, d as ForwardRef$4z, A as Alert, D as Divider } from "./index-BIHAiJnE.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-CWdMNRB1.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-RoETLXdU.mjs";
11
+ import "./i18n-Bga-GG_Z.mjs";
12
12
  const getFilteredModelsSchemas = (models) => {
13
13
  if (!models) {
14
14
  return [];
@@ -1,12 +1,12 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { P as PluginSettingsService$1, c as cloneDeep, s as set, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-B9hYlR1E.mjs";
3
+ import { P as PluginSettingsService$1, c as cloneDeep, s as set, L as LocalazyIdentityProvider, F as FetchIdentity } from "./FetchIdentity-lkoWjYjn.mjs";
4
4
  import { Layouts } from "@strapi/strapi/admin";
5
- import { c as Flex, B as Button, d as ForwardRef$4z, e as Box, A as Alert, T as Typography, F as Field, a as Toggle, M as MultiSelect, b as MultiSelectOption, D as Divider, S as SingleSelect, f as SingleSelectOption } from "./index-CgI_aKe_.mjs";
6
- import { i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-BmimcHYI.mjs";
7
- import { L as LanguagesSelector, P as ProjectService } from "./LanguagesSelector-zGN0icsS.mjs";
8
- import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-BfIxEUh2.mjs";
9
- import "./i18n-RoETLXdU.mjs";
5
+ import { c as Flex, B as Button, d as ForwardRef$4z, e as Box, A as Alert, T as Typography, F as Field, a as Toggle, M as MultiSelect, b as MultiSelectOption, D as Divider, S as SingleSelect, f as SingleSelectOption } from "./index-BIHAiJnE.mjs";
6
+ import { i as isEqual, R as RequireLocalazyAuth } from "./RequireLocalazyAuth-CqHrZ1Ah.mjs";
7
+ import { L as LanguagesSelector, P as ProjectService } from "./LanguagesSelector-vSZvVGUT.mjs";
8
+ import { c as createStrapiApiAxiosInstance } from "./strapi-api-base-CturxOqD.mjs";
9
+ import "./i18n-Bga-GG_Z.mjs";
10
10
  import { u as useTranslation } from "./useTranslation-CZQ4lU1m.mjs";
11
11
  class PluginSettingsService {
12
12
  static async getAdminPanelUsers() {
@@ -224,7 +224,22 @@ const GlobalSettings = () => {
224
224
  hint: t("plugin_settings.webhook_languages_info"),
225
225
  placeholder: t("plugin_settings.webhook_languages_placeholder")
226
226
  }
227
- )
227
+ ),
228
+ /* @__PURE__ */ jsx("br", {}),
229
+ /* @__PURE__ */ jsx("br", {}),
230
+ /* @__PURE__ */ jsxs(Field.Root, { hint: t("plugin_settings.webhook_incremental_sync_info"), children: [
231
+ /* @__PURE__ */ jsx(Field.Label, { children: t("plugin_settings.webhook_incremental_sync") }),
232
+ /* @__PURE__ */ jsx(
233
+ Toggle,
234
+ {
235
+ offLabel: t("plugin_settings.off"),
236
+ onLabel: t("plugin_settings.on"),
237
+ checked: typeof formModel?.download?.webhookIncrementalSync === "boolean" ? formModel.download.webhookIncrementalSync : true,
238
+ onChange: (e) => patchFormModel("download.webhookIncrementalSync", e.target.checked)
239
+ }
240
+ ),
241
+ /* @__PURE__ */ jsx(Field.Hint, {})
242
+ ] })
228
243
  ]
229
244
  }
230
245
  ) })
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const FetchIdentity = require("./FetchIdentity-W-xq7F8q.js");
5
+ const FetchIdentity = require("./FetchIdentity-DfV1OWMB.js");
6
6
  const admin = require("@strapi/strapi/admin");
7
- const index = require("./index-CaY3BYnQ.js");
8
- const RequireLocalazyAuth = require("./RequireLocalazyAuth-BDtwyPLH.js");
9
- const LanguagesSelector = require("./LanguagesSelector-Cq9JuASq.js");
10
- const strapiApiBase = require("./strapi-api-base-S2_cFlNu.js");
11
- require("./i18n-0dV2P-Hm.js");
7
+ const index = require("./index-BSNW1ypR.js");
8
+ const RequireLocalazyAuth = require("./RequireLocalazyAuth-BzM7C6Yw.js");
9
+ const LanguagesSelector = require("./LanguagesSelector-BmWfSZq6.js");
10
+ const strapiApiBase = require("./strapi-api-base-CN6q5tPh.js");
11
+ require("./i18n-DaBjUC3Y.js");
12
12
  const useTranslation = require("./useTranslation-BdIl-aLe.js");
13
13
  class PluginSettingsService {
14
14
  static async getAdminPanelUsers() {
@@ -226,7 +226,22 @@ const GlobalSettings = () => {
226
226
  hint: t("plugin_settings.webhook_languages_info"),
227
227
  placeholder: t("plugin_settings.webhook_languages_placeholder")
228
228
  }
229
- )
229
+ ),
230
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
231
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
232
+ /* @__PURE__ */ jsxRuntime.jsxs(index.Field.Root, { hint: t("plugin_settings.webhook_incremental_sync_info"), children: [
233
+ /* @__PURE__ */ jsxRuntime.jsx(index.Field.Label, { children: t("plugin_settings.webhook_incremental_sync") }),
234
+ /* @__PURE__ */ jsxRuntime.jsx(
235
+ index.Toggle,
236
+ {
237
+ offLabel: t("plugin_settings.off"),
238
+ onLabel: t("plugin_settings.on"),
239
+ checked: typeof formModel?.download?.webhookIncrementalSync === "boolean" ? formModel.download.webhookIncrementalSync : true,
240
+ onChange: (e) => patchFormModel("download.webhookIncrementalSync", e.target.checked)
241
+ }
242
+ ),
243
+ /* @__PURE__ */ jsxRuntime.jsx(index.Field.Hint, {})
244
+ ] })
230
245
  ]
231
246
  }
232
247
  ) })
@@ -3,9 +3,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const reactRouterDom = require("react-router-dom");
6
- const index = require("./index-CaY3BYnQ.js");
7
- const entryExclusionService = require("./entry-exclusion-service-BZkbrd3B.js");
8
- require("./i18n-0dV2P-Hm.js");
6
+ const index = require("./index-BSNW1ypR.js");
7
+ const entryExclusionService = require("./entry-exclusion-service-Cvu8PQUI.js");
8
+ require("./i18n-DaBjUC3Y.js");
9
9
  const useTranslation = require("./useTranslation-BdIl-aLe.js");
10
10
  const LocalazyPanel = () => {
11
11
  const { t } = useTranslation.useTranslation();