github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/ShareSnapshotModal.tsx (about) 1 import { CameraAlt } from "@material-ui/icons" 2 import { saveAs } from "file-saver" 3 import moment from "moment" 4 import React from "react" 5 import styled from "styled-components" 6 import { linkToTiltDocs, TiltDocsPage } from "./constants" 7 import FloatDialog from "./FloatDialog" 8 import { InstrumentedButton } from "./instrumentedComponents" 9 import "./ShareSnapshotModal.scss" 10 import { Color, Font, FontSize, SizeUnit } from "./style-helpers" 11 12 type ShareSnapshotModalProps = { 13 getSnapshot: () => Proto.webviewSnapshot 14 handleClose: () => void 15 isOpen: boolean 16 dialogAnchor: HTMLElement | null 17 } 18 19 // TODO (lizz): When offline snapshots are the default method for snapshots 20 // generation, cloud snapshot code can be refactored and this component renamed 21 export default function ShareSnapshotModal(props: ShareSnapshotModalProps) { 22 return ( 23 <LocalSnapshotDialog 24 dialogAnchor={props.dialogAnchor} 25 handleClose={props.handleClose} 26 isOpen={props.isOpen} 27 getSnapshot={props.getSnapshot} 28 /> 29 ) 30 } 31 32 type DownloadSnapshotModalProps = { 33 handleClose: () => void 34 getSnapshot: () => Proto.webviewSnapshot 35 isOpen: boolean 36 dialogAnchor: HTMLElement | null 37 } 38 39 const SaveSnapshotButton = styled(InstrumentedButton)` 40 background-color: ${Color.gray70}; 41 border: 1px solid ${Color.gray10}; 42 color: ${Color.gray10}; 43 display: flex; 44 font-family: ${Font.monospace}; 45 font-size: ${FontSize.default}; 46 margin: ${SizeUnit(0.75)} 0; 47 text-transform: unset; 48 49 &:focus, 50 &:active { 51 background-color: rgba(0, 0, 0, 0.04); 52 } 53 ` 54 55 const CodeSnippet = styled.code` 56 background-color: ${Color.offWhite}; 57 padding: 0 5px; 58 white-space: nowrap; 59 ` 60 61 export function formatTimestampForFilename(date: moment.Moment) { 62 return date.format("YYYY-MM-DD_HHmmss") 63 } 64 65 function downloadSnapshot(snapshot: Proto.webviewSnapshot) { 66 const timestamp = snapshot.createdAt ? moment(snapshot.createdAt) : moment() 67 const data = new Blob([JSON.stringify(snapshot)], { 68 type: "application/json", 69 }) 70 71 saveAs(data, `tilt-snapshot_${formatTimestampForFilename(timestamp)}.json`) 72 } 73 74 export function LocalSnapshotDialog(props: DownloadSnapshotModalProps) { 75 const { handleClose, getSnapshot, isOpen, dialogAnchor } = props 76 return ( 77 <FloatDialog 78 id="download-snapshot" 79 title="Create a Snapshot" 80 open={isOpen} 81 onClose={handleClose} 82 anchorEl={dialogAnchor} 83 > 84 <p> 85 Snapshots let you save and share a browsable view of your Tilt session. 86 You can download a snapshot here or with:{" "} 87 <CodeSnippet>tilt snapshot create</CodeSnippet>. 88 </p> 89 90 <SaveSnapshotButton 91 analyticsName="ui.web.downloadSnapshot" 92 onClick={() => downloadSnapshot(getSnapshot())} 93 startIcon={<CameraAlt />} 94 > 95 Save Snapshot 96 </SaveSnapshotButton> 97 <p> 98 View your saved snapshot with:{" "} 99 <CodeSnippet>tilt snapshot view {"<filename>"}</CodeSnippet>. 100 </p> 101 <p> 102 See the{" "} 103 <a 104 href={linkToTiltDocs(TiltDocsPage.Snapshots)} 105 target="_blank" 106 rel="noopener noreferrer" 107 > 108 snapshot docs 109 </a>{" "} 110 for more info. 111 </p> 112 </FloatDialog> 113 ) 114 }