monto-email-builder 1.0.6 → 1.0.8
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 +32 -1
- package/dist/App/InspectorDrawer/ConfigurationPanel/input-panels/ImageSidebarPanel.d.ts.map +1 -1
- package/dist/App/InspectorDrawer/index.d.ts.map +1 -1
- package/dist/App/SamplesDrawer/SidebarButton.d.ts +2 -2
- package/dist/App/SamplesDrawer/SidebarButton.d.ts.map +1 -1
- package/dist/App/SamplesDrawer/index.d.ts.map +1 -1
- package/dist/App/TemplatePanel/DownloadJson/index.d.ts.map +1 -1
- package/dist/App/TemplatePanel/ImportJson/index.d.ts.map +1 -1
- package/dist/App/TemplatePanel/NameInput.d.ts +3 -0
- package/dist/App/TemplatePanel/NameInput.d.ts.map +1 -0
- package/dist/App/TemplatePanel/SaveAndExitButton.d.ts +3 -0
- package/dist/App/TemplatePanel/SaveAndExitButton.d.ts.map +1 -0
- package/dist/App/TemplatePanel/SaveButton.d.ts +3 -0
- package/dist/App/TemplatePanel/SaveButton.d.ts.map +1 -0
- package/dist/App/TemplatePanel/helper/highlighters.d.ts.map +1 -1
- package/dist/App/TemplatePanel/index.d.ts.map +1 -1
- package/dist/App/index.d.ts.map +1 -1
- package/dist/EmailBuilder/index.d.ts +28 -3
- package/dist/EmailBuilder/index.d.ts.map +1 -1
- package/dist/documents/editor/EditorContext.d.ts +14 -1
- package/dist/documents/editor/EditorContext.d.ts.map +1 -1
- package/dist/getConfiguration/index.d.ts +7 -0
- package/dist/getConfiguration/index.d.ts.map +1 -1
- package/dist/getConfiguration/sample/basic-template.d.ts +4 -0
- package/dist/getConfiguration/sample/basic-template.d.ts.map +1 -0
- package/dist/getConfiguration/sample/reservation-reminder.d.ts.map +1 -1
- package/dist/index.js +523 -228
- package/dist/{samples-SfLrANbd.js → samples-BnRgwIcn.js} +268 -2259
- package/package.json +8 -13
- package/dist/main.d.ts +0 -2
- package/dist/main.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
3
|
-
import { Box, Typography, Stack, InputLabel, ToggleButtonGroup, Slider, TextField, Button, Menu, ButtonBase, MenuItem, ToggleButton, FormControlLabel, Switch, Drawer, Tabs, Tab,
|
|
2
|
+
import { useState, useRef, useEffect, Fragment as Fragment$1, useContext, createContext, useMemo } from "react";
|
|
3
|
+
import { Box, Typography, Stack, InputLabel, ToggleButtonGroup, Slider, TextField, Button, Menu, ButtonBase, MenuItem, ToggleButton, CircularProgress, FormControlLabel, Switch, Drawer, Tabs, Tab, Divider, Fade, IconButton, Paper, Tooltip, Dialog, DialogTitle, DialogContent, Link, DialogActions, Alert, useTheme, ThemeProvider, CssBaseline } from "@mui/material";
|
|
4
4
|
import { create } from "zustand";
|
|
5
|
-
import { E as EMPTY_EMAIL_MESSAGE } from "./samples-
|
|
5
|
+
import { E as EMPTY_EMAIL_MESSAGE } from "./samples-BnRgwIcn.js";
|
|
6
6
|
import { createTheme, alpha, lighten, darken } from "@mui/material/styles";
|
|
7
|
-
import { CloseOutlined, AddOutlined, TextFieldsOutlined, AlignVerticalTopOutlined, AlignVerticalBottomOutlined, AlignHorizontalLeftOutlined, AlignHorizontalRightOutlined, FormatAlignLeftOutlined, FormatAlignCenterOutlined, FormatAlignRightOutlined, RoundedCornerOutlined, AspectRatioOutlined, SpaceBarOutlined, VerticalAlignTopOutlined, VerticalAlignCenterOutlined, VerticalAlignBottomOutlined, HeightOutlined, LinkOutlined, CloudUploadOutlined,
|
|
7
|
+
import { CloseOutlined, AddOutlined, TextFieldsOutlined, AlignVerticalTopOutlined, AlignVerticalBottomOutlined, AlignHorizontalLeftOutlined, AlignHorizontalRightOutlined, FormatAlignLeftOutlined, FormatAlignCenterOutlined, FormatAlignRightOutlined, RoundedCornerOutlined, AspectRatioOutlined, SpaceBarOutlined, VerticalAlignTopOutlined, VerticalAlignCenterOutlined, VerticalAlignBottomOutlined, HeightOutlined, LinkOutlined, CloudUploadOutlined, HMobiledataOutlined, NotesOutlined, SmartButtonOutlined, ImageOutlined, AccountCircleOutlined, HorizontalRuleOutlined, Crop32Outlined, HtmlOutlined, ViewColumnOutlined, LibraryAddOutlined, ArrowUpwardOutlined, ArrowDownwardOutlined, DeleteOutlined, LastPageOutlined, AppRegistrationOutlined, FirstPageOutlined, MenuOutlined, FileDownloadOutlined, FileUploadOutlined, EditOutlined, PreviewOutlined, CodeOutlined, DataObjectOutlined, ExitToAppOutlined, SaveOutlined, MonitorOutlined, PhoneIphoneOutlined } from "@mui/icons-material";
|
|
8
8
|
import { AvatarPropsDefaults, AvatarPropsSchema, Avatar } from "@usewaypoint/block-avatar";
|
|
9
9
|
import { HexColorPicker, HexColorInput } from "react-colorful";
|
|
10
10
|
import { ButtonPropsDefaults, ButtonPropsSchema, Button as Button$1 } from "@usewaypoint/block-button";
|
|
@@ -19,58 +19,30 @@ import { SpacerPropsDefaults, SpacerPropsSchema, Spacer } from "@usewaypoint/blo
|
|
|
19
19
|
import { TextPropsSchema, Text } from "@usewaypoint/block-text";
|
|
20
20
|
import { renderToStaticMarkup, Reader } from "@usewaypoint/email-builder";
|
|
21
21
|
import { buildBlockConfigurationDictionary, buildBlockComponent, buildBlockConfigurationSchema } from "@usewaypoint/document-core";
|
|
22
|
-
const sampleTemplates = {
|
|
23
|
-
welcome: () => import("./samples-SfLrANbd.js").then((n) => n.w).then((m) => m.default),
|
|
24
|
-
"one-time-password": () => import("./samples-SfLrANbd.js").then((n) => n.o).then((m) => m.default),
|
|
25
|
-
"order-ecomerce": () => import("./samples-SfLrANbd.js").then((n) => n.a).then((m) => m.default),
|
|
26
|
-
"post-metrics-report": () => import("./samples-SfLrANbd.js").then((n) => n.p).then((m) => m.default),
|
|
27
|
-
"reservation-reminder": () => import("./samples-SfLrANbd.js").then((n) => n.r).then((m) => m.default),
|
|
28
|
-
"reset-password": () => import("./samples-SfLrANbd.js").then((n) => n.b).then((m) => m.default),
|
|
29
|
-
"respond-to-message": () => import("./samples-SfLrANbd.js").then((n) => n.c).then((m) => m.default),
|
|
30
|
-
"subscription-receipt": () => import("./samples-SfLrANbd.js").then((n) => n.s).then((m) => m.default)
|
|
31
|
-
};
|
|
32
|
-
const templateCache = {};
|
|
33
|
-
function getConfiguration(template) {
|
|
34
|
-
if (template.startsWith("#sample/")) {
|
|
35
|
-
return EMPTY_EMAIL_MESSAGE;
|
|
36
|
-
}
|
|
37
|
-
if (template.startsWith("#code/")) {
|
|
38
|
-
const encodedString = template.replace("#code/", "");
|
|
39
|
-
const configurationString = decodeURIComponent(atob(encodedString));
|
|
40
|
-
try {
|
|
41
|
-
return JSON.parse(configurationString);
|
|
42
|
-
} catch {
|
|
43
|
-
console.error(`Couldn't load configuration from hash.`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return EMPTY_EMAIL_MESSAGE;
|
|
47
|
-
}
|
|
48
|
-
async function loadSampleTemplate(sampleName) {
|
|
49
|
-
const loader = sampleTemplates[sampleName];
|
|
50
|
-
if (!loader) {
|
|
51
|
-
return EMPTY_EMAIL_MESSAGE;
|
|
52
|
-
}
|
|
53
|
-
if (templateCache[sampleName]) {
|
|
54
|
-
return templateCache[sampleName];
|
|
55
|
-
}
|
|
56
|
-
const template = await loader();
|
|
57
|
-
templateCache[sampleName] = template;
|
|
58
|
-
return template;
|
|
59
|
-
}
|
|
60
22
|
const common$1 = {
|
|
61
23
|
newDocument: "New Blank Document",
|
|
62
24
|
useBuiltInTemplates: "Use Built-in Templates",
|
|
63
|
-
emailBuilder: "Email Builder"
|
|
25
|
+
emailBuilder: "Email Builder",
|
|
26
|
+
save: "Save",
|
|
27
|
+
saving: "Saving...",
|
|
28
|
+
saveAndExit: "Save and Exit",
|
|
29
|
+
namePlaceholder: "Enter template name",
|
|
30
|
+
unnamedTemplate: "",
|
|
31
|
+
desktopView: "Desktop view",
|
|
32
|
+
mobileView: "Mobile view",
|
|
33
|
+
downloadJson: "Download JSON file",
|
|
34
|
+
importJson: "Import JSON"
|
|
64
35
|
};
|
|
65
36
|
const samples$1 = {
|
|
66
|
-
welcomeEmail: "
|
|
37
|
+
welcomeEmail: "Marketing Template",
|
|
67
38
|
oneTimePasscode: "One-time passcode (OTP)",
|
|
68
39
|
resetPassword: "Reset password",
|
|
69
40
|
orderEcommerce: "E-commerce receipt",
|
|
70
41
|
subscriptionReceipt: "Subscription receipt",
|
|
71
|
-
reservationReminder: "
|
|
42
|
+
reservationReminder: "Verification Code Template",
|
|
72
43
|
postMetrics: "Post metrics",
|
|
73
|
-
respondToMessage: "Respond to inquiry"
|
|
44
|
+
respondToMessage: "Respond to inquiry",
|
|
45
|
+
quickStart: "Quick Start"
|
|
74
46
|
};
|
|
75
47
|
const inspector$1 = {
|
|
76
48
|
styles: "Styles",
|
|
@@ -121,17 +93,27 @@ const en = {
|
|
|
121
93
|
const common = {
|
|
122
94
|
newDocument: "新建空白文档",
|
|
123
95
|
useBuiltInTemplates: "使用内置模板",
|
|
124
|
-
emailBuilder: "邮件编辑器"
|
|
96
|
+
emailBuilder: "邮件编辑器",
|
|
97
|
+
save: "保存",
|
|
98
|
+
saving: "保存中...",
|
|
99
|
+
saveAndExit: "保存并退出",
|
|
100
|
+
namePlaceholder: "这里放置接受的 name",
|
|
101
|
+
unnamedTemplate: "",
|
|
102
|
+
desktopView: "桌面视图",
|
|
103
|
+
mobileView: "移动视图",
|
|
104
|
+
downloadJson: "下载 JSON 文件",
|
|
105
|
+
importJson: "导入 JSON"
|
|
125
106
|
};
|
|
126
107
|
const samples = {
|
|
127
|
-
welcomeEmail: "
|
|
108
|
+
welcomeEmail: "营销模板",
|
|
128
109
|
oneTimePasscode: "一次性密码 (OTP)",
|
|
129
110
|
resetPassword: "重置密码",
|
|
130
111
|
orderEcommerce: "电商收据",
|
|
131
112
|
subscriptionReceipt: "订阅收据",
|
|
132
|
-
reservationReminder: "
|
|
113
|
+
reservationReminder: "验证码模板",
|
|
133
114
|
postMetrics: "指标报告",
|
|
134
|
-
respondToMessage: "回复询问"
|
|
115
|
+
respondToMessage: "回复询问",
|
|
116
|
+
quickStart: "快速开始"
|
|
135
117
|
};
|
|
136
118
|
const inspector = {
|
|
137
119
|
styles: "样式",
|
|
@@ -222,7 +204,7 @@ function setLanguage$1(lang) {
|
|
|
222
204
|
}
|
|
223
205
|
}
|
|
224
206
|
const editorStateStore = create((set, get) => ({
|
|
225
|
-
document:
|
|
207
|
+
document: EMPTY_EMAIL_MESSAGE,
|
|
226
208
|
selectedBlockId: null,
|
|
227
209
|
selectedSidebarTab: "styles",
|
|
228
210
|
selectedMainTab: "editor",
|
|
@@ -230,7 +212,11 @@ const editorStateStore = create((set, get) => ({
|
|
|
230
212
|
inspectorDrawerOpen: true,
|
|
231
213
|
samplesDrawerOpen: true,
|
|
232
214
|
language: getLanguage(),
|
|
233
|
-
onChange: void 0
|
|
215
|
+
onChange: void 0,
|
|
216
|
+
saveHandler: void 0,
|
|
217
|
+
saveAndExitHandler: void 0,
|
|
218
|
+
name: "",
|
|
219
|
+
onNameChange: void 0
|
|
234
220
|
}));
|
|
235
221
|
function useDocument() {
|
|
236
222
|
return editorStateStore((s) => s.document);
|
|
@@ -271,22 +257,22 @@ function setSelectedBlockId(selectedBlockId) {
|
|
|
271
257
|
function setSidebarTab(selectedSidebarTab) {
|
|
272
258
|
return editorStateStore.setState({ selectedSidebarTab });
|
|
273
259
|
}
|
|
274
|
-
function resetDocument(
|
|
260
|
+
function resetDocument(document2) {
|
|
275
261
|
editorStateStore.setState({
|
|
276
|
-
document,
|
|
262
|
+
document: document2,
|
|
277
263
|
selectedSidebarTab: "styles",
|
|
278
264
|
selectedBlockId: null
|
|
279
265
|
});
|
|
280
266
|
const onChange = editorStateStore.getState().onChange;
|
|
281
267
|
if (onChange) {
|
|
282
|
-
onChange(
|
|
268
|
+
onChange(document2);
|
|
283
269
|
}
|
|
284
270
|
}
|
|
285
|
-
function setDocument(
|
|
271
|
+
function setDocument(document2) {
|
|
286
272
|
const originalDocument = editorStateStore.getState().document;
|
|
287
273
|
const newDocument = {
|
|
288
274
|
...originalDocument,
|
|
289
|
-
...
|
|
275
|
+
...document2
|
|
290
276
|
};
|
|
291
277
|
editorStateStore.setState({
|
|
292
278
|
document: newDocument
|
|
@@ -323,8 +309,48 @@ function setLanguage(lang) {
|
|
|
323
309
|
setLanguage$1(lang);
|
|
324
310
|
return editorStateStore.setState({ language: lang });
|
|
325
311
|
}
|
|
312
|
+
function useSaveHandler() {
|
|
313
|
+
return editorStateStore((s) => s.saveHandler);
|
|
314
|
+
}
|
|
315
|
+
function setSaveHandler(handler) {
|
|
316
|
+
return editorStateStore.setState({ saveHandler: handler });
|
|
317
|
+
}
|
|
318
|
+
async function saveDocument() {
|
|
319
|
+
const document2 = editorStateStore.getState().document;
|
|
320
|
+
const saveHandler = editorStateStore.getState().saveHandler;
|
|
321
|
+
if (saveHandler) {
|
|
322
|
+
await saveHandler(document2);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function useSaveAndExitHandler() {
|
|
326
|
+
return editorStateStore((s) => s.saveAndExitHandler);
|
|
327
|
+
}
|
|
328
|
+
function setSaveAndExitHandler(handler) {
|
|
329
|
+
return editorStateStore.setState({ saveAndExitHandler: handler });
|
|
330
|
+
}
|
|
331
|
+
function saveAndExitDocument(onExit) {
|
|
332
|
+
const document2 = editorStateStore.getState().document;
|
|
333
|
+
if (onExit) {
|
|
334
|
+
Promise.resolve(onExit(document2)).catch((error) => {
|
|
335
|
+
console.error("Error in exit handler:", error);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function useName() {
|
|
340
|
+
return editorStateStore((s) => s.name);
|
|
341
|
+
}
|
|
342
|
+
function setName(name) {
|
|
343
|
+
editorStateStore.setState({ name });
|
|
344
|
+
const onNameChange = editorStateStore.getState().onNameChange;
|
|
345
|
+
if (onNameChange) {
|
|
346
|
+
onNameChange(name);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function setOnNameChange(handler) {
|
|
350
|
+
return editorStateStore.setState({ onNameChange: handler });
|
|
351
|
+
}
|
|
326
352
|
const BRAND_NAVY = "#212443";
|
|
327
|
-
const BRAND_BLUE = "#
|
|
353
|
+
const BRAND_BLUE = "#1E40AF";
|
|
328
354
|
const BRAND_GREEN = "#1F8466";
|
|
329
355
|
const BRAND_RED = "#E81212";
|
|
330
356
|
const BRAND_YELLOW = "#F6DC9F";
|
|
@@ -1944,6 +1970,7 @@ function HtmlSidebarPanel({ data, setData }) {
|
|
|
1944
1970
|
}
|
|
1945
1971
|
function ImageSidebarPanel({ data, setData }) {
|
|
1946
1972
|
var _a, _b, _c, _d, _e, _f;
|
|
1973
|
+
const { t: t2 } = useTranslation();
|
|
1947
1974
|
const [, setErrors] = useState(null);
|
|
1948
1975
|
const [uploadMode, setUploadMode] = useState("url");
|
|
1949
1976
|
const [uploading, setUploading] = useState(false);
|
|
@@ -1984,7 +2011,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
1984
2011
|
var _a2;
|
|
1985
2012
|
(_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
1986
2013
|
};
|
|
1987
|
-
return /* @__PURE__ */ jsxs(BaseSidebarPanel, { title: "
|
|
2014
|
+
return /* @__PURE__ */ jsxs(BaseSidebarPanel, { title: t2("image.imageBlock"), children: [
|
|
1988
2015
|
/* @__PURE__ */ jsxs(Stack, { spacing: 1, children: [
|
|
1989
2016
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, children: [
|
|
1990
2017
|
/* @__PURE__ */ jsxs(
|
|
@@ -1997,7 +2024,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
1997
2024
|
fullWidth: true,
|
|
1998
2025
|
children: [
|
|
1999
2026
|
/* @__PURE__ */ jsx(LinkOutlined, { fontSize: "small", sx: { mr: 0.5 } }),
|
|
2000
|
-
"
|
|
2027
|
+
t2("image.url")
|
|
2001
2028
|
]
|
|
2002
2029
|
}
|
|
2003
2030
|
),
|
|
@@ -2012,7 +2039,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2012
2039
|
disabled: !imageUploadHandler,
|
|
2013
2040
|
children: [
|
|
2014
2041
|
/* @__PURE__ */ jsx(CloudUploadOutlined, { fontSize: "small", sx: { mr: 0.5 } }),
|
|
2015
|
-
"
|
|
2042
|
+
t2("image.upload")
|
|
2016
2043
|
]
|
|
2017
2044
|
}
|
|
2018
2045
|
)
|
|
@@ -2020,7 +2047,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2020
2047
|
uploadMode === "url" ? /* @__PURE__ */ jsx(
|
|
2021
2048
|
TextInput,
|
|
2022
2049
|
{
|
|
2023
|
-
label: "
|
|
2050
|
+
label: t2("image.sourceUrl"),
|
|
2024
2051
|
defaultValue: ((_a = data.props) == null ? void 0 : _a.url) ?? "",
|
|
2025
2052
|
onChange: (v) => {
|
|
2026
2053
|
const url = v.trim().length === 0 ? null : v.trim();
|
|
@@ -2042,20 +2069,20 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2042
2069
|
Button,
|
|
2043
2070
|
{
|
|
2044
2071
|
variant: "outlined",
|
|
2045
|
-
startIcon: /* @__PURE__ */ jsx(CloudUploadOutlined, {}),
|
|
2072
|
+
startIcon: uploading ? /* @__PURE__ */ jsx(CircularProgress, { size: 16 }) : /* @__PURE__ */ jsx(CloudUploadOutlined, {}),
|
|
2046
2073
|
onClick: handleUploadClick,
|
|
2047
2074
|
disabled: uploading || !imageUploadHandler,
|
|
2048
2075
|
fullWidth: true,
|
|
2049
|
-
children: uploading ? "
|
|
2076
|
+
children: uploading ? t2("image.uploading") : t2("image.selectImage")
|
|
2050
2077
|
}
|
|
2051
2078
|
),
|
|
2052
|
-
!imageUploadHandler && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: "
|
|
2079
|
+
!imageUploadHandler && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: t2("image.uploadHandlerNotConfigured") })
|
|
2053
2080
|
] })
|
|
2054
2081
|
] }),
|
|
2055
2082
|
/* @__PURE__ */ jsx(
|
|
2056
2083
|
TextInput,
|
|
2057
2084
|
{
|
|
2058
|
-
label: "
|
|
2085
|
+
label: t2("image.altText"),
|
|
2059
2086
|
defaultValue: ((_b = data.props) == null ? void 0 : _b.alt) ?? "",
|
|
2060
2087
|
onChange: (alt) => updateData({ ...data, props: { ...data.props, alt } })
|
|
2061
2088
|
}
|
|
@@ -2063,7 +2090,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2063
2090
|
/* @__PURE__ */ jsx(
|
|
2064
2091
|
TextInput,
|
|
2065
2092
|
{
|
|
2066
|
-
label: "
|
|
2093
|
+
label: t2("image.clickThroughUrl"),
|
|
2067
2094
|
defaultValue: ((_c = data.props) == null ? void 0 : _c.linkHref) ?? "",
|
|
2068
2095
|
onChange: (v) => {
|
|
2069
2096
|
const linkHref = v.trim().length === 0 ? null : v.trim();
|
|
@@ -2075,7 +2102,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2075
2102
|
/* @__PURE__ */ jsx(
|
|
2076
2103
|
TextDimensionInput,
|
|
2077
2104
|
{
|
|
2078
|
-
label: "
|
|
2105
|
+
label: t2("image.width"),
|
|
2079
2106
|
defaultValue: (_d = data.props) == null ? void 0 : _d.width,
|
|
2080
2107
|
onChange: (width) => updateData({ ...data, props: { ...data.props, width } })
|
|
2081
2108
|
}
|
|
@@ -2083,7 +2110,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2083
2110
|
/* @__PURE__ */ jsx(
|
|
2084
2111
|
TextDimensionInput,
|
|
2085
2112
|
{
|
|
2086
|
-
label: "
|
|
2113
|
+
label: t2("image.height"),
|
|
2087
2114
|
defaultValue: (_e = data.props) == null ? void 0 : _e.height,
|
|
2088
2115
|
onChange: (height) => updateData({ ...data, props: { ...data.props, height } })
|
|
2089
2116
|
}
|
|
@@ -2092,7 +2119,7 @@ function ImageSidebarPanel({ data, setData }) {
|
|
|
2092
2119
|
/* @__PURE__ */ jsxs(
|
|
2093
2120
|
RadioGroupInput,
|
|
2094
2121
|
{
|
|
2095
|
-
label: "
|
|
2122
|
+
label: t2("image.alignment"),
|
|
2096
2123
|
defaultValue: ((_f = data.props) == null ? void 0 : _f.contentAlignment) ?? "middle",
|
|
2097
2124
|
onChange: (contentAlignment) => updateData({ ...data, props: { ...data.props, contentAlignment } }),
|
|
2098
2125
|
children: [
|
|
@@ -2202,12 +2229,12 @@ function renderMessage(val) {
|
|
|
2202
2229
|
}
|
|
2203
2230
|
function ConfigurationPanel() {
|
|
2204
2231
|
const { t: t2 } = useTranslation();
|
|
2205
|
-
const
|
|
2232
|
+
const document2 = useDocument();
|
|
2206
2233
|
const selectedBlockId = useSelectedBlockId();
|
|
2207
2234
|
if (!selectedBlockId) {
|
|
2208
2235
|
return renderMessage(t2("inspector.clickBlockToInspect"));
|
|
2209
2236
|
}
|
|
2210
|
-
const block =
|
|
2237
|
+
const block = document2[selectedBlockId];
|
|
2211
2238
|
if (!block) {
|
|
2212
2239
|
return renderMessage(t2("inspector.blockNotFound", { id: selectedBlockId }));
|
|
2213
2240
|
}
|
|
@@ -2273,7 +2300,8 @@ function InspectorDrawer() {
|
|
|
2273
2300
|
PaperProps: {
|
|
2274
2301
|
sx: {
|
|
2275
2302
|
position: "relative",
|
|
2276
|
-
height: "100%"
|
|
2303
|
+
height: "100%",
|
|
2304
|
+
zIndex: 0
|
|
2277
2305
|
}
|
|
2278
2306
|
},
|
|
2279
2307
|
sx: {
|
|
@@ -2282,10 +2310,12 @@ function InspectorDrawer() {
|
|
|
2282
2310
|
flexShrink: 0,
|
|
2283
2311
|
flexGrow: 0,
|
|
2284
2312
|
overflow: "hidden",
|
|
2313
|
+
zIndex: 0,
|
|
2285
2314
|
"& .MuiDrawer-paper": {
|
|
2286
2315
|
position: "relative",
|
|
2287
2316
|
height: "100%",
|
|
2288
|
-
width: "100%"
|
|
2317
|
+
width: "100%",
|
|
2318
|
+
zIndex: 0
|
|
2289
2319
|
}
|
|
2290
2320
|
},
|
|
2291
2321
|
children: [
|
|
@@ -2298,59 +2328,51 @@ function InspectorDrawer() {
|
|
|
2298
2328
|
}
|
|
2299
2329
|
);
|
|
2300
2330
|
}
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2331
|
+
const sampleTemplates = {
|
|
2332
|
+
welcome: () => import("./samples-BnRgwIcn.js").then((n) => n.w).then((m) => m.default),
|
|
2333
|
+
"one-time-password": () => import("./samples-BnRgwIcn.js").then((n) => n.o).then((m) => m.default),
|
|
2334
|
+
"order-ecomerce": () => import("./samples-BnRgwIcn.js").then((n) => n.a).then((m) => m.default),
|
|
2335
|
+
"post-metrics-report": () => import("./samples-BnRgwIcn.js").then((n) => n.p).then((m) => m.default),
|
|
2336
|
+
"reservation-reminder": () => import("./samples-BnRgwIcn.js").then((n) => n.r).then((m) => m.default),
|
|
2337
|
+
"reset-password": () => import("./samples-BnRgwIcn.js").then((n) => n.b).then((m) => m.default),
|
|
2338
|
+
"respond-to-message": () => import("./samples-BnRgwIcn.js").then((n) => n.c).then((m) => m.default),
|
|
2339
|
+
"subscription-receipt": () => import("./samples-BnRgwIcn.js").then((n) => n.s).then((m) => m.default),
|
|
2340
|
+
"basic-template": () => import("./samples-BnRgwIcn.js").then((n) => n.d).then((m) => m.default)
|
|
2341
|
+
};
|
|
2342
|
+
const templateCache = {};
|
|
2343
|
+
async function loadSampleTemplate(sampleName) {
|
|
2344
|
+
const loader = sampleTemplates[sampleName];
|
|
2345
|
+
if (!loader) {
|
|
2346
|
+
return EMPTY_EMAIL_MESSAGE;
|
|
2347
|
+
}
|
|
2348
|
+
if (templateCache[sampleName]) {
|
|
2349
|
+
return templateCache[sampleName];
|
|
2350
|
+
}
|
|
2351
|
+
const template = await loader();
|
|
2352
|
+
templateCache[sampleName] = template;
|
|
2353
|
+
return template;
|
|
2322
2354
|
}
|
|
2323
|
-
function SidebarButton({
|
|
2355
|
+
function SidebarButton({ sampleName, children }) {
|
|
2324
2356
|
const [loading, setLoading] = useState(false);
|
|
2325
2357
|
const handleClick = async () => {
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
} finally {
|
|
2335
|
-
setLoading(false);
|
|
2336
|
-
}
|
|
2337
|
-
} else {
|
|
2338
|
-
resetDocument(getConfiguration(href));
|
|
2358
|
+
setLoading(true);
|
|
2359
|
+
try {
|
|
2360
|
+
const template = await loadSampleTemplate(sampleName);
|
|
2361
|
+
resetDocument(template);
|
|
2362
|
+
} catch (error) {
|
|
2363
|
+
console.error("Failed to load template:", error);
|
|
2364
|
+
} finally {
|
|
2365
|
+
setLoading(false);
|
|
2339
2366
|
}
|
|
2340
2367
|
};
|
|
2341
|
-
return /* @__PURE__ */ jsx(Button, { size: "small",
|
|
2368
|
+
return /* @__PURE__ */ jsx(Button, { size: "small", onClick: handleClick, disabled: loading, children: loading ? "Loading..." : children });
|
|
2342
2369
|
}
|
|
2343
2370
|
const SAMPLES_DRAWER_WIDTH = 240;
|
|
2344
2371
|
function SamplesDrawer() {
|
|
2345
2372
|
const { t: t2 } = useTranslation();
|
|
2346
2373
|
const samplesDrawerOpen = useSamplesDrawerOpen();
|
|
2347
|
-
const currentHash = typeof window !== "undefined" ? window.location.hash : "";
|
|
2348
|
-
const isNewDocument = !currentHash || currentHash === "#";
|
|
2349
2374
|
const handleNewDocumentClick = () => {
|
|
2350
|
-
resetDocument(
|
|
2351
|
-
if (typeof window !== "undefined") {
|
|
2352
|
-
window.location.hash = "#";
|
|
2353
|
-
}
|
|
2375
|
+
resetDocument(EMPTY_EMAIL_MESSAGE);
|
|
2354
2376
|
};
|
|
2355
2377
|
return /* @__PURE__ */ jsx(
|
|
2356
2378
|
Drawer,
|
|
@@ -2361,7 +2383,8 @@ function SamplesDrawer() {
|
|
|
2361
2383
|
PaperProps: {
|
|
2362
2384
|
sx: {
|
|
2363
2385
|
position: "relative",
|
|
2364
|
-
height: "100%"
|
|
2386
|
+
height: "100%",
|
|
2387
|
+
zIndex: 0
|
|
2365
2388
|
}
|
|
2366
2389
|
},
|
|
2367
2390
|
sx: {
|
|
@@ -2370,10 +2393,12 @@ function SamplesDrawer() {
|
|
|
2370
2393
|
flexShrink: 0,
|
|
2371
2394
|
flexGrow: 0,
|
|
2372
2395
|
overflow: "hidden",
|
|
2396
|
+
zIndex: 0,
|
|
2373
2397
|
"& .MuiDrawer-paper": {
|
|
2374
2398
|
position: "relative",
|
|
2375
2399
|
height: "100%",
|
|
2376
|
-
width: "100%"
|
|
2400
|
+
width: "100%",
|
|
2401
|
+
zIndex: 0
|
|
2377
2402
|
}
|
|
2378
2403
|
},
|
|
2379
2404
|
children: /* @__PURE__ */ jsx(Stack, { spacing: 3, py: 1, px: 2, width: SAMPLES_DRAWER_WIDTH, children: /* @__PURE__ */ jsxs(Stack, { spacing: 2, sx: { "& .MuiButtonBase-root": { width: "100%", justifyContent: "flex-start" } }, children: [
|
|
@@ -2384,10 +2409,9 @@ function SamplesDrawer() {
|
|
|
2384
2409
|
size: "small",
|
|
2385
2410
|
variant: "contained",
|
|
2386
2411
|
color: "primary",
|
|
2387
|
-
href: "#",
|
|
2388
2412
|
onClick: handleNewDocumentClick,
|
|
2389
2413
|
sx: {
|
|
2390
|
-
fontWeight:
|
|
2414
|
+
fontWeight: 600,
|
|
2391
2415
|
width: "100%",
|
|
2392
2416
|
justifyContent: "flex-start"
|
|
2393
2417
|
},
|
|
@@ -2398,8 +2422,9 @@ function SamplesDrawer() {
|
|
|
2398
2422
|
/* @__PURE__ */ jsxs(Stack, { spacing: 1, children: [
|
|
2399
2423
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { px: 0.75, fontWeight: 500 }, children: t2("common.useBuiltInTemplates") }),
|
|
2400
2424
|
/* @__PURE__ */ jsxs(Stack, { alignItems: "flex-start", children: [
|
|
2401
|
-
/* @__PURE__ */ jsx(SidebarButton, {
|
|
2402
|
-
/* @__PURE__ */ jsx(SidebarButton, {
|
|
2425
|
+
/* @__PURE__ */ jsx(SidebarButton, { sampleName: "basic-template", children: t2("samples.quickStart") }),
|
|
2426
|
+
/* @__PURE__ */ jsx(SidebarButton, { sampleName: "welcome", children: t2("samples.welcomeEmail") }),
|
|
2427
|
+
/* @__PURE__ */ jsx(SidebarButton, { sampleName: "reservation-reminder", children: t2("samples.reservationReminder") })
|
|
2403
2428
|
] })
|
|
2404
2429
|
] })
|
|
2405
2430
|
] }) })
|
|
@@ -2763,7 +2788,7 @@ function ColumnsContainerEditor({ style, props }) {
|
|
|
2763
2788
|
}
|
|
2764
2789
|
function ContainerEditor({ style, props }) {
|
|
2765
2790
|
const childrenIds = (props == null ? void 0 : props.childrenIds) ?? [];
|
|
2766
|
-
const
|
|
2791
|
+
const document2 = useDocument();
|
|
2767
2792
|
const currentBlockId = useCurrentBlockId();
|
|
2768
2793
|
return /* @__PURE__ */ jsx(Container, { style, children: /* @__PURE__ */ jsx(
|
|
2769
2794
|
EditorChildrenIds,
|
|
@@ -2775,7 +2800,7 @@ function ContainerEditor({ style, props }) {
|
|
|
2775
2800
|
[currentBlockId]: {
|
|
2776
2801
|
type: "Container",
|
|
2777
2802
|
data: {
|
|
2778
|
-
...
|
|
2803
|
+
...document2[currentBlockId].data,
|
|
2779
2804
|
props: { childrenIds: childrenIds2 }
|
|
2780
2805
|
}
|
|
2781
2806
|
}
|
|
@@ -2810,7 +2835,7 @@ function getFontFamily(fontFamily) {
|
|
|
2810
2835
|
}
|
|
2811
2836
|
function EmailLayoutEditor(props) {
|
|
2812
2837
|
const childrenIds = props.childrenIds ?? [];
|
|
2813
|
-
const
|
|
2838
|
+
const document2 = useDocument();
|
|
2814
2839
|
const currentBlockId = useCurrentBlockId();
|
|
2815
2840
|
return /* @__PURE__ */ jsx(
|
|
2816
2841
|
"div",
|
|
@@ -2863,7 +2888,7 @@ function EmailLayoutEditor(props) {
|
|
|
2863
2888
|
[currentBlockId]: {
|
|
2864
2889
|
type: "EmailLayout",
|
|
2865
2890
|
data: {
|
|
2866
|
-
...
|
|
2891
|
+
...document2[currentBlockId].data,
|
|
2867
2892
|
childrenIds: childrenIds2
|
|
2868
2893
|
}
|
|
2869
2894
|
}
|
|
@@ -2910,7 +2935,7 @@ const sx = {
|
|
|
2910
2935
|
zIndex: "fab"
|
|
2911
2936
|
};
|
|
2912
2937
|
function TuneMenu({ blockId }) {
|
|
2913
|
-
const
|
|
2938
|
+
const document2 = useDocument();
|
|
2914
2939
|
const handleDeleteClick = () => {
|
|
2915
2940
|
var _a, _b, _c;
|
|
2916
2941
|
const filterChildrenIds = (childrenIds) => {
|
|
@@ -2919,7 +2944,7 @@ function TuneMenu({ blockId }) {
|
|
|
2919
2944
|
}
|
|
2920
2945
|
return childrenIds.filter((f) => f !== blockId);
|
|
2921
2946
|
};
|
|
2922
|
-
const nDocument = { ...
|
|
2947
|
+
const nDocument = { ...document2 };
|
|
2923
2948
|
for (const [id, b] of Object.entries(nDocument)) {
|
|
2924
2949
|
const block = b;
|
|
2925
2950
|
if (id === blockId) {
|
|
@@ -2986,7 +3011,7 @@ function TuneMenu({ blockId }) {
|
|
|
2986
3011
|
}
|
|
2987
3012
|
return childrenIds;
|
|
2988
3013
|
};
|
|
2989
|
-
const nDocument = { ...
|
|
3014
|
+
const nDocument = { ...document2 };
|
|
2990
3015
|
for (const [id, b] of Object.entries(nDocument)) {
|
|
2991
3016
|
const block = b;
|
|
2992
3017
|
if (id === blockId) {
|
|
@@ -3139,8 +3164,8 @@ const EditorConfigurationSchema = z.record(z.string(), EditorBlockSchema);
|
|
|
3139
3164
|
const EditorBlockContext = createContext(null);
|
|
3140
3165
|
const useCurrentBlockId = () => useContext(EditorBlockContext);
|
|
3141
3166
|
function EditorBlock({ id }) {
|
|
3142
|
-
const
|
|
3143
|
-
const block =
|
|
3167
|
+
const document2 = useDocument();
|
|
3168
|
+
const block = document2[id];
|
|
3144
3169
|
if (!block) {
|
|
3145
3170
|
throw new Error("Could not find block");
|
|
3146
3171
|
}
|
|
@@ -3168,28 +3193,60 @@ function ToggleSamplesPanelButton() {
|
|
|
3168
3193
|
return /* @__PURE__ */ jsx(IconButton, { onClick: toggleSamplesDrawerOpen, children: icon });
|
|
3169
3194
|
}
|
|
3170
3195
|
function DownloadJson() {
|
|
3196
|
+
const { t: t2 } = useTranslation();
|
|
3171
3197
|
const doc = useDocument();
|
|
3172
3198
|
const href = useMemo(() => {
|
|
3173
3199
|
return `data:text/plain,${encodeURIComponent(JSON.stringify(doc, null, " "))}`;
|
|
3174
3200
|
}, [doc]);
|
|
3175
|
-
return /* @__PURE__ */ jsx(Tooltip, { title: "
|
|
3201
|
+
return /* @__PURE__ */ jsx(Tooltip, { title: t2("common.downloadJson"), children: /* @__PURE__ */ jsx(IconButton, { href, download: "emailTemplate.json", children: /* @__PURE__ */ jsx(FileDownloadOutlined, { fontSize: "small" }) }) });
|
|
3176
3202
|
}
|
|
3177
3203
|
let hljs;
|
|
3178
3204
|
let jsonHighlighter;
|
|
3179
3205
|
let xmlHighlighter;
|
|
3180
3206
|
let prettierFormat;
|
|
3181
|
-
let prettierPluginBabel;
|
|
3182
|
-
let prettierPluginEstree;
|
|
3183
3207
|
let prettierPluginHtml;
|
|
3208
|
+
function escapeHtml(text) {
|
|
3209
|
+
if (typeof document === "undefined") {
|
|
3210
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3211
|
+
}
|
|
3212
|
+
const div = document.createElement("div");
|
|
3213
|
+
div.textContent = text;
|
|
3214
|
+
return div.innerHTML;
|
|
3215
|
+
}
|
|
3216
|
+
function loadHighlightJsCSS() {
|
|
3217
|
+
if (typeof document === "undefined") return;
|
|
3218
|
+
const existingLink = document.querySelector("link[data-highlight-js-css]");
|
|
3219
|
+
if (existingLink) return;
|
|
3220
|
+
try {
|
|
3221
|
+
const link = document.createElement("link");
|
|
3222
|
+
link.rel = "stylesheet";
|
|
3223
|
+
link.href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css";
|
|
3224
|
+
link.setAttribute("data-highlight-js-css", "true");
|
|
3225
|
+
document.head.appendChild(link);
|
|
3226
|
+
} catch (error) {
|
|
3227
|
+
console.warn("Failed to load highlight.js CSS:", error);
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3184
3230
|
async function loadHighlightJs() {
|
|
3185
3231
|
if (!hljs) {
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3232
|
+
try {
|
|
3233
|
+
const hljsModule = await import("highlight.js");
|
|
3234
|
+
hljs = hljsModule.default || hljsModule;
|
|
3235
|
+
jsonHighlighter = await import("highlight.js/lib/languages/json");
|
|
3236
|
+
xmlHighlighter = await import("highlight.js/lib/languages/xml");
|
|
3237
|
+
const jsonLang = jsonHighlighter.default || jsonHighlighter;
|
|
3238
|
+
const xmlLang = xmlHighlighter.default || xmlHighlighter;
|
|
3239
|
+
hljs.registerLanguage("json", jsonLang);
|
|
3240
|
+
hljs.registerLanguage("html", xmlLang);
|
|
3241
|
+
loadHighlightJsCSS();
|
|
3242
|
+
} catch (error) {
|
|
3243
|
+
console.error("Failed to load highlight.js. Please ensure highlight.js is installed:", error);
|
|
3244
|
+
hljs = {
|
|
3245
|
+
highlight: (code) => ({ value: escapeHtml(code) })
|
|
3246
|
+
};
|
|
3247
|
+
}
|
|
3191
3248
|
}
|
|
3192
|
-
return hljs
|
|
3249
|
+
return hljs;
|
|
3193
3250
|
}
|
|
3194
3251
|
function dynamicImport(path) {
|
|
3195
3252
|
const importFunc = new Function("path", "return import(path)");
|
|
@@ -3199,28 +3256,27 @@ async function loadPrettier() {
|
|
|
3199
3256
|
if (!prettierFormat) {
|
|
3200
3257
|
try {
|
|
3201
3258
|
const prettierMain = await import("prettier");
|
|
3259
|
+
const prettierVersion = prettierMain.version || "2.0.0";
|
|
3260
|
+
const majorVersion = parseInt(prettierVersion.split(".")[0], 10);
|
|
3261
|
+
if (majorVersion < 3) {
|
|
3262
|
+
prettierFormat = prettierMain.format;
|
|
3263
|
+
prettierPluginHtml = null;
|
|
3264
|
+
return prettierFormat;
|
|
3265
|
+
}
|
|
3202
3266
|
try {
|
|
3203
3267
|
const prettierStandalone = await dynamicImport("prettier/standalone");
|
|
3204
3268
|
prettierFormat = prettierStandalone.format;
|
|
3205
3269
|
try {
|
|
3206
|
-
|
|
3270
|
+
prettierPluginHtml = await dynamicImport("prettier/parser-html");
|
|
3207
3271
|
} catch {
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
prettierPluginEstree = null;
|
|
3214
|
-
}
|
|
3215
|
-
try {
|
|
3216
|
-
prettierPluginHtml = await dynamicImport("prettier/plugins/html");
|
|
3217
|
-
} catch {
|
|
3218
|
-
prettierPluginHtml = null;
|
|
3272
|
+
try {
|
|
3273
|
+
prettierPluginHtml = await dynamicImport("prettier/plugins/html");
|
|
3274
|
+
} catch {
|
|
3275
|
+
prettierPluginHtml = null;
|
|
3276
|
+
}
|
|
3219
3277
|
}
|
|
3220
3278
|
} catch {
|
|
3221
3279
|
prettierFormat = prettierMain.format;
|
|
3222
|
-
prettierPluginBabel = null;
|
|
3223
|
-
prettierPluginEstree = null;
|
|
3224
3280
|
prettierPluginHtml = null;
|
|
3225
3281
|
}
|
|
3226
3282
|
} catch (error) {
|
|
@@ -3231,28 +3287,200 @@ async function loadPrettier() {
|
|
|
3231
3287
|
return prettierFormat;
|
|
3232
3288
|
}
|
|
3233
3289
|
async function html(value) {
|
|
3234
|
-
|
|
3290
|
+
let hljsInstance;
|
|
3291
|
+
let format;
|
|
3292
|
+
try {
|
|
3293
|
+
[hljsInstance, format] = await Promise.all([loadHighlightJs(), loadPrettier()]);
|
|
3294
|
+
} catch (error) {
|
|
3295
|
+
console.error("Failed to load highlight.js or prettier:", error);
|
|
3296
|
+
return escapeHtml(value);
|
|
3297
|
+
}
|
|
3235
3298
|
const formatOptions = {
|
|
3236
|
-
parser: "html"
|
|
3299
|
+
parser: "html",
|
|
3300
|
+
printWidth: 120,
|
|
3301
|
+
tabWidth: 2,
|
|
3302
|
+
useTabs: false,
|
|
3303
|
+
htmlWhitespaceSensitivity: "ignore",
|
|
3304
|
+
// 忽略HTML空白敏感度,避免不必要的缩进
|
|
3305
|
+
bracketSameLine: false
|
|
3306
|
+
// 确保开始和结束标签在不同行,便于对齐
|
|
3237
3307
|
};
|
|
3238
3308
|
if (prettierPluginHtml) {
|
|
3239
|
-
|
|
3309
|
+
const htmlParser = prettierPluginHtml.default || prettierPluginHtml;
|
|
3310
|
+
formatOptions.plugins = [htmlParser];
|
|
3311
|
+
}
|
|
3312
|
+
const removeLeadingIndent = (text) => {
|
|
3313
|
+
const lines = text.split("\n");
|
|
3314
|
+
if (lines.length === 0) return text;
|
|
3315
|
+
const firstNonEmptyLine = lines.find((line) => line.trim().length > 0);
|
|
3316
|
+
if (!firstNonEmptyLine) return text;
|
|
3317
|
+
const trimmedFirstLine = firstNonEmptyLine.trim();
|
|
3318
|
+
const isRootTag = trimmedFirstLine.startsWith("<!DOCTYPE") || trimmedFirstLine.startsWith("<html");
|
|
3319
|
+
if (isRootTag) {
|
|
3320
|
+
const leadingSpaces = firstNonEmptyLine.length - firstNonEmptyLine.trimStart().length;
|
|
3321
|
+
if (leadingSpaces > 0) {
|
|
3322
|
+
return lines.map((line) => {
|
|
3323
|
+
if (line.trim().length === 0) return line;
|
|
3324
|
+
const currentLeading = line.length - line.trimStart().length;
|
|
3325
|
+
if (currentLeading >= leadingSpaces) {
|
|
3326
|
+
return line.substring(leadingSpaces);
|
|
3327
|
+
}
|
|
3328
|
+
return line;
|
|
3329
|
+
}).join("\n");
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
return text;
|
|
3333
|
+
};
|
|
3334
|
+
const fixTagAlignment = (text) => {
|
|
3335
|
+
var _a, _b;
|
|
3336
|
+
const lines = text.split("\n");
|
|
3337
|
+
const stack = [];
|
|
3338
|
+
const result = [];
|
|
3339
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3340
|
+
const line = lines[i];
|
|
3341
|
+
const trimmed = line.trim();
|
|
3342
|
+
if (!trimmed) {
|
|
3343
|
+
result.push(line);
|
|
3344
|
+
continue;
|
|
3345
|
+
}
|
|
3346
|
+
const currentIndent = line.length - line.trimStart().length;
|
|
3347
|
+
const isClosingTag = trimmed.startsWith("</");
|
|
3348
|
+
const isSelfClosing = trimmed.endsWith("/>");
|
|
3349
|
+
const isOpeningTag = trimmed.startsWith("<") && !isClosingTag && !isSelfClosing;
|
|
3350
|
+
if (isClosingTag) {
|
|
3351
|
+
const tagName = (_a = trimmed.match(/<\/(\w+)/)) == null ? void 0 : _a[1];
|
|
3352
|
+
if (tagName && stack.length > 0) {
|
|
3353
|
+
const opening = stack[stack.length - 1];
|
|
3354
|
+
if (opening.tag === tagName) {
|
|
3355
|
+
const correctIndent = opening.indent;
|
|
3356
|
+
result.push(" ".repeat(correctIndent) + trimmed);
|
|
3357
|
+
stack.pop();
|
|
3358
|
+
continue;
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
result.push(line);
|
|
3362
|
+
} else if (isOpeningTag) {
|
|
3363
|
+
const tagName = (_b = trimmed.match(/<(\w+)/)) == null ? void 0 : _b[1];
|
|
3364
|
+
if (tagName) {
|
|
3365
|
+
stack.push({ tag: tagName, indent: currentIndent });
|
|
3366
|
+
}
|
|
3367
|
+
result.push(line);
|
|
3368
|
+
} else {
|
|
3369
|
+
result.push(line);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
return result.join("\n");
|
|
3373
|
+
};
|
|
3374
|
+
let prettyValue;
|
|
3375
|
+
try {
|
|
3376
|
+
prettyValue = await format(value, formatOptions);
|
|
3377
|
+
if (!prettyValue || typeof prettyValue !== "string") {
|
|
3378
|
+
throw new Error("Prettier returned invalid value");
|
|
3379
|
+
}
|
|
3380
|
+
prettyValue = removeLeadingIndent(prettyValue);
|
|
3381
|
+
prettyValue = fixTagAlignment(prettyValue);
|
|
3382
|
+
} catch (error) {
|
|
3383
|
+
try {
|
|
3384
|
+
const prettierMain = await import("prettier");
|
|
3385
|
+
const mainFormatOptions = {
|
|
3386
|
+
parser: "html",
|
|
3387
|
+
printWidth: 120,
|
|
3388
|
+
tabWidth: 2,
|
|
3389
|
+
useTabs: false,
|
|
3390
|
+
htmlWhitespaceSensitivity: "ignore",
|
|
3391
|
+
bracketSameLine: false
|
|
3392
|
+
// 确保开始和结束标签在不同行,便于对齐
|
|
3393
|
+
};
|
|
3394
|
+
prettyValue = await prettierMain.format(value, mainFormatOptions);
|
|
3395
|
+
if (!prettyValue || typeof prettyValue !== "string") {
|
|
3396
|
+
throw new Error("Prettier main package returned invalid value");
|
|
3397
|
+
}
|
|
3398
|
+
prettyValue = removeLeadingIndent(prettyValue);
|
|
3399
|
+
prettyValue = fixTagAlignment(prettyValue);
|
|
3400
|
+
} catch (fallbackError) {
|
|
3401
|
+
try {
|
|
3402
|
+
let formatted = value.replace(/></g, ">\n<").replace(/\n\s*\n/g, "\n").split("\n");
|
|
3403
|
+
let indent = 0;
|
|
3404
|
+
const indentSize = 2;
|
|
3405
|
+
const result = [];
|
|
3406
|
+
for (let i = 0; i < formatted.length; i++) {
|
|
3407
|
+
const line = formatted[i];
|
|
3408
|
+
const trimmed = line.trim();
|
|
3409
|
+
if (!trimmed) {
|
|
3410
|
+
result.push("");
|
|
3411
|
+
continue;
|
|
3412
|
+
}
|
|
3413
|
+
const isClosingTag = trimmed.startsWith("</");
|
|
3414
|
+
const isSelfClosing = trimmed.endsWith("/>");
|
|
3415
|
+
const isOpeningTag = trimmed.startsWith("<") && !isClosingTag && !isSelfClosing;
|
|
3416
|
+
if (isClosingTag) {
|
|
3417
|
+
indent = Math.max(0, indent - indentSize);
|
|
3418
|
+
result.push(" ".repeat(indent) + trimmed);
|
|
3419
|
+
} else if (isOpeningTag) {
|
|
3420
|
+
result.push(" ".repeat(indent) + trimmed);
|
|
3421
|
+
indent += indentSize;
|
|
3422
|
+
} else if (isSelfClosing) {
|
|
3423
|
+
result.push(" ".repeat(indent) + trimmed);
|
|
3424
|
+
} else {
|
|
3425
|
+
result.push(" ".repeat(indent) + trimmed);
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
prettyValue = result.filter((line) => line.length > 0).join("\n");
|
|
3429
|
+
} catch {
|
|
3430
|
+
console.warn("Failed to format HTML, returning original value:", error);
|
|
3431
|
+
prettyValue = value;
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
try {
|
|
3436
|
+
return hljsInstance.highlight(prettyValue, { language: "html" }).value;
|
|
3437
|
+
} catch (error) {
|
|
3438
|
+
console.error("Failed to highlight HTML:", error);
|
|
3439
|
+
return escapeHtml(prettyValue);
|
|
3240
3440
|
}
|
|
3241
|
-
const prettyValue = await format(value, formatOptions);
|
|
3242
|
-
return hljsInstance.highlight(prettyValue, { language: "html" }).value;
|
|
3243
3441
|
}
|
|
3244
3442
|
async function json(value) {
|
|
3245
|
-
|
|
3443
|
+
let hljsInstance;
|
|
3444
|
+
let format;
|
|
3445
|
+
try {
|
|
3446
|
+
[hljsInstance, format] = await Promise.all([loadHighlightJs(), loadPrettier()]);
|
|
3447
|
+
} catch (error) {
|
|
3448
|
+
console.error("Failed to load highlight.js or prettier:", error);
|
|
3449
|
+
return escapeHtml(value);
|
|
3450
|
+
}
|
|
3246
3451
|
const formatOptions = {
|
|
3247
|
-
parser: "json"
|
|
3248
|
-
printWidth: 0
|
|
3249
|
-
trailingComma:
|
|
3452
|
+
parser: "json"
|
|
3453
|
+
// 移除 printWidth: 0,使用默认值或设置一个合理的值
|
|
3454
|
+
// trailingComma: 'all' 在 JSON 中可能不支持,移除
|
|
3250
3455
|
};
|
|
3251
|
-
|
|
3252
|
-
|
|
3456
|
+
let prettyValue;
|
|
3457
|
+
try {
|
|
3458
|
+
prettyValue = await format(value, formatOptions);
|
|
3459
|
+
} catch (error) {
|
|
3460
|
+
try {
|
|
3461
|
+
const prettierMain = await import("prettier");
|
|
3462
|
+
prettyValue = await prettierMain.format(value, {
|
|
3463
|
+
parser: "json"
|
|
3464
|
+
});
|
|
3465
|
+
} catch (fallbackError) {
|
|
3466
|
+
try {
|
|
3467
|
+
const parsed = JSON.parse(value);
|
|
3468
|
+
prettyValue = JSON.stringify(parsed, null, 2);
|
|
3469
|
+
} catch {
|
|
3470
|
+
console.warn("Failed to format JSON, returning original value:", error);
|
|
3471
|
+
prettyValue = value;
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
if (typeof prettyValue !== "string") {
|
|
3476
|
+
prettyValue = JSON.stringify(prettyValue, null, 2);
|
|
3477
|
+
}
|
|
3478
|
+
try {
|
|
3479
|
+
return hljsInstance.highlight(prettyValue, { language: "json" }).value;
|
|
3480
|
+
} catch (error) {
|
|
3481
|
+
console.error("Failed to highlight JSON:", error);
|
|
3482
|
+
return escapeHtml(prettyValue);
|
|
3253
3483
|
}
|
|
3254
|
-
const prettyValue = await format(value, formatOptions);
|
|
3255
|
-
return hljsInstance.highlight(prettyValue, { language: "javascript" }).value;
|
|
3256
3484
|
}
|
|
3257
3485
|
function HighlightedCodePanel({ type, value }) {
|
|
3258
3486
|
const [code, setCode] = useState(null);
|
|
@@ -3285,8 +3513,8 @@ function HighlightedCodePanel({ type, value }) {
|
|
|
3285
3513
|
);
|
|
3286
3514
|
}
|
|
3287
3515
|
function HtmlPanel() {
|
|
3288
|
-
const
|
|
3289
|
-
const code = useMemo(() => renderToStaticMarkup(
|
|
3516
|
+
const document2 = useDocument();
|
|
3517
|
+
const code = useMemo(() => renderToStaticMarkup(document2, { rootBlockId: "root" }), [document2]);
|
|
3290
3518
|
return /* @__PURE__ */ jsx(HighlightedCodePanel, { type: "html", value: code });
|
|
3291
3519
|
}
|
|
3292
3520
|
function validateTextAreaValue(value) {
|
|
@@ -3374,19 +3602,20 @@ function ImportJsonDialog({ onClose }) {
|
|
|
3374
3602
|
] });
|
|
3375
3603
|
}
|
|
3376
3604
|
function ImportJson() {
|
|
3605
|
+
const { t: t2 } = useTranslation();
|
|
3377
3606
|
const [open, setOpen] = useState(false);
|
|
3378
3607
|
let dialog = null;
|
|
3379
3608
|
if (open) {
|
|
3380
3609
|
dialog = /* @__PURE__ */ jsx(ImportJsonDialog, { onClose: () => setOpen(false) });
|
|
3381
3610
|
}
|
|
3382
3611
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3383
|
-
/* @__PURE__ */ jsx(Tooltip, { title: "
|
|
3612
|
+
/* @__PURE__ */ jsx(Tooltip, { title: t2("common.importJson"), children: /* @__PURE__ */ jsx(IconButton, { onClick: () => setOpen(true), children: /* @__PURE__ */ jsx(FileUploadOutlined, { fontSize: "small" }) }) }),
|
|
3384
3613
|
dialog
|
|
3385
3614
|
] });
|
|
3386
3615
|
}
|
|
3387
3616
|
function JsonPanel() {
|
|
3388
|
-
const
|
|
3389
|
-
const code = useMemo(() => JSON.stringify(
|
|
3617
|
+
const document2 = useDocument();
|
|
3618
|
+
const code = useMemo(() => JSON.stringify(document2, null, " "), [document2]);
|
|
3390
3619
|
return /* @__PURE__ */ jsx(HighlightedCodePanel, { type: "json", value: code });
|
|
3391
3620
|
}
|
|
3392
3621
|
function MainTabsGroup() {
|
|
@@ -3435,32 +3664,93 @@ function MainTabsGroup() {
|
|
|
3435
3664
|
)
|
|
3436
3665
|
] });
|
|
3437
3666
|
}
|
|
3438
|
-
function
|
|
3439
|
-
const
|
|
3440
|
-
const
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3667
|
+
function NameInput() {
|
|
3668
|
+
const { t: t2 } = useTranslation();
|
|
3669
|
+
const name = useName();
|
|
3670
|
+
return /* @__PURE__ */ jsx(
|
|
3671
|
+
Typography,
|
|
3672
|
+
{
|
|
3673
|
+
component: "span",
|
|
3674
|
+
variant: "body2",
|
|
3675
|
+
sx: {
|
|
3676
|
+
position: "absolute",
|
|
3677
|
+
left: "50%",
|
|
3678
|
+
transform: "translateX(-50%)",
|
|
3679
|
+
maxWidth: "300px",
|
|
3680
|
+
overflow: "hidden",
|
|
3681
|
+
textOverflow: "ellipsis",
|
|
3682
|
+
whiteSpace: "nowrap",
|
|
3683
|
+
color: "text.primary",
|
|
3684
|
+
fontWeight: 500
|
|
3685
|
+
},
|
|
3686
|
+
children: name || t2("common.unnamedTemplate")
|
|
3687
|
+
}
|
|
3688
|
+
);
|
|
3689
|
+
}
|
|
3690
|
+
function SaveAndExitButton() {
|
|
3691
|
+
const { t: t2 } = useTranslation();
|
|
3692
|
+
const saveHandler = useSaveHandler();
|
|
3693
|
+
const saveAndExitHandler = useSaveAndExitHandler();
|
|
3694
|
+
const [saving, setSaving] = useState(false);
|
|
3695
|
+
const handleSaveAndExit = async () => {
|
|
3696
|
+
if (!saveAndExitHandler) {
|
|
3697
|
+
console.warn("Save and exit handler is not configured.");
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
setSaving(true);
|
|
3701
|
+
try {
|
|
3702
|
+
if (saveHandler) {
|
|
3703
|
+
await saveDocument();
|
|
3704
|
+
}
|
|
3705
|
+
saveAndExitDocument(saveAndExitHandler);
|
|
3706
|
+
} catch (error) {
|
|
3707
|
+
console.error("Failed to save and exit:", error);
|
|
3708
|
+
} finally {
|
|
3709
|
+
setSaving(false);
|
|
3710
|
+
}
|
|
3445
3711
|
};
|
|
3446
|
-
|
|
3447
|
-
|
|
3712
|
+
return /* @__PURE__ */ jsx(Tooltip, { title: t2("common.saveAndExit"), children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
3713
|
+
IconButton,
|
|
3714
|
+
{
|
|
3715
|
+
color: "primary",
|
|
3716
|
+
size: "small",
|
|
3717
|
+
onClick: handleSaveAndExit,
|
|
3718
|
+
disabled: saving || !saveAndExitHandler,
|
|
3719
|
+
children: saving ? /* @__PURE__ */ jsx(CircularProgress, { size: 16, color: "inherit" }) : /* @__PURE__ */ jsx(ExitToAppOutlined, { fontSize: "small" })
|
|
3720
|
+
}
|
|
3721
|
+
) }) });
|
|
3722
|
+
}
|
|
3723
|
+
function SaveButton() {
|
|
3724
|
+
const { t: t2 } = useTranslation();
|
|
3725
|
+
const saveHandler = useSaveHandler();
|
|
3726
|
+
const [saving, setSaving] = useState(false);
|
|
3727
|
+
const handleSave = async () => {
|
|
3728
|
+
if (!saveHandler) {
|
|
3729
|
+
console.warn("Save handler is not configured. Please set saveHandler in EmailBuilder props.");
|
|
3730
|
+
return;
|
|
3731
|
+
}
|
|
3732
|
+
setSaving(true);
|
|
3733
|
+
try {
|
|
3734
|
+
await saveDocument();
|
|
3735
|
+
} catch (error) {
|
|
3736
|
+
console.error("Failed to save document:", error);
|
|
3737
|
+
} finally {
|
|
3738
|
+
setSaving(false);
|
|
3739
|
+
}
|
|
3448
3740
|
};
|
|
3449
|
-
return /* @__PURE__ */
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
}
|
|
3459
|
-
)
|
|
3460
|
-
] });
|
|
3741
|
+
return /* @__PURE__ */ jsx(Tooltip, { title: t2("common.save"), children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
3742
|
+
IconButton,
|
|
3743
|
+
{
|
|
3744
|
+
color: "primary",
|
|
3745
|
+
onClick: handleSave,
|
|
3746
|
+
disabled: saving || !saveHandler,
|
|
3747
|
+
children: saving ? /* @__PURE__ */ jsx(CircularProgress, { size: 16 }) : /* @__PURE__ */ jsx(SaveOutlined, { fontSize: "small" })
|
|
3748
|
+
}
|
|
3749
|
+
) }) });
|
|
3461
3750
|
}
|
|
3462
3751
|
function TemplatePanel() {
|
|
3463
|
-
const
|
|
3752
|
+
const { t: t2 } = useTranslation();
|
|
3753
|
+
const document2 = useDocument();
|
|
3464
3754
|
const selectedMainTab = useSelectedMainTab();
|
|
3465
3755
|
const selectedScreenSize = useSelectedScreenSize();
|
|
3466
3756
|
let mainBoxSx = {
|
|
@@ -3491,7 +3781,7 @@ function TemplatePanel() {
|
|
|
3491
3781
|
case "editor":
|
|
3492
3782
|
return /* @__PURE__ */ jsx(Box, { sx: mainBoxSx, children: /* @__PURE__ */ jsx(EditorBlock, { id: "root" }) });
|
|
3493
3783
|
case "preview":
|
|
3494
|
-
return /* @__PURE__ */ jsx(Box, { sx: mainBoxSx, children: /* @__PURE__ */ jsx(Reader, { document, rootBlockId: "root" }) });
|
|
3784
|
+
return /* @__PURE__ */ jsx(Box, { sx: mainBoxSx, children: /* @__PURE__ */ jsx(Reader, { document: document2, rootBlockId: "root" }) });
|
|
3495
3785
|
case "html":
|
|
3496
3786
|
return /* @__PURE__ */ jsx(HtmlPanel, {});
|
|
3497
3787
|
case "json":
|
|
@@ -3508,7 +3798,8 @@ function TemplatePanel() {
|
|
|
3508
3798
|
borderColor: "divider",
|
|
3509
3799
|
backgroundColor: "white",
|
|
3510
3800
|
flexShrink: 0,
|
|
3511
|
-
|
|
3801
|
+
position: "relative",
|
|
3802
|
+
zIndex: 1,
|
|
3512
3803
|
px: 1
|
|
3513
3804
|
},
|
|
3514
3805
|
direction: "row",
|
|
@@ -3516,16 +3807,18 @@ function TemplatePanel() {
|
|
|
3516
3807
|
alignItems: "center",
|
|
3517
3808
|
children: [
|
|
3518
3809
|
/* @__PURE__ */ jsx(ToggleSamplesPanelButton, {}),
|
|
3810
|
+
/* @__PURE__ */ jsx(NameInput, {}),
|
|
3519
3811
|
/* @__PURE__ */ jsxs(Stack, { px: 2, direction: "row", gap: 2, width: "100%", justifyContent: "space-between", alignItems: "center", children: [
|
|
3520
3812
|
/* @__PURE__ */ jsx(Stack, { direction: "row", spacing: 2, children: /* @__PURE__ */ jsx(MainTabsGroup, {}) }),
|
|
3521
|
-
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 2, children: [
|
|
3813
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 2, alignItems: "center", children: [
|
|
3522
3814
|
/* @__PURE__ */ jsx(DownloadJson, {}),
|
|
3523
3815
|
/* @__PURE__ */ jsx(ImportJson, {}),
|
|
3524
|
-
/* @__PURE__ */
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3816
|
+
/* @__PURE__ */ jsx(SaveButton, {}),
|
|
3817
|
+
/* @__PURE__ */ jsx(SaveAndExitButton, {}),
|
|
3818
|
+
/* @__PURE__ */ jsxs(ToggleButtonGroup, { size: "small", value: selectedScreenSize, exclusive: true, onChange: handleScreenSizeChange, children: [
|
|
3819
|
+
/* @__PURE__ */ jsx(ToggleButton, { value: "desktop", children: /* @__PURE__ */ jsx(Tooltip, { title: t2("common.desktopView"), children: /* @__PURE__ */ jsx(MonitorOutlined, { fontSize: "small" }) }) }),
|
|
3820
|
+
/* @__PURE__ */ jsx(ToggleButton, { value: "mobile", children: /* @__PURE__ */ jsx(Tooltip, { title: t2("common.mobileView"), children: /* @__PURE__ */ jsx(PhoneIphoneOutlined, { fontSize: "small" }) }) })
|
|
3821
|
+
] })
|
|
3529
3822
|
] })
|
|
3530
3823
|
] }),
|
|
3531
3824
|
/* @__PURE__ */ jsx(ToggleInspectorPanelButton, {})
|
|
@@ -3559,7 +3852,7 @@ function App() {
|
|
|
3559
3852
|
},
|
|
3560
3853
|
children: [
|
|
3561
3854
|
/* @__PURE__ */ jsx(SamplesDrawer, {}),
|
|
3562
|
-
/* @__PURE__ */
|
|
3855
|
+
/* @__PURE__ */ jsx(
|
|
3563
3856
|
Stack,
|
|
3564
3857
|
{
|
|
3565
3858
|
sx: {
|
|
@@ -3568,12 +3861,10 @@ function App() {
|
|
|
3568
3861
|
// 允许 flex 项目收缩到内容以下
|
|
3569
3862
|
transition: `${marginLeftTransition}, ${marginRightTransition}`,
|
|
3570
3863
|
position: "relative",
|
|
3571
|
-
overflow: "hidden"
|
|
3864
|
+
overflow: "hidden",
|
|
3865
|
+
zIndex: 0
|
|
3572
3866
|
},
|
|
3573
|
-
children:
|
|
3574
|
-
/* @__PURE__ */ jsx(Box, { sx: { position: "absolute", top: 8, right: 8, zIndex: 1e3 }, children: /* @__PURE__ */ jsx(LanguageSwitcher, {}) }),
|
|
3575
|
-
/* @__PURE__ */ jsx(TemplatePanel, {})
|
|
3576
|
-
]
|
|
3867
|
+
children: /* @__PURE__ */ jsx(TemplatePanel, {})
|
|
3577
3868
|
}
|
|
3578
3869
|
),
|
|
3579
3870
|
/* @__PURE__ */ jsx(InspectorDrawer, {})
|
|
@@ -3586,38 +3877,42 @@ function EmailBuilder({
|
|
|
3586
3877
|
initialLanguage = "en",
|
|
3587
3878
|
imageUploadHandler,
|
|
3588
3879
|
onChange,
|
|
3880
|
+
saveHandler,
|
|
3881
|
+
saveAndExitHandler,
|
|
3882
|
+
initialName,
|
|
3883
|
+
onNameChange,
|
|
3589
3884
|
theme: customTheme
|
|
3590
3885
|
}) {
|
|
3591
|
-
const currentLanguage = useLanguage();
|
|
3592
3886
|
useEffect(() => {
|
|
3593
|
-
if (initialDocument) {
|
|
3887
|
+
if (initialDocument !== void 0) {
|
|
3594
3888
|
resetDocument(initialDocument);
|
|
3595
3889
|
}
|
|
3596
|
-
|
|
3597
|
-
setLanguage(initialLanguage);
|
|
3598
|
-
}
|
|
3599
|
-
if (imageUploadHandler) {
|
|
3600
|
-
setImageUploadHandler(imageUploadHandler);
|
|
3601
|
-
}
|
|
3602
|
-
if (onChange) {
|
|
3603
|
-
setOnChange(onChange);
|
|
3604
|
-
}
|
|
3605
|
-
}, []);
|
|
3890
|
+
}, [initialDocument]);
|
|
3606
3891
|
useEffect(() => {
|
|
3607
|
-
if (initialLanguage
|
|
3892
|
+
if (initialLanguage !== void 0) {
|
|
3608
3893
|
setLanguage(initialLanguage);
|
|
3609
3894
|
}
|
|
3610
|
-
}, [initialLanguage
|
|
3895
|
+
}, [initialLanguage]);
|
|
3611
3896
|
useEffect(() => {
|
|
3612
|
-
|
|
3613
|
-
setImageUploadHandler(imageUploadHandler);
|
|
3614
|
-
}
|
|
3897
|
+
setImageUploadHandler(imageUploadHandler);
|
|
3615
3898
|
}, [imageUploadHandler]);
|
|
3616
3899
|
useEffect(() => {
|
|
3617
|
-
|
|
3618
|
-
setOnChange(onChange);
|
|
3619
|
-
}
|
|
3900
|
+
setOnChange(onChange);
|
|
3620
3901
|
}, [onChange]);
|
|
3902
|
+
useEffect(() => {
|
|
3903
|
+
setSaveHandler(saveHandler);
|
|
3904
|
+
}, [saveHandler]);
|
|
3905
|
+
useEffect(() => {
|
|
3906
|
+
setSaveAndExitHandler(saveAndExitHandler);
|
|
3907
|
+
}, [saveAndExitHandler]);
|
|
3908
|
+
useEffect(() => {
|
|
3909
|
+
if (initialName !== void 0) {
|
|
3910
|
+
setName(initialName);
|
|
3911
|
+
}
|
|
3912
|
+
}, [initialName]);
|
|
3913
|
+
useEffect(() => {
|
|
3914
|
+
setOnNameChange(onNameChange);
|
|
3915
|
+
}, [onNameChange]);
|
|
3621
3916
|
return /* @__PURE__ */ jsxs(ThemeProvider, { theme: customTheme || THEME, children: [
|
|
3622
3917
|
/* @__PURE__ */ jsx(CssBaseline, {}),
|
|
3623
3918
|
/* @__PURE__ */ jsx(
|