Skip to content

Commit d0ea702

Browse files
committed
Disable button
1 parent 25f943a commit d0ea702

File tree

2 files changed

+69
-23
lines changed

2 files changed

+69
-23
lines changed

apps/builder/app/builder/features/topbar/domain-checkbox.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Checkbox,
1010
} from "@webstudio-is/design-system";
1111
import { $userPlanFeatures } from "~/builder/shared/nano-states";
12+
import { $project } from "~/shared/nano-states";
1213

1314
export const domainToPublishName = "domainToPublish[]";
1415

@@ -21,6 +22,11 @@ interface DomainCheckboxProps {
2122

2223
const DomainCheckbox = (props: DomainCheckboxProps) => {
2324
const hasProPlan = useStore($userPlanFeatures).hasProPlan;
25+
const project = useStore($project);
26+
27+
if (project === undefined) {
28+
return;
29+
}
2430

2531
const tooltipContentForFreeUsers = hasProPlan ? undefined : (
2632
<Flex direction="column" gap="2" css={{ maxWidth: theme.spacing[28] }}>
@@ -52,17 +58,24 @@ const DomainCheckbox = (props: DomainCheckboxProps) => {
5258
const defaultChecked = hasProPlan ? props.defaultChecked : true;
5359
const disabled = hasProPlan ? props.disabled : true;
5460

61+
const hideDomainCheckbox =
62+
project.domainsVirtual.filter(
63+
(domain) => domain.status === "ACTIVE" && domain.verified
64+
).length === 0 && hasProPlan;
65+
5566
return (
56-
<Tooltip content={tooltipContentForFreeUsers} variant="wrapped">
57-
<Checkbox
58-
disabled={disabled}
59-
key={props.buildId ?? "-"}
60-
defaultChecked={defaultChecked}
61-
css={{ pointerEvents: "all" }}
62-
name={domainToPublishName}
63-
value={props.domain}
64-
/>
65-
</Tooltip>
67+
<div style={{ display: hideDomainCheckbox ? "none" : "contents" }}>
68+
<Tooltip content={tooltipContentForFreeUsers} variant="wrapped">
69+
<Checkbox
70+
disabled={disabled}
71+
key={props.buildId ?? "-"}
72+
defaultChecked={hideDomainCheckbox || defaultChecked}
73+
css={{ pointerEvents: "all" }}
74+
name={domainToPublishName}
75+
value={props.domain}
76+
/>
77+
</Tooltip>
78+
</div>
6679
);
6780
};
6881

apps/builder/app/builder/features/topbar/publish.tsx

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
useOptimistic,
55
useTransition,
66
startTransition,
7+
useRef,
78
} from "react";
89
import { useStore } from "@nanostores/react";
910
import {
@@ -62,15 +63,12 @@ type ChangeProjectDomainProps = {
6263
refresh: () => void;
6364
};
6465

65-
// type TimeoutId = undefined | ReturnType<typeof setTimeout>;
66-
6766
const ChangeProjectDomain = ({
6867
project,
6968
refresh,
7069
}: ChangeProjectDomainProps) => {
7170
const id = useId();
7271
const publishedOrigin = useStore($publishedOrigin);
73-
const hasProPlan = useStore($userPlanFeatures).hasProPlan;
7472

7573
const [domain, setDomain] = useState(project.domain);
7674
const [error, setError] = useState<string>();
@@ -112,19 +110,15 @@ const ChangeProjectDomain = ({
112110
status: "PENDING" as const,
113111
};
114112

115-
const hideDomainCheckbox = project.domainsVirtual.length === 0 && hasProPlan;
116-
117113
return (
118114
<CollapsibleDomainSection
119115
title={new URL(publishedOrigin).host}
120116
prefix={
121-
hideDomainCheckbox ? null : (
122-
<DomainCheckbox
123-
defaultChecked={project.latestBuildVirtual?.domain === domain}
124-
buildId={project.latestBuildVirtual?.buildId}
125-
domain={domain}
126-
></DomainCheckbox>
127-
)
117+
<DomainCheckbox
118+
defaultChecked={project.latestBuildVirtual?.domain === domain}
119+
buildId={project.latestBuildVirtual?.buildId}
120+
domain={domain}
121+
/>
128122
}
129123
suffix={
130124
<Grid flow="column" align="center">
@@ -208,6 +202,39 @@ const Publish = ({
208202
}) => {
209203
const [publishError, setPublishError] = useState<string | undefined>();
210204
const [isPublishing, setIsPublishing] = useOptimistic(false);
205+
const buttonRef = useRef<HTMLButtonElement>(null);
206+
const [hasSelectedDomains, setHasSelectedDomains] = useState(false);
207+
208+
useEffect(() => {
209+
const form = buttonRef.current?.closest("form");
210+
211+
if (form == null) {
212+
return;
213+
}
214+
215+
const handleFormInput = () => {
216+
const formData = new FormData(form);
217+
const domainsSelected = formData.getAll(domainToPublishName).length;
218+
setHasSelectedDomains(domainsSelected > 0);
219+
};
220+
221+
const observer = new MutationObserver(() => {
222+
handleFormInput();
223+
});
224+
225+
observer.observe(form, {
226+
attributes: true,
227+
childList: true,
228+
subtree: true,
229+
attributeFilter: ["value", "checked"],
230+
});
231+
232+
handleFormInput();
233+
234+
return () => {
235+
observer.disconnect();
236+
};
237+
}, []);
211238

212239
const handlePublish = async (formData: FormData) => {
213240
setPublishError(undefined);
@@ -301,13 +328,19 @@ const Publish = ({
301328

302329
<Tooltip
303330
content={
304-
isPublishInProgress ? "Publish process in progress" : undefined
331+
isPublishInProgress
332+
? "Publish process in progress"
333+
: hasSelectedDomains
334+
? undefined
335+
: "Select at least one domain to publish"
305336
}
306337
>
307338
<Button
339+
ref={buttonRef}
308340
formAction={handlePublish}
309341
color="positive"
310342
state={isPublishInProgress ? "pending" : undefined}
343+
disabled={hasSelectedDomains === false}
311344
>
312345
Publish
313346
</Button>

0 commit comments

Comments
 (0)