Skip to content

Commit f151682

Browse files
finnar-binagalin920shrunyanallenpigargithub-actions[bot]
authored
Chore/fix merge issues (#2968)
Co-authored-by: Andres Galindo <agalin920@gmail.com> Co-authored-by: Stuart Runyan <shrunyan@gmail.com> Co-authored-by: Allen Pigar <50983144+allenpigar@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent deeb2f5 commit f151682

File tree

16 files changed

+274
-204
lines changed

16 files changed

+274
-204
lines changed

package-lock.json

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"@tinymce/tinymce-react": "^4.3.0",
6060
"@welldone-software/why-did-you-render": "^6.1.1",
6161
"@zesty-io/core": "1.10.0",
62-
"@zesty-io/material": "^0.15.3",
62+
"@zesty-io/material": "^0.15.5",
6363
"chart.js": "^3.8.0",
6464
"chartjs-adapter-moment": "^1.0.1",
6565
"chartjs-plugin-datalabels": "^2.0.0",

src/apps/content-editor/src/app/components/Editor/Editor.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -275,19 +275,29 @@ export default memo(function Editor({
275275
}
276276

277277
if (firstContentField && firstContentField.name === name) {
278+
// Remove tags and replace MS smart quotes with regular quotes
279+
const cleanedValue = value
280+
?.replace(/<[^>]*>/g, "")
281+
?.replaceAll(/[\u2018\u2019\u201A]/gm, "'")
282+
?.replaceAll("&rsquo;", "'")
283+
?.replaceAll(/[\u201C\u201D\u201E]/gm, '"')
284+
?.replaceAll("&ldquo;", '"')
285+
?.replaceAll("&rdquo;", '"')
286+
?.slice(0, 160);
287+
278288
dispatch({
279289
type: "SET_ITEM_WEB",
280290
itemZUID,
281291
key: "metaDescription",
282-
value: value.replace(/<[^>]*>/g, "").slice(0, 160),
292+
value: cleanedValue,
283293
});
284294

285295
if ("og_description" in metaFields) {
286296
dispatch({
287297
type: "SET_ITEM_DATA",
288298
itemZUID,
289299
key: "og_description",
290-
value: value.replace(/<[^>]*>/g, "").slice(0, 160),
300+
value: cleanedValue,
291301
});
292302
}
293303

@@ -296,7 +306,7 @@ export default memo(function Editor({
296306
type: "SET_ITEM_DATA",
297307
itemZUID,
298308
key: "tc_description",
299-
value: value.replace(/<[^>]*>/g, "").slice(0, 160),
309+
value: cleanedValue,
300310
});
301311
}
302312
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { useMemo, useRef, useEffect } from "react";
1+
import {
2+
useMemo,
3+
useRef,
4+
useEffect,
5+
forwardRef,
6+
useImperativeHandle,
7+
} from "react";
28
import { Stack, Typography, Box, ThemeProvider } from "@mui/material";
39
import DangerousRoundedIcon from "@mui/icons-material/DangerousRounded";
410
import { theme } from "@zesty-io/material";
@@ -64,97 +70,115 @@ const getErrorMessage = (errors: Error) => {
6470
return errorMessages;
6571
};
6672

67-
export const FieldError = ({ errors, fields }: FieldErrorProps) => {
68-
const errorContainerEl = useRef(null);
69-
70-
// Scroll to the errors on mount
71-
useEffect(() => {
72-
errorContainerEl?.current?.scrollIntoView({
73-
behavior: "smooth",
74-
block: "center",
75-
inline: "center",
76-
});
77-
}, []);
78-
79-
const fieldErrors = useMemo(() => {
80-
const errorMap = Object.entries(errors)?.map(([name, errorDetails]) => {
81-
const errorMessages = getErrorMessage(errorDetails);
82-
83-
const fieldData = fields?.find((field) => field.name === name);
84-
85-
return {
86-
label:
87-
fieldData?.label ||
88-
SEO_FIELD_LABELS[name as keyof typeof SEO_FIELD_LABELS],
89-
errorMessages,
90-
sort: fieldData?.sort,
91-
ZUID: fieldData?.ZUID || name,
92-
};
93-
});
94-
95-
return errorMap.sort((a, b) => a.sort - b.sort);
96-
}, [errors, fields]);
97-
98-
const fieldsWithErrors = fieldErrors?.filter(
99-
(error) => error.errorMessages.length > 0
100-
);
101-
102-
const handleErrorClick = (fieldZUID: string) => {
103-
const fieldElement = document.getElementById(fieldZUID);
104-
fieldElement?.scrollIntoView({ behavior: "smooth" });
105-
};
106-
107-
return (
108-
<ThemeProvider theme={theme}>
109-
<Stack
110-
data-cy="FieldErrorsList"
111-
ref={errorContainerEl}
112-
p={2}
113-
gap={1}
114-
borderRadius={1}
115-
sx={{ backgroundColor: "red.50", color: "error.dark" }}
116-
>
117-
<DangerousRoundedIcon color="inherit" fontSize="small" />
118-
<Typography variant="h6">
119-
Item cannot be saved due to invalid field values.
120-
</Typography>
121-
<Typography variant="body2">
122-
Please correct the following {fieldsWithErrors?.length} field
123-
{fieldsWithErrors?.length > 1 && "s"} before saving:
124-
</Typography>
125-
<Box component="ol" ml={2}>
126-
{fieldErrors?.map((error, index) => {
127-
if (error.errorMessages.length > 0) {
128-
return (
129-
<Typography key={index} variant="body2" component="li">
130-
<Box
131-
sx={{
132-
borderBottom: 1,
133-
borderColor: "error.dark",
134-
cursor: "pointer",
135-
height: 16,
136-
display: "inline-block",
137-
}}
138-
component="span"
139-
onClick={() => handleErrorClick(error.ZUID)}
140-
>
141-
{error.label}
142-
</Box>
143-
{error.errorMessages.length === 1 ? (
144-
<i> - {error.errorMessages[0]}</i>
145-
) : (
146-
<Box component="ul" sx={{ pl: 3, listStyleType: "disc" }}>
147-
{error.errorMessages.map((msg, idx) => (
148-
<li key={idx}>{msg}</li>
149-
))}
73+
export const FieldError = forwardRef(
74+
({ errors, fields }: FieldErrorProps, ref) => {
75+
const errorContainerEl = useRef(null);
76+
77+
useImperativeHandle(
78+
ref,
79+
() => {
80+
return {
81+
scrollToErrors() {
82+
errorContainerEl?.current?.scrollIntoView({
83+
behavior: "smooth",
84+
block: "center",
85+
inline: "center",
86+
});
87+
},
88+
};
89+
},
90+
[errorContainerEl]
91+
);
92+
93+
// Scroll to the errors on mount
94+
useEffect(() => {
95+
errorContainerEl?.current?.scrollIntoView({
96+
behavior: "smooth",
97+
block: "center",
98+
inline: "center",
99+
});
100+
}, []);
101+
102+
const fieldErrors = useMemo(() => {
103+
const errorMap = Object.entries(errors)?.map(([name, errorDetails]) => {
104+
const errorMessages = getErrorMessage(errorDetails);
105+
106+
const fieldData = fields?.find((field) => field.name === name);
107+
108+
return {
109+
label:
110+
fieldData?.label ||
111+
SEO_FIELD_LABELS[name as keyof typeof SEO_FIELD_LABELS],
112+
errorMessages,
113+
sort: fieldData?.sort,
114+
ZUID: fieldData?.ZUID || name,
115+
};
116+
});
117+
118+
return errorMap.sort((a, b) => a.sort - b.sort);
119+
}, [errors, fields]);
120+
121+
const fieldsWithErrors = fieldErrors?.filter(
122+
(error) => error.errorMessages.length > 0
123+
);
124+
125+
const handleErrorClick = (fieldZUID: string) => {
126+
const fieldElement = document.getElementById(fieldZUID);
127+
fieldElement?.scrollIntoView({ behavior: "smooth" });
128+
};
129+
130+
return (
131+
<ThemeProvider theme={theme}>
132+
<Stack
133+
data-cy="FieldErrorsList"
134+
ref={errorContainerEl}
135+
p={2}
136+
gap={1}
137+
borderRadius={1}
138+
sx={{ backgroundColor: "red.50", color: "error.dark" }}
139+
>
140+
<DangerousRoundedIcon color="inherit" fontSize="small" />
141+
<Typography variant="h6">
142+
Item cannot be saved due to invalid field values.
143+
</Typography>
144+
<Typography variant="body2">
145+
Please correct the following {fieldsWithErrors?.length} field
146+
{fieldsWithErrors?.length > 1 && "s"} before saving:
147+
</Typography>
148+
<Box component="ol" ml={2}>
149+
{fieldErrors?.map((error, index) => {
150+
if (error.errorMessages.length > 0) {
151+
return (
152+
<Typography key={index} variant="body2" component="li">
153+
<Box
154+
sx={{
155+
borderBottom: 1,
156+
borderColor: "error.dark",
157+
cursor: "pointer",
158+
height: 16,
159+
display: "inline-block",
160+
}}
161+
component="span"
162+
onClick={() => handleErrorClick(error.ZUID)}
163+
>
164+
{error.label}
150165
</Box>
151-
)}
152-
</Typography>
153-
);
154-
}
155-
})}
156-
</Box>
157-
</Stack>
158-
</ThemeProvider>
159-
);
160-
};
166+
{error.errorMessages.length === 1 ? (
167+
<i> - {error.errorMessages[0]}</i>
168+
) : (
169+
<Box component="ul" sx={{ pl: 3, listStyleType: "disc" }}>
170+
{error.errorMessages.map((msg, idx) => (
171+
<li key={idx}>{msg}</li>
172+
))}
173+
</Box>
174+
)}
175+
</Typography>
176+
);
177+
}
178+
})}
179+
</Box>
180+
</Stack>
181+
</ThemeProvider>
182+
);
183+
}
184+
);

src/apps/content-editor/src/app/components/PendingEditsModal/PendingEditsModal.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export default memo(function PendingEditsModal(props: PendingEditsModalProps) {
5151
answer(true);
5252
})
5353
.catch((err) => {
54+
console.error(err);
5455
// @ts-ignore
5556
answer(false);
5657
})

src/apps/content-editor/src/app/views/ItemCreate/ItemCreate.tsx

+22-8
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const ItemCreate = () => {
8484
// const [hasSEOErrors, setHasSEOErrors] = useState(false);
8585
const [SEOErrors, setSEOErrors] = useState<FieldErrors>({});
8686
const metaRef = useRef(null);
87+
const fieldErrorRef = useRef(null);
8788

8889
const [
8990
createPublishing,
@@ -182,7 +183,10 @@ export const ItemCreate = () => {
182183
setSaveClicked(true);
183184

184185
metaRef.current?.validateMetaFields?.();
185-
if (hasErrors || hasSEOErrors) return;
186+
if (hasErrors || hasSEOErrors) {
187+
fieldErrorRef.current?.scrollToErrors?.();
188+
return;
189+
}
186190

187191
setSaving(true);
188192

@@ -266,6 +270,7 @@ export const ItemCreate = () => {
266270
setFieldErrors(errors);
267271

268272
// scroll to required field
273+
fieldErrorRef.current?.scrollToErrors?.();
269274
}
270275

271276
if (res.error) {
@@ -382,12 +387,15 @@ export const ItemCreate = () => {
382387
direction="row"
383388
gap={4}
384389
>
385-
<Box width="60%" height="100%">
390+
<Box width="60%" minWidth={640} height="100%">
386391
{saveClicked && (hasErrors || hasSEOErrors) && (
387-
<FieldError
388-
errors={{ ...fieldErrors, ...SEOErrors }}
389-
fields={activeFields}
390-
/>
392+
<Box mb={3}>
393+
<FieldError
394+
ref={fieldErrorRef}
395+
errors={{ ...fieldErrors, ...SEOErrors }}
396+
fields={activeFields}
397+
/>
398+
</Box>
391399
)}
392400
<Editor
393401
// @ts-ignore no types
@@ -425,8 +433,14 @@ export const ItemCreate = () => {
425433
/>
426434
</Box>
427435
<ThemeProvider theme={theme}>
428-
<Box position="sticky" top={0} alignSelf="flex-start" width="40%">
429-
<SocialMediaPreview />
436+
<Box
437+
position="sticky"
438+
top={0}
439+
alignSelf="flex-start"
440+
width="40%"
441+
maxWidth={620}
442+
>
443+
{model?.type !== "dataset" && <SocialMediaPreview />}
430444
</Box>
431445
</ThemeProvider>
432446
</Stack>

src/apps/content-editor/src/app/views/ItemEdit/Content/Content.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,13 @@ export default function Content(props) {
7373
>
7474
<Box width="100%">
7575
{props.saveClicked && props.hasErrors && (
76-
<FieldError
77-
errors={props.fieldErrors}
78-
fields={props.activeFields}
79-
/>
76+
<Box mb={3}>
77+
<FieldError
78+
ref={props.fieldErrorRef}
79+
errors={props.fieldErrors}
80+
fields={props.activeFields}
81+
/>
82+
</Box>
8083
)}
8184
<Editor
8285
// active={this.state.makeActive}

0 commit comments

Comments
 (0)