diff --git a/apps/builder/app/builder/features/command-panel/groups/wrap-group.test.tsx b/apps/builder/app/builder/features/command-panel/groups/wrap-group.test.tsx index ade504c49d35..8e62e639b9dd 100644 --- a/apps/builder/app/builder/features/command-panel/groups/wrap-group.test.tsx +++ b/apps/builder/app/builder/features/command-panel/groups/wrap-group.test.tsx @@ -94,20 +94,19 @@ describe("canWrapInstance for components", () => { expect(result).toBe(true); }); - test("should reject invalid wrapping (text in CodeText)", () => { + test("should allow wrapping text in a legacy CodeText", () => { $instances.set( renderData( <$.Body ws:id="body"> - <$.Box ws:id="box"> + <$.Text ws:id="text">Hello ).instances ); - selectInstance(["box", "body"]); + selectInstance(["text", "body"]); - // CodeText only accepts text content, not boxes const result = canWrapInstance( - "box", - ["box", "body"], + "text", + ["text", "body"], "body", "CodeText", undefined, @@ -115,7 +114,7 @@ describe("canWrapInstance for components", () => { $props.get(), $registeredComponentMetas.get() ); - expect(result).toBe(false); + expect(result).toBe(true); }); }); diff --git a/apps/builder/app/builder/features/publish/publish.tsx b/apps/builder/app/builder/features/publish/publish.tsx index 35712e952dc8..5751c23b82a6 100644 --- a/apps/builder/app/builder/features/publish/publish.tsx +++ b/apps/builder/app/builder/features/publish/publish.tsx @@ -103,7 +103,7 @@ import { type PrePublishAuditFinding, } from "@webstudio-is/project-build/runtime"; -const PrePublishAuditError = ({ +const PrePublishAuditMessage = ({ finding, }: { finding: PrePublishAuditFinding; @@ -164,7 +164,7 @@ const PrePublishAuditError = ({ ); }; -const getPrePublishAuditError = () => { +const getPrePublishAuditMessages = () => { const findings = runPrePublishAudit({ pages: $pages.get(), instances: $instances.get(), @@ -173,8 +173,14 @@ const getPrePublishAuditError = () => { resources: $resources.get(), metas: $registeredComponentMetas.get(), }); - const finding = findings.find(({ severity }) => severity === "error"); - return finding && ; + const getMessage = (severity: PrePublishAuditFinding["severity"]) => { + const finding = findings.find((item) => item.severity === severity); + return finding && ; + }; + return { + error: getMessage("error"), + warning: getMessage("warning"), + }; }; type ChangeProjectDomainProps = { @@ -463,6 +469,9 @@ const Publish = ({ const [publishError, setPublishError] = useState< undefined | JSX.Element | string >(); + const [publishWarning, setPublishWarning] = useState< + undefined | JSX.Element | string + >(); const [isPublishing, setIsPublishing] = useOptimistic(false); const buttonRef = useRef(null); const [hasSelectedDomains, setHasSelectedDomains] = useState(false); @@ -511,27 +520,7 @@ const Publish = ({ }; }, [project.domain]); - const handlePublish = async (formData: FormData) => { - setPublishError(undefined); - - const auditError = getPrePublishAuditError(); - if (auditError !== undefined) { - toast.error(auditError); - setPublishError(auditError); - return; - } - - // Custom domain checkboxes are disabled on free plan so they are never - // submitted — only the staging (wstd.io) domain can appear in formData. - const domains = formData - .getAll(domainToPublishName) - .map((domainEntry) => domainEntry.toString()); - - if (domains.length === 0) { - toast.error("Please select at least one domain to publish"); - return; - } - + const publish = async (domains: string[]) => { setIsPublishing(true); const publishResult = await nativeClient.domain.publish.mutate({ @@ -628,6 +617,38 @@ const Publish = ({ } }; + const handlePublish = (formData: FormData) => { + setPublishError(undefined); + setPublishWarning(undefined); + + const { error: auditError, warning: auditWarning } = + getPrePublishAuditMessages(); + if (auditError !== undefined) { + toast.error(auditError); + setPublishError(auditError); + return; + } + if (auditWarning !== undefined) { + toast.warn(auditWarning); + setPublishWarning(auditWarning); + } + + // Custom domain checkboxes are disabled on free plan so they are never + // submitted — only the staging (wstd.io) domain can appear in formData. + const domains = formData + .getAll(domainToPublishName) + .map((domainEntry) => domainEntry.toString()); + + if (domains.length === 0) { + toast.error("Please select at least one domain to publish"); + return; + } + + startTransition(async () => { + await publish(domains); + }); + }; + const hasPendingState = project.latestBuildVirtual ? getPublishStatusAndText(project.latestBuildVirtual).status === "PENDING" : false; @@ -639,6 +660,11 @@ const Publish = ({ return ( {publishError && {publishError}} + {publishWarning && ( + + {publishWarning} + + )}