@translationstudio/translationstudio-strapi-extension 2.1.0 → 4.0.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 (48) hide show
  1. package/README.md +1 -1
  2. package/dist/Types.d.ts +36 -0
  3. package/dist/_chunks/App-BR-y9Q87.js +331 -0
  4. package/dist/_chunks/App-Cc3EklWX.mjs +331 -0
  5. package/dist/_chunks/HistoryPage-BG_RchOk.js +1057 -0
  6. package/dist/_chunks/HistoryPage-CSMW8AED.mjs +1057 -0
  7. package/dist/_chunks/index-B9kFLfY3.js +834 -0
  8. package/dist/_chunks/index-ChM8Lw4L.mjs +835 -0
  9. package/dist/admin/index.js +1 -1
  10. package/dist/admin/index.mjs +2 -2
  11. package/dist/admin/src/components/BulkTranslationMenu.d.ts +3 -0
  12. package/dist/admin/src/components/BulkTranslationPanel.d.ts +3 -0
  13. package/dist/admin/src/components/EntryHistory.d.ts +3 -0
  14. package/dist/admin/src/components/HistoryIcon.d.ts +2 -0
  15. package/dist/admin/src/components/HistoryMenu.d.ts +2 -0
  16. package/dist/admin/src/components/LoadingSpinner.d.ts +4 -0
  17. package/dist/admin/src/components/SettingsIcon.d.ts +2 -0
  18. package/dist/admin/src/components/TranslationstudioLogo.d.ts +2 -0
  19. package/dist/admin/src/components/utils/alertUtils.d.ts +13 -0
  20. package/dist/admin/src/components/utils/dateUtils.d.ts +1 -0
  21. package/dist/admin/src/components/utils/emailUtils.d.ts +2 -0
  22. package/dist/admin/src/components/utils/entryUtils.d.ts +2 -0
  23. package/dist/admin/src/components/utils/filterAndTransformContentTypes.d.ts +2 -0
  24. package/dist/admin/src/components/utils/formatDate.d.ts +1 -0
  25. package/dist/admin/src/components/utils/getEntryHelper.d.ts +3 -0
  26. package/dist/admin/src/components/utils/handleHistoryResponse.d.ts +5 -0
  27. package/dist/admin/src/components/utils/historyDataUtils.d.ts +13 -0
  28. package/dist/admin/src/components/utils/historyStatusUtils.d.ts +7 -0
  29. package/dist/admin/src/components/utils/searchUtils.d.ts +2 -0
  30. package/dist/admin/src/components/utils/sortUtils.d.ts +9 -0
  31. package/dist/admin/src/components/utils/statusHelper.d.ts +6 -0
  32. package/dist/admin/src/components/utils/theme.d.ts +15 -0
  33. package/dist/admin/src/components/utils/translationUtils.d.ts +5 -0
  34. package/dist/admin/src/components/utils/useDebounce.d.ts +1 -0
  35. package/dist/admin/src/pages/HistoryPage.d.ts +2 -0
  36. package/dist/server/index.js +50 -29
  37. package/dist/server/index.mjs +50 -29
  38. package/dist/server/src/controllers/controller.d.ts +1 -1
  39. package/dist/server/src/controllers/index.d.ts +1 -1
  40. package/dist/server/src/index.d.ts +2 -4
  41. package/dist/server/src/services/functions/importData/transformFieldsToData.d.ts +1 -1
  42. package/dist/server/src/services/index.d.ts +1 -3
  43. package/dist/server/src/services/service.d.ts +1 -3
  44. package/package.json +23 -21
  45. package/dist/_chunks/App-Hb9oaG2M.mjs +0 -337
  46. package/dist/_chunks/App-v67y1hUs.js +0 -337
  47. package/dist/_chunks/index-BgsAgrFL.mjs +0 -345
  48. package/dist/_chunks/index-ehPijnQ-.js +0 -344
@@ -0,0 +1,331 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { getFetchClient, Page } from "@strapi/strapi/admin";
3
+ import { Routes, Route } from "react-router-dom";
4
+ import { Main, Box, Alert, Grid, Typography, TextInput, Switch, Button } from "@strapi/design-system";
5
+ import { useState, useCallback, useEffect } from "react";
6
+ import { T as TranslationstudioLogo } from "./index-ChM8Lw4L.mjs";
7
+ const apiService = {
8
+ async loadLicense(get) {
9
+ try {
10
+ const response = await get("/translationstudio/getLicense");
11
+ return response.data?.license || "";
12
+ } catch (err) {
13
+ console.error(err);
14
+ return "";
15
+ }
16
+ },
17
+ async loadDevUrl(get) {
18
+ try {
19
+ const response = await get("/translationstudio/devurl");
20
+ return response.data?.url || "";
21
+ } catch (err) {
22
+ console.error(err);
23
+ return "";
24
+ }
25
+ },
26
+ async updateDevUrl(post, url) {
27
+ try {
28
+ const response = await post("/translationstudio/devurl", { url });
29
+ return response.data?.success || false;
30
+ } catch (err) {
31
+ console.error(err);
32
+ return false;
33
+ }
34
+ }
35
+ };
36
+ const styles = {
37
+ textInput: {
38
+ width: "90%",
39
+ display: "inline-block"
40
+ },
41
+ button: {
42
+ backgroundColor: "#e94642",
43
+ border: "none",
44
+ paddingTop: "0.6em",
45
+ paddingBottom: "0.6em"
46
+ },
47
+ tab: {
48
+ color: "#e94642",
49
+ cursor: "pointer",
50
+ textDecoration: "none",
51
+ fontSize: "18px",
52
+ fontWeight: "600"
53
+ },
54
+ activeTab: {
55
+ textDecoration: "underline"
56
+ },
57
+ inactiveTab: {
58
+ opacity: 0.7
59
+ },
60
+ alert: {
61
+ position: "fixed",
62
+ top: "10%",
63
+ left: "50%",
64
+ transform: "translate(-50%, -50%)",
65
+ zIndex: 10,
66
+ minWidth: "400px",
67
+ maxWidth: "90%"
68
+ }
69
+ };
70
+ const SettingsPage = () => {
71
+ const [licenseValue, setLicenseValue] = useState("");
72
+ const [tokenValue, setTokenValue] = useState("");
73
+ const [devUrl, setDevUrl] = useState("");
74
+ const [isLoading, setIsLoading] = useState(true);
75
+ const [isLoadingToken, setIsLoadingToken] = useState(false);
76
+ const [showDevOptions, setShowDevOptions] = useState(false);
77
+ const [showAlert, setShowAlert] = useState(false);
78
+ const [alertType, setAlertType] = useState("success");
79
+ const [alertMessage, setAlertMessage] = useState("");
80
+ const { get, post } = getFetchClient();
81
+ const displayAlert = useCallback((variant, message) => {
82
+ const defaultMessage = variant === "success" ? "License saved" : "Error saving license";
83
+ setAlertType(variant);
84
+ setAlertMessage(message || defaultMessage);
85
+ setShowAlert(true);
86
+ setTimeout(() => setShowAlert(false), 5e3);
87
+ }, []);
88
+ useEffect(() => {
89
+ const loadInitialData = async () => {
90
+ setIsLoading(true);
91
+ try {
92
+ const [license, devUrlData] = await Promise.all([
93
+ apiService.loadLicense(get),
94
+ apiService.loadDevUrl(get)
95
+ ]);
96
+ if (license) setLicenseValue(license);
97
+ if (devUrlData) {
98
+ setDevUrl(devUrlData);
99
+ setShowDevOptions(true);
100
+ }
101
+ } catch (err) {
102
+ console.error("Failed to load initial data:", err);
103
+ } finally {
104
+ setIsLoading(false);
105
+ }
106
+ };
107
+ loadInitialData();
108
+ }, [setIsLoading, setDevUrl, setLicenseValue, setShowDevOptions]);
109
+ useEffect(() => {
110
+ const fetchToken = async () => {
111
+ setIsLoadingToken(true);
112
+ try {
113
+ const response = await get("/translationstudio/getToken");
114
+ setTokenValue(response.data?.token || "");
115
+ } catch (err) {
116
+ console.error(err);
117
+ } finally {
118
+ setIsLoadingToken(false);
119
+ }
120
+ };
121
+ fetchToken();
122
+ }, []);
123
+ const handleLicenseChange = useCallback((e) => {
124
+ setLicenseValue(e.target.value.trim());
125
+ }, []);
126
+ const handleSaveLicense = useCallback(async () => {
127
+ try {
128
+ await post("/translationstudio/setLicense", { license: licenseValue });
129
+ displayAlert("success");
130
+ } catch (err) {
131
+ console.error(err);
132
+ displayAlert("danger");
133
+ }
134
+ }, [post, licenseValue, displayAlert]);
135
+ const handleGenerateToken = useCallback(async () => {
136
+ setIsLoadingToken(true);
137
+ try {
138
+ const response = await post("/translationstudio/generateToken");
139
+ if (response.data?.token) {
140
+ setTokenValue(response.data.token);
141
+ }
142
+ } catch (err) {
143
+ console.error(err);
144
+ } finally {
145
+ setIsLoadingToken(false);
146
+ }
147
+ }, [post]);
148
+ const handleUpdateUrl = useCallback(async () => {
149
+ setIsLoading(true);
150
+ try {
151
+ await apiService.updateDevUrl(post, devUrl);
152
+ if (devUrl === "") setShowDevOptions(false);
153
+ } finally {
154
+ setIsLoading(false);
155
+ }
156
+ }, [post, devUrl]);
157
+ const handleDevOptionsToggle = useCallback(
158
+ (val) => {
159
+ if (val) {
160
+ setShowDevOptions(val);
161
+ } else {
162
+ apiService.updateDevUrl(post, "").finally(() => setShowDevOptions(val));
163
+ }
164
+ },
165
+ [post]
166
+ );
167
+ const ActionButton = ({
168
+ onClick,
169
+ disabled,
170
+ loading,
171
+ children,
172
+ icon
173
+ }) => /* @__PURE__ */ jsx(
174
+ Button,
175
+ {
176
+ onClick,
177
+ disabled,
178
+ loading,
179
+ style: styles.button,
180
+ size: "L",
181
+ startIcon: icon,
182
+ children
183
+ }
184
+ );
185
+ const LinkText = ({ href, children }) => /* @__PURE__ */ jsx(
186
+ "a",
187
+ {
188
+ href,
189
+ target: "_blank",
190
+ rel: "noopener noreferrer",
191
+ style: { textDecoration: "none", color: "#e94642" },
192
+ children
193
+ }
194
+ );
195
+ return /* @__PURE__ */ jsxs(Main, { children: [
196
+ showAlert && /* @__PURE__ */ jsx(Box, { style: styles.alert, children: /* @__PURE__ */ jsx(Alert, { closeLabel: "Close", variant: alertType, onClose: () => setShowAlert(false), children: alertMessage }) }),
197
+ /* @__PURE__ */ jsx(Box, { padding: 10, style: { minHeight: "90vh", marginTop: "5vh" }, children: /* @__PURE__ */ jsxs(Grid.Root, { children: [
198
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, children: /* @__PURE__ */ jsx(Box, { style: { textAlign: "right", width: "100%" }, children: /* @__PURE__ */ jsx(
199
+ "picture",
200
+ {
201
+ style: {
202
+ width: "150px",
203
+ height: "auto",
204
+ display: "inline-block"
205
+ },
206
+ children: /* @__PURE__ */ jsx(TranslationstudioLogo, {})
207
+ }
208
+ ) }) }),
209
+ /* @__PURE__ */ jsxs(Fragment, { children: [
210
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingTop: "2em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "translationstudio License" }) }),
211
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingBottom: "1em" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "charlie", children: [
212
+ "You can create or revoke a license at",
213
+ " ",
214
+ /* @__PURE__ */ jsx(LinkText, { href: "https://account.translationstudio.tech/", children: "account.translationstudio.tech" })
215
+ ] }) }),
216
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 10, children: /* @__PURE__ */ jsx("div", { style: { display: "block", width: "95%" }, children: /* @__PURE__ */ jsx(
217
+ TextInput,
218
+ {
219
+ name: "jwt-token",
220
+ label: "JWT Token",
221
+ placeholder: "Paste your Strapi translationstudio license into this field and click save to apply it to this project",
222
+ value: licenseValue,
223
+ onChange: handleLicenseChange,
224
+ disabled: isLoading,
225
+ style: styles.textInput
226
+ }
227
+ ) }) }),
228
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 2, children: /* @__PURE__ */ jsx(
229
+ ActionButton,
230
+ {
231
+ onClick: handleSaveLicense,
232
+ disabled: isLoading,
233
+ icon: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
234
+ "path",
235
+ {
236
+ d: "M21,20V8.414a1,1,0,0,0-.293-.707L16.293,3.293A1,1,0,0,0,15.586,3H4A1,1,0,0,0,3,4V20a1,1,0,0,0,1,1H20A1,1,0,0,0,21,20ZM9,8h6V6h1v3H8V6H9ZM8,18V14h8v4Z",
237
+ fill: "currentColor"
238
+ }
239
+ ) }),
240
+ children: "Save license"
241
+ }
242
+ ) }),
243
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingTop: "3em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Authorize translationstudio requests" }) }),
244
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingBottom: "1em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "charlie", children: "When translationstudio connects with this plugin it will use the following access key to authorize itself." }) }),
245
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 10, children: /* @__PURE__ */ jsx("div", { style: { display: "block", width: "95%" }, children: /* @__PURE__ */ jsx(
246
+ TextInput,
247
+ {
248
+ name: "access-token",
249
+ label: "Access Key",
250
+ placeholder: "Generate an access key to validate incoming requests",
251
+ value: tokenValue,
252
+ onChange: () => {
253
+ },
254
+ disabled: true,
255
+ style: styles.textInput
256
+ }
257
+ ) }) }),
258
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 2, children: /* @__PURE__ */ jsx(
259
+ ActionButton,
260
+ {
261
+ onClick: handleGenerateToken,
262
+ disabled: isLoadingToken,
263
+ loading: isLoadingToken,
264
+ icon: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
265
+ "path",
266
+ {
267
+ d: "M12 4V1L8 5L12 9V6C15.31 6 18 8.69 18 12C18 13.01 17.75 13.97 17.3 14.8L18.76 16.26C19.54 15.03 20 13.57 20 12C20 7.58 16.42 4 12 4ZM12 18C8.69 18 6 15.31 6 12C6 10.99 6.25 10.03 6.7 9.2L5.24 7.74C4.46 8.97 4 10.43 4 12C4 16.42 7.58 20 12 20V23L16 19L12 15V18Z",
268
+ fill: "currentColor"
269
+ }
270
+ ) }),
271
+ children: isLoadingToken ? "Generating..." : tokenValue ? "New access key" : "Create access key"
272
+ }
273
+ ) }),
274
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingTop: "5em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Customization" }) }),
275
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingBottom: "1em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "charlie", children: "You will not need these settings, but you might want to customize your translationstudio instance." }) }),
276
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, children: /* @__PURE__ */ jsx(
277
+ Switch,
278
+ {
279
+ checked: showDevOptions,
280
+ onCheckedChange: () => handleDevOptionsToggle(!showDevOptions),
281
+ onLabel: "Use custom translationstudio URL",
282
+ offLabel: "Custom translationstudio URL is currently disabled (default)",
283
+ visibleLabels: true
284
+ }
285
+ ) }),
286
+ showDevOptions && /* @__PURE__ */ jsxs(Fragment, { children: [
287
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingTop: "2em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Use custom translationstudio URL." }) }),
288
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingBottom: "1em" }, children: /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "This is usually only necessary for development purposes." }) }),
289
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 10, children: /* @__PURE__ */ jsx("div", { style: { display: "block", width: "95%" }, children: /* @__PURE__ */ jsx(
290
+ TextInput,
291
+ {
292
+ onChange: (e) => setDevUrl(e.target.value.trim()),
293
+ name: "devurl",
294
+ label: "Custom translationstudio url",
295
+ placeholder: "Paste your custom translationstudio url here",
296
+ value: devUrl,
297
+ style: styles.textInput
298
+ }
299
+ ) }) }),
300
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 2, children: /* @__PURE__ */ jsx(
301
+ ActionButton,
302
+ {
303
+ onClick: handleUpdateUrl,
304
+ disabled: isLoading,
305
+ loading: isLoading,
306
+ icon: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M8 5V19L19 12L8 5Z", fill: "currentColor" }) }),
307
+ children: "Update URL"
308
+ }
309
+ ) })
310
+ ] }),
311
+ /* @__PURE__ */ jsx(Grid.Item, { xs: 12, style: { paddingTop: "4em" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "sigma", style: { textAlign: "right" }, children: [
312
+ "If you do not have a translationstudio account, please create one at",
313
+ " ",
314
+ /* @__PURE__ */ jsx(LinkText, { href: "https://account.translationstudio.tech/", children: "account.translationstudio.tech" }),
315
+ ". You can find further information at",
316
+ " ",
317
+ /* @__PURE__ */ jsx(LinkText, { href: "https://www.translationstudio.tech/", children: "translationstudio.tech" })
318
+ ] }) })
319
+ ] })
320
+ ] }) })
321
+ ] });
322
+ };
323
+ const App = () => {
324
+ return /* @__PURE__ */ jsxs(Routes, { children: [
325
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(SettingsPage, {}) }),
326
+ /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
327
+ ] });
328
+ };
329
+ export {
330
+ App
331
+ };