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  }