@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
178 lines (176 loc) • 6.39 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState } from 'react';
import RepoStatusSkeleton from './RepoStatusSkeleton';
import RepoStatusUI from './RepoStatusUI';
import CommitResolutionDialog from '../../CommitResolutionDialog/CommitResolutionDialog';
import { bulkResolveConflict, cancelFailedPull, resolveConflict } from '../../../services/repositories';
import { useDispatch } from 'react-redux';
import { showSystemNotification } from '../../../state/actions/system';
import { showErrorDialog } from '../../../state/reducers/dialogs/error';
import { FormattedMessage, useIntl } from 'react-intl';
import ConflictedPathDiffDialog from '../../ConflictedPathDiffDialog';
import { useActiveSiteId } from '../../../hooks/useActiveSiteId';
import { messages } from './translations';
import { ConfirmDialog } from '../../ConfirmDialog';
export function RepoStatus(props) {
const {
status,
openConfirmDialog = false,
onCommitSuccess: onCommitSuccessProp,
onRevertSuccess,
onFailedPullCancelled,
onConflictResolved,
onConfirmDialogOk
} = props;
const siteId = useActiveSiteId();
const [openCommitResolutionDialog, setOpenCommitResolutionDialog] = useState(false);
const [openRemoteRepositoriesDiffDialog, setOpenRemoteRepositoriesDiffDialog] = useState(false);
const [diffPath, setDiffPath] = useState(null);
const dispatch = useDispatch();
const [fetching, setFetching] = useState(false);
const { formatMessage } = useIntl();
if (!props.status || fetching) {
return React.createElement(RepoStatusSkeleton, null);
}
const onRevertPull = () => {
setFetching(true);
cancelFailedPull(siteId).subscribe({
next(status) {
onFailedPullCancelled?.(status);
setFetching(false);
onRevertSuccess?.();
dispatch(
showSystemNotification({
message: formatMessage(messages.revertPullSuccessMessage)
})
);
},
error({ response }) {
dispatch(showErrorDialog({ error: response }));
}
});
};
const onCommitSuccess = (status) => {
onCommitSuccessProp?.(status);
setFetching(false);
setOpenCommitResolutionDialog(false);
dispatch(
showSystemNotification({
message: formatMessage(messages.commitSuccessMessage)
})
);
};
const onResolveConflictsSuccess = (status) => {
onConflictResolved?.(status);
setFetching(false);
setOpenRemoteRepositoriesDiffDialog(false);
};
const onResolveConflictsError = (response) => {
dispatch(showErrorDialog({ error: response }));
setFetching(false);
};
const onResolveConflict = (resolution, path) => {
setFetching(true);
resolveConflict(siteId, path, resolution).subscribe({
next(status) {
onResolveConflictsSuccess(status);
},
error({ response }) {
onResolveConflictsError(response);
}
});
};
const onBulkResolveConflict = (resolution) => {
setFetching(true);
bulkResolveConflict(siteId, status.conflicting, resolution).subscribe({
next(status) {
onResolveConflictsSuccess(status);
},
error({ response }) {
onResolveConflictsError(response);
}
});
};
const onCommitError = (response) => {
dispatch(showErrorDialog({ error: response }));
};
const openDiffDialog = (path) => {
setDiffPath(path);
setOpenRemoteRepositoriesDiffDialog(true);
};
const onBulkAction = (e, action) => {
switch (action) {
case 'acceptAll':
onBulkResolveConflict('theirs');
break;
case 'keepAll':
onBulkResolveConflict('ours');
break;
case 'revertAll':
onRevertPull();
break;
}
};
return React.createElement(
React.Fragment,
null,
React.createElement(RepoStatusUI, {
status: status,
onCommitClick: () => setOpenCommitResolutionDialog(true),
onResolveConflict: onResolveConflict,
onDiffClick: openDiffDialog,
onBulkAction: onBulkAction
}),
React.createElement(CommitResolutionDialog, {
open: openCommitResolutionDialog,
onClose: () => setOpenCommitResolutionDialog(false),
onCommitRequestSent: () => setFetching(true),
onCommitSuccess: onCommitSuccess,
onCommitError: onCommitError
}),
React.createElement(ConflictedPathDiffDialog, {
open: openRemoteRepositoriesDiffDialog,
path: diffPath,
onResolveConflict: onResolveConflict,
onClose: () => setOpenRemoteRepositoriesDiffDialog(false)
}),
React.createElement(ConfirmDialog, {
open: openConfirmDialog,
body: React.createElement(FormattedMessage, { defaultMessage: 'A resolution is required before continuing' }),
okButtonText: React.createElement(FormattedMessage, { defaultMessage: 'Stay and continue resolution' }),
cancelButtonText: React.createElement(FormattedMessage, { defaultMessage: 'Revert all and close' }),
onOk: onConfirmDialogOk,
onCancel: () => onRevertPull()
})
);
}
export default RepoStatus;