import React from 'react'; import PropTypes from 'prop-types'; import dayjs from 'dayjs'; import { Modal, ModalBody } from 'reactstrap'; import { Utils } from '../../utils/utils'; import { gettext, siteRoot, enableRepoSnapshotLabel as showLabel } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import Loading from '../loading'; import Paginator from '../../components/paginator'; import ModalPortal from '../../components/modal-portal'; import CommitDetails from '../../components/dialog/commit-details'; import UpdateRepoCommitLabels from '../../components/dialog/edit-repo-commit-labels'; import SeahubModalHeader from '@/components/common/seahub-modal-header'; import '../../css/repo-history.css'; const propTypes = { repoID: PropTypes.string.isRequired, userPerm: PropTypes.string.isRequired, currentRepoInfo: PropTypes.object.isRequired, toggleDialog: PropTypes.func.isRequired }; class RepoHistory extends React.Component { constructor(props) { super(props); this.state = { isLoading: true, errorMsg: '', currentPage: 1, perPage: 100, hasNextPage: false, items: [] }; } componentDidMount() { this.getItems(this.state.currentPage); } getItems = (page) => { const { repoID } = this.props; seafileAPI.getRepoHistory(repoID, page, this.state.perPage).then((res) => { this.setState({ isLoading: false, currentPage: page, items: res.data.data, hasNextPage: res.data.more }); }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); }; resetPerPage = (perPage) => { this.setState({ perPage: perPage }, () => { this.getItems(1); }); }; render() { const { repoID, userPerm, currentRepoInfo, toggleDialog } = this.props; const { repo_name: repoName } = currentRepoInfo; let title = gettext('{placeholder} Modification History'); title = title.replace('{placeholder}', '' + Utils.HTMLescape(repoName) + ''); return ( {userPerm == 'rw' &&

{gettext('Tip: a snapshot will be generated after modification, which records the library state after the modification.')}

}
); } } class Content extends React.Component { constructor(props) { super(props); this.theadData = showLabel ? [ { width: '43%', text: gettext('Description') }, { width: '12%', text: gettext('Time') }, { width: '9%', text: gettext('Modifier') }, { width: '12%', text: `${gettext('Device')} / ${gettext('Version')}` }, { width: '12%', text: gettext('Labels') }, { width: '12%', text: '' } ] : [ { width: '43%', text: gettext('Description') }, { width: '15%', text: gettext('Time') }, { width: '15%', text: gettext('Modifier') }, { width: '15%', text: `${gettext('Device')} / ${gettext('Version')}` }, { width: '12%', text: '' } ]; } getPreviousPage = () => { this.props.getListByPage(this.props.currentPage - 1); }; getNextPage = () => { this.props.getListByPage(this.props.currentPage + 1); }; render() { const { isLoading, errorMsg, items, curPerPage, currentPage, hasNextPage } = this.props; if (isLoading) { return ; } if (errorMsg) { return

{errorMsg}

; } return ( {this.theadData.map((item, index) => { return ; })} {items.map((item, index) => { item.isFirstCommit = (currentPage == 1) && (index == 0); item.showDetails = hasNextPage || (index != items.length - 1); return ; })}
{item.text}
); } } Content.propTypes = { isLoading: PropTypes.bool.isRequired, errorMsg: PropTypes.string.isRequired, items: PropTypes.array.isRequired, currentPage: PropTypes.number.isRequired, hasNextPage: PropTypes.bool.isRequired, curPerPage: PropTypes.number.isRequired, resetPerPage: PropTypes.func.isRequired, getListByPage: PropTypes.func.isRequired, }; class Item extends React.Component { constructor(props) { super(props); this.state = { labels: this.props.item.tags, isIconShown: false, isCommitLabelUpdateDialogOpen: false, isCommitDetailsDialogOpen: false }; } handleMouseOver = () => { this.setState({ isIconShown: true }); }; handleMouseOut = () => { this.setState({ isIconShown: false }); }; showCommitDetails = (e) => { e.preventDefault(); this.setState({ isCommitDetailsDialogOpen: !this.state.isCommitDetailsDialogOpen }); }; toggleCommitDetailsDialog = () => { this.setState({ isCommitDetailsDialogOpen: !this.state.isCommitDetailsDialogOpen }); }; editLabel = (e) => { e.preventDefault(); this.setState({ isCommitLabelUpdateDialogOpen: !this.state.isCommitLabelUpdateDialogOpen }); }; toggleLabelEditDialog = () => { this.setState({ isCommitLabelUpdateDialogOpen: !this.state.isCommitLabelUpdateDialogOpen }); }; updateLabels = (labels) => { this.setState({ labels: labels }); }; render() { const { item, repoID, userPerm } = this.props; const { isIconShown, isCommitLabelUpdateDialogOpen, isCommitDetailsDialogOpen, labels } = this.state; let name = ''; if (item.email) { if (!item.second_parent_id) { name = {item.name}; } else { name = gettext('None'); } } else { name = gettext('Unknown'); } return ( {item.description} {item.showDetails && {gettext('Details')} } {dayjs(item.time).format('YYYY-MM-DD')} {name} {item.client_version ? `${item.device_name} / ${item.client_version}` : 'API / --'} {showLabel && {labels.map((item, index) => { return {item}; })} {userPerm == 'rw' && } } {userPerm == 'rw' && ( item.isFirstCommit ? {gettext('Current Version')} : {gettext('View Snapshot')} )} {isCommitDetailsDialogOpen && } {isCommitLabelUpdateDialogOpen && } ); } } Item.propTypes = { item: PropTypes.object.isRequired, }; RepoHistory.propTypes = propTypes; export default RepoHistory;