@@ -21,6 +21,7 @@ import {
2121} from "@webstudio-is/icons" ;
2222import { CollapsibleDomainSection } from "./collapsible-domain-section" ;
2323import {
24+ Fragment ,
2425 startTransition ,
2526 useEffect ,
2627 useOptimistic ,
@@ -34,12 +35,13 @@ import { useStore } from "@nanostores/react";
3435import { $publisherHost } from "~/shared/nano-states" ;
3536import { extractCname } from "./cname" ;
3637import { useEffectEvent } from "~/shared/hook-utils/effect-event" ;
37- import DomainCheckbox from "./domain-checkbox" ;
38+ import { DomainCheckbox } from "./domain-checkbox" ;
3839import { CopyToClipboard } from "~/builder/shared/copy-to-clipboard" ;
3940import { RelativeTime } from "~/builder/shared/relative-time" ;
4041
4142export type Domain = Project [ "domainsVirtual" ] [ number ] ;
42- type DomainStatus = Project [ "domainsVirtual" ] [ number ] [ "status" ] ;
43+
44+ type DomainStatus = Domain [ "status" ] ;
4345
4446const InputEllipsis = styled ( InputField , {
4547 "&>input" : {
@@ -164,23 +166,28 @@ const StatusIcon = (props: { projectDomain: Domain; isLoading: boolean }) => {
164166 ) ;
165167} ;
166168
167- const DomainItem = ( props : {
169+ const DomainItem = ( {
170+ initiallyOpen,
171+ projectDomain,
172+ project,
173+ refresh,
174+ } : {
168175 initiallyOpen : boolean ;
169176 projectDomain : Domain ;
170- refresh : ( ) => Promise < void > ;
171177 project : Project ;
178+ refresh : ( ) => Promise < void > ;
172179} ) => {
173180 const timeSinceLastUpdateMs =
174- Date . now ( ) - new Date ( props . projectDomain . updatedAt ) . getTime ( ) ;
181+ Date . now ( ) - new Date ( projectDomain . updatedAt ) . getTime ( ) ;
175182
176183 const DAY_IN_MS = 24 * 60 * 60 * 1000 ;
177184
178- const status = props . projectDomain . verified
179- ? ( `VERIFIED_${ props . projectDomain . status } ` as `VERIFIED_${DomainStatus } `)
185+ const status = projectDomain . verified
186+ ? ( `VERIFIED_${ projectDomain . status } ` as `VERIFIED_${DomainStatus } `)
180187 : `UNVERIFIED` ;
181188
182189 const [ isStatusLoading , setIsStatusLoading ] = useState (
183- props . initiallyOpen ||
190+ initiallyOpen ||
184191 status === "VERIFIED_ACTIVE" ||
185192 timeSinceLastUpdateMs > DAY_IN_MS
186193 ? false
@@ -195,16 +202,16 @@ const DomainItem = (props: {
195202 const handleRemoveDomain = async ( ) => {
196203 setIsRemoveInProgress ( true ) ;
197204 const result = await nativeClient . domain . remove . mutate ( {
198- projectId : props . projectDomain . projectId ,
199- domainId : props . projectDomain . domainId ,
205+ projectId : projectDomain . projectId ,
206+ domainId : projectDomain . domainId ,
200207 } ) ;
201208
202209 if ( result . success === false ) {
203210 toast . error ( result . error ) ;
204211 return ;
205212 }
206213
207- await props . refresh ( ) ;
214+ await refresh ( ) ;
208215 } ;
209216
210217 const [ verifyError , setVerifyError ] = useState < string | undefined > ( undefined ) ;
@@ -214,16 +221,16 @@ const DomainItem = (props: {
214221 setIsCheckStateInProgress ( true ) ;
215222
216223 const verifyResult = await nativeClient . domain . verify . mutate ( {
217- projectId : props . projectDomain . projectId ,
218- domainId : props . projectDomain . domainId ,
224+ projectId : projectDomain . projectId ,
225+ domainId : projectDomain . domainId ,
219226 } ) ;
220227
221228 if ( verifyResult . success === false ) {
222229 setVerifyError ( verifyResult . error ) ;
223230 return ;
224231 }
225232
226- await props . refresh ( ) ;
233+ await refresh ( ) ;
227234 } ) ;
228235
229236 const [ updateStatusError , setUpdateStatusError ] = useState <
@@ -235,8 +242,8 @@ const DomainItem = (props: {
235242 setIsCheckStateInProgress ( true ) ;
236243
237244 const updateStatusResult = await nativeClient . domain . updateStatus . mutate ( {
238- projectId : props . projectDomain . projectId ,
239- domain : props . projectDomain . domain ,
245+ projectId : projectDomain . projectId ,
246+ domain : projectDomain . domain ,
240247 } ) ;
241248
242249 setIsStatusLoading ( false ) ;
@@ -246,7 +253,7 @@ const DomainItem = (props: {
246253 return ;
247254 }
248255
249- await props . refresh ( ) ;
256+ await refresh ( ) ;
250257 } ) ;
251258
252259 const onceRef = useRef ( false ) ;
@@ -272,67 +279,60 @@ const DomainItem = (props: {
272279 } ) ;
273280 } , [ status , handleVerify , handleUpdateStatus , isStatusLoading ] ) ;
274281
275- const publisherHost = useStore ( $publisherHost ) ;
276- const cnameEntryName = extractCname ( props . projectDomain . domain ) ;
277- const cnameEntryValue = `${ props . projectDomain . cname } .customers.${ publisherHost } ` ;
278-
279- const txtEntryName =
280- cnameEntryName === "@"
281- ? "_webstudio_is"
282- : `_webstudio_is.${ cnameEntryName } ` ;
283-
284- const domainStatus = getStatus ( props . projectDomain ) ;
285-
286- const cnameRecord = {
287- type : "CNAME" ,
288- host : cnameEntryName ,
289- value : cnameEntryValue ,
290- ttl : 300 ,
291- } as const ;
292-
293- const txtRecord = {
294- type : "TXT" ,
295- host : txtEntryName ,
296- value : props . projectDomain . expectedTxtRecord ,
297- ttl : 300 ,
298- } as const ;
299-
300- const dnsRecords = [ cnameRecord , txtRecord ] ;
282+ const domainStatus = getStatus ( projectDomain ) ;
301283
302284 const { isVerifiedActive, text } = getStatusText ( {
303- projectDomain : props . projectDomain ,
285+ projectDomain,
304286 isLoading : false ,
305287 } ) ;
306288
289+ const publisherHost = useStore ( $publisherHost ) ;
290+ const cname = extractCname ( projectDomain . domain ) ;
291+ const dnsRecords = [
292+ {
293+ type : "CNAME" ,
294+ host : cname ,
295+ value : `${ projectDomain . cname } .customers.${ publisherHost } ` ,
296+ ttl : 300 ,
297+ } as const ,
298+ {
299+ type : "TXT" ,
300+ host : cname === "@" ? "_webstudio_is" : `_webstudio_is.${ cname } ` ,
301+ value : projectDomain . expectedTxtRecord ,
302+ ttl : 300 ,
303+ } as const ,
304+ ] ;
305+
307306 return (
308307 < CollapsibleDomainSection
309308 prefix = {
310309 < DomainCheckbox
311- buildId = { props . projectDomain . latestBuildVirtual ?. buildId }
310+ buildId = { projectDomain . latestBuildVirtual ?. buildId }
312311 defaultChecked = {
313- props . projectDomain . latestBuildVirtual ?. buildId != null &&
314- props . projectDomain . latestBuildVirtual ?. buildId ===
315- props . project . latestBuildVirtual ?. buildId
312+ projectDomain . latestBuildVirtual ?. buildId != null &&
313+ projectDomain . latestBuildVirtual ?. buildId ===
314+ project . latestBuildVirtual ?. buildId
316315 }
317- domain = { props . projectDomain . domain }
316+ domain = { projectDomain . domain }
318317 disabled = { domainStatus !== "VERIFIED_ACTIVE" }
319318 />
320319 }
321- initiallyOpen = { props . initiallyOpen }
322- title = { props . projectDomain . domain }
320+ initiallyOpen = { initiallyOpen }
321+ title = { projectDomain . domain }
323322 suffix = {
324323 < Grid flow = "column" >
325324 < StatusIcon
326325 isLoading = { isStatusLoading }
327- projectDomain = { props . projectDomain }
326+ projectDomain = { projectDomain }
328327 />
329328
330- < Tooltip content = { `Proceed to ${ props . projectDomain . domain } ` } >
329+ < Tooltip content = { `Proceed to ${ projectDomain . domain } ` } >
331330 < IconButton
331+ type = "button"
332332 tabIndex = { - 1 }
333333 disabled = { status !== "VERIFIED_ACTIVE" }
334334 onClick = { ( event ) => {
335- const url = new URL ( `https://${ props . projectDomain . domain } ` ) ;
335+ const url = new URL ( `https://${ projectDomain . domain } ` ) ;
336336 window . open ( url . href , "_blank" ) ;
337337 event . preventDefault ( ) ;
338338 } }
@@ -423,67 +423,45 @@ const DomainItem = (props: {
423423
424424 < Grid
425425 gap = { 2 }
426- css = { {
427- gridTemplateColumns : `${ theme . spacing [ 18 ] } 1fr 1fr` ,
428- } }
426+ css = { { gridTemplateColumns : `${ theme . spacing [ 18 ] } 1fr 1fr` } }
429427 >
430- < Text color = "subtle" variant = { "titles" } >
428+ < Text color = "subtle" variant = "titles" >
431429 TYPE
432430 </ Text >
433- < Text color = "subtle" variant = { "titles" } >
431+ < Text color = "subtle" variant = "titles" >
434432 NAME
435433 </ Text >
436- < Text color = "subtle" variant = { "titles" } >
434+ < Text color = "subtle" variant = "titles" >
437435 VALUE
438436 </ Text >
439437
440- < InputEllipsis readOnly value = "CNAME" />
441- < InputEllipsis
442- readOnly
443- value = { cnameRecord . host }
444- suffix = {
445- < CopyToClipboard text = { cnameRecord . host } >
446- < NestedInputButton type = "button" >
447- < CopyIcon />
448- </ NestedInputButton >
449- </ CopyToClipboard >
450- }
451- />
452- < InputEllipsis
453- readOnly
454- value = { cnameRecord . value }
455- suffix = {
456- < CopyToClipboard text = { cnameRecord . value } >
457- < NestedInputButton type = "button" >
458- < CopyIcon />
459- </ NestedInputButton >
460- </ CopyToClipboard >
461- }
462- />
463-
464- < InputEllipsis readOnly value = "TXT" />
465- < InputEllipsis
466- readOnly
467- value = { txtRecord . host }
468- suffix = {
469- < CopyToClipboard text = { txtRecord . host } >
470- < NestedInputButton type = "button" >
471- < CopyIcon />
472- </ NestedInputButton >
473- </ CopyToClipboard >
474- }
475- />
476- < InputEllipsis
477- readOnly
478- value = { txtRecord . value }
479- suffix = {
480- < CopyToClipboard text = { txtRecord . value } >
481- < NestedInputButton type = "button" >
482- < CopyIcon />
483- </ NestedInputButton >
484- </ CopyToClipboard >
485- }
486- />
438+ { dnsRecords . map ( ( record , index ) => (
439+ < Fragment key = { index } >
440+ < InputEllipsis readOnly value = { record . type } />
441+ < InputEllipsis
442+ readOnly
443+ value = { record . host }
444+ suffix = {
445+ < CopyToClipboard text = { record . host } >
446+ < NestedInputButton type = "button" >
447+ < CopyIcon />
448+ </ NestedInputButton >
449+ </ CopyToClipboard >
450+ }
451+ />
452+ < InputEllipsis
453+ readOnly
454+ value = { record . value }
455+ suffix = {
456+ < CopyToClipboard text = { record . value } >
457+ < NestedInputButton type = "button" >
458+ < CopyIcon />
459+ </ NestedInputButton >
460+ </ CopyToClipboard >
461+ }
462+ />
463+ </ Fragment >
464+ ) ) }
487465 </ Grid >
488466
489467 < Grid
@@ -500,7 +478,7 @@ const DomainItem = (props: {
500478
501479 < Entri
502480 dnsRecords = { dnsRecords }
503- domain = { props . projectDomain . domain }
481+ domain = { projectDomain . domain }
504482 onClose = { ( ) => {
505483 // Sometimes Entri modal dialog hangs even if it's successful,
506484 // until they fix that, we'll just refresh the status here on every onClose event
0 commit comments