text: import React, { Component, Fragment } from 'react';
  import { Link } from '@reach/router';
  import moment from 'moment';
  import { Utils } from '../../../utils/utils';
  import { seafileAPI } from '../../../utils/seafile-api';
  import { isPro, siteRoot, gettext } from '../../../utils/constants';
  import toaster from '../../../components/toast';
  import EmptyTip from '../../../components/empty-tip';
  import Loading from '../../../components/loading';
  import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog';
  import TransferDialog from '../../../components/dialog/transfer-dialog';
  import OpMenu from '../../../components/dialog/op-menu';
  import MainPanelTopbar from '../main-panel-topbar';
  import Nav from './user-nav';
  
  const { enableSysAdminViewRepo } = window.sysadmin.pageOptions;
  
  class Content extends Component {
  
    constructor(props) {
      super(props);
      this.state = {
        isItemFreezed: false
      };
    }
  
    onFreezedItem = () => {
      this.setState({isItemFreezed: true});
    }
  
    onUnfreezedItem = () => {
      this.setState({isItemFreezed: false});
    }
  
    render() {
      const { loading, errorMsg, items } = this.props;
      if (loading) {
        return <Loading />;
      } else if (errorMsg) {
        return <p className="error text-center mt-4">{errorMsg}</p>;
      } else {
        const emptyTip = (
          <EmptyTip>
            <h2>{gettext('No libraries')}</h2>
          </EmptyTip>
        );
        const table = (
          <Fragment>
            <table>
              <thead>
                <tr>
                  <th width="5%"></th>
                  <th width="35%">{gettext('Name')}</th>
                  <th width="30%">{gettext('Size')}</th>
                  <th width="25%">{gettext('Last Update')}</th>
                  <th width="5%">{/* Operations */}</th>
                </tr>
              </thead>
              <tbody>
                {items.map((item, index) => {
                  return (<Item
                    key={index}
                    item={item}
                    isItemFreezed={this.state.isItemFreezed}
                    onFreezedItem={this.onFreezedItem}
                    onUnfreezedItem={this.onUnfreezedItem}
                    deleteRepo={this.props.deleteRepo}
                    transferRepo={this.props.transferRepo}
                  />);
                })}
              </tbody>
            </table>
          </Fragment>
        );
        return items.length ? table : emptyTip;
      }
    }
  }
  
  class Item extends Component {
  
    constructor(props) {
      super(props);
      this.state = {
        isOpIconShown: false,
        highlight: false,
        isDeleteDialogOpen: false,
        isTransferDialogOpen: false
      };
    }
  
    handleMouseEnter = () => {
      if (!this.props.isItemFreezed) {
        this.setState({
          isOpIconShown: true,
          highlight: true
        });
      }
    }
  
    handleMouseLeave = () => {
      if (!this.props.isItemFreezed) {
        this.setState({
          isOpIconShown: false,
          highlight: false
        });
      }
    }
  
    onUnfreezedItem = () => {
      this.setState({
        highlight: false,
        isOpIconShow: false
      });
      this.props.onUnfreezedItem();
    }
  
    toggleDeleteDialog = () => {
      this.setState({isDeleteDialogOpen: !this.state.isDeleteDialogOpen});
    }
  
    deleteRepo = () => {
      this.props.deleteRepo(this.props.item.id);
    }
  
    toggleTransferDialog = () => {
      this.setState({isTransferDialogOpen: !this.state.isTransferDialogOpen});
    }
  
    transferRepo = (owner) => {
      this.props.transferRepo(this.props.item.id, owner.email);
      this.toggleTransferDialog();
    }
  
    renderRepoName = () => {
      const { item } = this.props;
      const repo = item;
      if (repo.name) {
        if (isPro && enableSysAdminViewRepo && !repo.encrypted) {
          return <Link to={`${siteRoot}sys/libraries/${repo.id}/`}>{repo.name}</Link>;
        } else {
          return repo.name;
        }
      } else {
        return gettext('Broken ({repo_id_placeholder})')
          .replace('{repo_id_placeholder}', repo.id);
      }
    }
  
    translateOperations = (item) => {
      let translateResult = '';
      switch (item) {
        case 'Delete':
          translateResult = gettext('Delete');
          break;
        case 'Transfer':
          translateResult = gettext('Transfer');
          break;
      }
  
      return translateResult;
    }
  
    onMenuItemClick = (operation) => {
      switch(operation) {
        case 'Delete':
          this.toggleDeleteDialog();
          break;
        case 'Transfer':
          this.toggleTransferDialog();
          break;
      }
    }
  
    render() {
      const { item } = this.props;
      const { isOpIconShown, isDeleteDialogOpen, isTransferDialogOpen } = this.state;
  
      const iconUrl = Utils.getLibIconUrl(item);
      const iconTitle = Utils.getLibIconTitle(item);
  
      const itemName = '<span class="op-target">' + Utils.HTMLescape(item.name) + '</span>';
      const deleteDialogMsg = gettext('Are you sure you want to delete {placeholder} ?').replace('{placeholder}', itemName);
  
      return (
        <Fragment>
          <tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
            <td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
            <td>{this.renderRepoName()}</td>
            <td>{Utils.bytesToSize(item.size)}</td>
            <td>{moment(item.last_modified).fromNow()}</td>
            <td>
              {isOpIconShown &&
              <OpMenu
                operations={['Delete', 'Transfer']}
                translateOperations={this.translateOperations}
                onMenuItemClick={this.onMenuItemClick}
                onFreezedItem={this.props.onFreezedItem}
                onUnfreezedItem={this.onUnfreezedItem}
              />
              }
            </td>
          </tr>
          {isDeleteDialogOpen &&
            <CommonOperationConfirmationDialog
              title={gettext('Delete Library')}
              message={deleteDialogMsg}
              executeOperation={this.deleteRepo}
              confirmBtnText={gettext('Delete')}
              toggleDialog={this.toggleDeleteDialog}
            />
          }
          {isTransferDialogOpen &&
          <TransferDialog
            itemName={item.name}
            submit={this.transferRepo}
            canTransferToDept={false}
            toggleDialog={this.toggleTransferDialog}
          />
          }
        </Fragment>
      );
    }
  }
  
  class Repos extends Component {
  
    constructor(props) {
      super(props);
      this.state = {
        loading: true,
        errorMsg: '',
        userInfo: {},
        repoList: []
      };
    }
  
    componentDidMount () {
      seafileAPI.sysAdminGetUser(this.props.email).then((res) => {
        this.setState({
          userInfo: res.data
        });
      });
      seafileAPI.sysAdminListReposByOwner(this.props.email).then(res => {
        this.setState({
          loading: false,
          repoList: res.data.repos
        });
      }).catch((error) => {
        this.setState({
          loading: false,
          errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
        });
      });
    }
  
    deleteRepo = (repoID) => {
      seafileAPI.sysAdminDeleteRepo(repoID).then(res => {
        let newRepoList = this.state.repoList.filter(item => {
          return item.id != repoID;
        });
        this.setState({repoList: newRepoList});
        toaster.success(gettext('Successfully deleted 1 item.'));
      }).catch((error) => {
        let errMessage = Utils.getErrorMsg(error);
        toaster.danger(errMessage);
      });
    }
  
    transferRepo = (repoID, email) => {
      seafileAPI.sysAdminTransferRepo(repoID, email).then((res) => {
        let newRepoList = this.state.repoList.filter(item => {
          return item.id != repoID;
        });
        this.setState({repoList: newRepoList});
        let message = gettext('Successfully transferred the library.');
        toaster.success(message);
      }).catch(error => {
        let errMessage = Utils.getErrorMsg(error);
        toaster.danger(errMessage);
      });
    }
  
    render() {
      return (
        <Fragment>
          <MainPanelTopbar />
          <div className="main-panel-center flex-row">
            <div className="cur-view-container">
              <Nav currentItem="owned-repos" email={this.props.email} userName={this.state.userInfo.name} />
              <div className="cur-view-content">
                <Content
                  loading={this.state.loading}
                  errorMsg={this.state.errorMsg}
                  items={this.state.repoList}
                  deleteRepo={this.deleteRepo}
                  transferRepo={this.transferRepo}
                />
              </div>
            </div>
          </div>
        </Fragment>
      );
    }
  }
  
  export default Repos;
  