github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/pages/repositories/services/import_data.jsx (about)

     1  import {imports} from "../../../lib/api";
     2  import Row from "react-bootstrap/Row";
     3  import InputGroup from 'react-bootstrap/InputGroup';
     4  import Col from "react-bootstrap/Col";
     5  import {LinearProgress} from "@mui/material";
     6  import React, {useState} from "react";
     7  import Button from "react-bootstrap/Button";
     8  import Alert from "react-bootstrap/Alert";
     9  import Form from "react-bootstrap/Form";
    10  import {MetadataFields} from "../../../lib/components/repository/changes";
    11  
    12  const ImportPhase = {
    13      NotStarted: 0,
    14      InProgress: 1,
    15      Completed: 2,
    16      Failed: 3,
    17  }
    18  
    19  const startImport = async (setImportID, prependPath, commitMsg, sourceRef, repoId, refId, metadata = {}) => {
    20      const response = await imports.create(repoId, refId, sourceRef, prependPath, commitMsg, metadata);
    21      setImportID(response.id);
    22  }
    23  
    24  const ImportProgress = ({numObjects}) => {
    25      return (<Row>
    26          <Col>
    27              <div className='import-text'>
    28                  Imported
    29                      <span className='import-num-objects'> {numObjects} </span>
    30                  objects so far...
    31              </div>
    32              <div>
    33                  <LinearProgress color="success"/>
    34              </div>
    35              <div>
    36                  <small><abbr><br/>Please leave this tab open while import is in progress...</abbr></small>
    37              </div>
    38          </Col>
    39      </Row>);
    40  }
    41  
    42  const ImportDone = ({numObjects, branch = ''}) => {
    43      return (<Row>
    44          <Col>
    45              <div className={"mt-10 mb-2 me-2 row mt-4 import-success"}>
    46                  <p><strong>Success!</strong></p>
    47              </div>
    48              <div className='import-text'>
    49                  <strong>
    50                      <span className='import-num-objects'> {numObjects} </span>
    51                  </strong> objects imported and committed into branch
    52                  <strong>
    53                      <span className='import-num-objects'> {branch} </span>
    54                  </strong>.
    55              </div>
    56          </Col>
    57      </Row>);
    58  }
    59  const ExecuteImportButton = ({isEnabled, importPhase, importFunc, doneFunc}) => {
    60      switch (importPhase) {
    61          case ImportPhase.Completed:
    62              return <Button
    63                  variant="success"
    64                  onClick={doneFunc}
    65                  disabled={!isEnabled}>
    66                      Close
    67              </Button>
    68          case ImportPhase.Failed:
    69          case ImportPhase.NotStarted:
    70              return <Button
    71                  variant="success"
    72                  disabled={!isEnabled}
    73                  onClick={importFunc}>
    74                  Import
    75              </Button>
    76          case ImportPhase.InProgress:
    77              return <Button
    78                  variant="success"
    79                  disabled={true}>
    80                  Importing...
    81              </Button>
    82      }
    83  }
    84  
    85  const ImportForm = ({
    86                          config,
    87                          pathStyle,
    88                          sourceRef,
    89                          destRef,
    90                          path,
    91                          commitMsgRef,
    92                          repo,
    93                          branch,
    94                          updateSrcValidity,
    95                          metadataFields,
    96                          setMetadataFields,
    97                          err = null,
    98                          ...rest
    99                      }) => {
   100      const [isSourceValid, setIsSourceValid] = useState(true);
   101      const importValidityRegexStr = config.import_validity_regex;
   102      const storageNamespaceValidityRegex = RegExp(importValidityRegexStr);
   103      const updateSourceURLValidity = () => {
   104          if (!sourceRef.current.value) {
   105              updateSrcValidity(true);
   106              setIsSourceValid(true);
   107              return
   108          }
   109          const isValid = storageNamespaceValidityRegex.test(sourceRef.current.value);
   110          updateSrcValidity(isValid);
   111          setIsSourceValid(isValid);
   112      };
   113      const sourceURIExample = config ? config.blockstore_namespace_example : "s3://my-bucket/path/";
   114      return (<div {...rest}>
   115          <Alert variant="info">
   116              This feature doesn&apos;t copy data. It only creates pointers in the lakeFS metadata.<br/>
   117              lakeFS will never change objects in the import source.
   118              &#160;<a href="https://docs.lakefs.io/howto/import.html" target="_blank" rel="noreferrer">Learn more</a>
   119          </Alert>
   120          <Form>
   121              <Form.Group className='mt-4 form-group'>
   122                  <Form.Label>Import from</Form.Label>
   123                  <Form.Control type="text" name="import-from" style={pathStyle} ref={sourceRef} autoFocus
   124                                placeholder={sourceURIExample}
   125                                onChange={updateSourceURLValidity}/>
   126                  {isSourceValid === false &&
   127                      <Form.Text className="text-danger">
   128                          {`Import source should match the following pattern: "${importValidityRegexStr}"`}
   129                      </Form.Text>
   130                  }
   131                  {isSourceValid &&
   132                      <Form.Text style={{color: 'grey', justifyContent: "space-between"}}>
   133                          A URI on the object store to import from.<br/>
   134                      </Form.Text>
   135                  }
   136              </Form.Group>
   137              <Form.Group className='mt-4 form-group'>
   138                  <Form.Label>Destination</Form.Label>
   139                  <InputGroup>
   140                      <div className={"input-group-prepend"}>
   141                          <InputGroup.Text className={"text-muted"}>lakefs://{repo}/{branch}/</InputGroup.Text>
   142                      </div>
   143                      <Form.Control type="text" name="destination" ref={destRef} defaultValue={path}/>
   144                  </InputGroup>
   145                  <Form.Text style={{color: 'grey'}} md={{offset: 2, span: 10000}}>
   146                      Leave empty to import to the repository&apos;s root.
   147                  </Form.Text>
   148              </Form.Group>
   149  
   150              <Form.Group className='mt-4 form-group'>
   151                  <Form.Label>Commit message</Form.Label>
   152                  <Form.Control type="text" ref={commitMsgRef} name="commit-message"/>
   153              </Form.Group>
   154              <MetadataFields className={"mt-4"} metadataFields={metadataFields} setMetadataFields={setMetadataFields}/>
   155              {err &&
   156                  <Alert className="mt-4 small" variant={"danger"}>{err.message}</Alert>}
   157          </Form>
   158      </div>)
   159  }
   160  
   161  export {
   162      startImport, ImportProgress, ImportDone, ExecuteImportButton, ImportForm, ImportPhase,
   163  }