Open Authoring bugfixes and pagination improvements (#2523)
* Fix handling of displayURLs which are strings * Add fromFetchArguments to unsentRequest * Add parseLinkHeader to backendUtil * Handle paginated endpoints in GitHub API * Rename fork workflow to Open Authoring across the whole repo * Fixes for bugs in GitHub API introduced by Open Authoring changes * Fix getDeployPreview * Fix incorrect auth header formatting GitHub implementation cf. https://github.com/netlify/netlify-cms/pull/2456#discussion_r309633387 * Remove unused and broken method from GitHub API cf. https://github.com/netlify/netlify-cms/pull/2456#discussion_r308687145 * Fix editorialWorkflowGit method in GitHub API * Request published entry content from origin repo * Better error when deleting a published post in Open Authoring * Rename to Open Authoring in fork request message Also adds a note to the fork request message that an existing fork of the same repo will be used automatically. * fix linting
This commit is contained in:
committed by
Shawn Erquhart
parent
66da66affd
commit
34e1f09105
@ -7,7 +7,7 @@ export const AUTH_REQUEST = 'AUTH_REQUEST';
|
||||
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
|
||||
export const AUTH_FAILURE = 'AUTH_FAILURE';
|
||||
export const AUTH_REQUEST_DONE = 'AUTH_REQUEST_DONE';
|
||||
export const USE_FORK_WORKFLOW = 'USE_FORK_WORKFLOW';
|
||||
export const USE_OPEN_AUTHORING = 'USE_OPEN_AUTHORING';
|
||||
export const LOGOUT = 'LOGOUT';
|
||||
|
||||
export function authenticating() {
|
||||
@ -37,9 +37,9 @@ export function doneAuthenticating() {
|
||||
};
|
||||
}
|
||||
|
||||
export function useForkWorkflow() {
|
||||
export function useOpenAuthoring() {
|
||||
return {
|
||||
type: USE_FORK_WORKFLOW,
|
||||
type: USE_OPEN_AUTHORING,
|
||||
};
|
||||
}
|
||||
|
||||
@ -59,8 +59,8 @@ export function authenticateUser() {
|
||||
.currentUser()
|
||||
.then(user => {
|
||||
if (user) {
|
||||
if (user.useForkWorkflow) {
|
||||
dispatch(useForkWorkflow());
|
||||
if (user.useOpenAuthoring) {
|
||||
dispatch(useOpenAuthoring());
|
||||
}
|
||||
dispatch(authenticate(user));
|
||||
} else {
|
||||
@ -83,8 +83,8 @@ export function loginUser(credentials) {
|
||||
return backend
|
||||
.authenticate(credentials)
|
||||
.then(user => {
|
||||
if (user.useForkWorkflow) {
|
||||
dispatch(useForkWorkflow());
|
||||
if (user.useOpenAuthoring) {
|
||||
dispatch(useOpenAuthoring());
|
||||
}
|
||||
dispatch(authenticate(user));
|
||||
})
|
||||
|
@ -250,9 +250,10 @@ export function loadMediaDisplayURL(file) {
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (typeof url === 'string' || typeof displayURL === 'string') {
|
||||
if (typeof displayURL === 'string') {
|
||||
dispatch(mediaDisplayURLRequest(id));
|
||||
dispatch(mediaDisplayURLSuccess(id, displayURL));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const backend = currentBackend(state.config);
|
||||
|
@ -61,7 +61,7 @@ class Editor extends React.Component {
|
||||
newEntry: PropTypes.bool.isRequired,
|
||||
displayUrl: PropTypes.string,
|
||||
hasWorkflow: PropTypes.bool,
|
||||
useForkWorkflow: PropTypes.bool,
|
||||
useOpenAuthoring: PropTypes.bool,
|
||||
unpublishedEntry: PropTypes.bool,
|
||||
isModification: PropTypes.bool,
|
||||
collectionEntriesLoaded: PropTypes.bool,
|
||||
@ -351,7 +351,7 @@ class Editor extends React.Component {
|
||||
hasChanged,
|
||||
displayUrl,
|
||||
hasWorkflow,
|
||||
useForkWorkflow,
|
||||
useOpenAuthoring,
|
||||
unpublishedEntry,
|
||||
newEntry,
|
||||
isModification,
|
||||
@ -399,7 +399,7 @@ class Editor extends React.Component {
|
||||
hasChanged={hasChanged}
|
||||
displayUrl={displayUrl}
|
||||
hasWorkflow={hasWorkflow}
|
||||
useForkWorkflow={useForkWorkflow}
|
||||
useOpenAuthoring={useOpenAuthoring}
|
||||
hasUnpublishedChanges={unpublishedEntry}
|
||||
isNewEntry={newEntry}
|
||||
isModification={isModification}
|
||||
@ -425,7 +425,7 @@ function mapStateToProps(state, ownProps) {
|
||||
const hasChanged = entryDraft.get('hasChanged');
|
||||
const displayUrl = config.get('display_url');
|
||||
const hasWorkflow = config.get('publish_mode') === EDITORIAL_WORKFLOW;
|
||||
const useForkWorkflow = globalUI.get('useForkWorkflow', false);
|
||||
const useOpenAuthoring = globalUI.get('useOpenAuthoring', false);
|
||||
const isModification = entryDraft.getIn(['entry', 'isModification']);
|
||||
const collectionEntriesLoaded = !!entries.getIn(['pages', collectionName]);
|
||||
const unpublishedEntry = selectUnpublishedEntry(state, collectionName, slug);
|
||||
@ -445,7 +445,7 @@ function mapStateToProps(state, ownProps) {
|
||||
hasChanged,
|
||||
displayUrl,
|
||||
hasWorkflow,
|
||||
useForkWorkflow,
|
||||
useOpenAuthoring,
|
||||
isModification,
|
||||
collectionEntriesLoaded,
|
||||
currentStatus,
|
||||
|
@ -166,7 +166,7 @@ class EditorInterface extends Component {
|
||||
hasChanged,
|
||||
displayUrl,
|
||||
hasWorkflow,
|
||||
useForkWorkflow,
|
||||
useOpenAuthoring,
|
||||
hasUnpublishedChanges,
|
||||
isNewEntry,
|
||||
isModification,
|
||||
@ -241,7 +241,7 @@ class EditorInterface extends Component {
|
||||
displayUrl={displayUrl}
|
||||
collection={collection}
|
||||
hasWorkflow={hasWorkflow}
|
||||
useForkWorkflow={useForkWorkflow}
|
||||
useOpenAuthoring={useOpenAuthoring}
|
||||
hasUnpublishedChanges={hasUnpublishedChanges}
|
||||
isNewEntry={isNewEntry}
|
||||
isModification={isModification}
|
||||
@ -295,7 +295,7 @@ EditorInterface.propTypes = {
|
||||
hasChanged: PropTypes.bool,
|
||||
displayUrl: PropTypes.string,
|
||||
hasWorkflow: PropTypes.bool,
|
||||
useForkWorkflow: PropTypes.bool,
|
||||
useOpenAuthoring: PropTypes.bool,
|
||||
hasUnpublishedChanges: PropTypes.bool,
|
||||
isNewEntry: PropTypes.bool,
|
||||
isModification: PropTypes.bool,
|
||||
|
@ -218,7 +218,7 @@ class EditorToolbar extends React.Component {
|
||||
displayUrl: PropTypes.string,
|
||||
collection: ImmutablePropTypes.map.isRequired,
|
||||
hasWorkflow: PropTypes.bool,
|
||||
useForkWorkflow: PropTypes.bool,
|
||||
useOpenAuthoring: PropTypes.bool,
|
||||
hasUnpublishedChanges: PropTypes.bool,
|
||||
isNewEntry: PropTypes.bool,
|
||||
isModification: PropTypes.bool,
|
||||
@ -380,7 +380,7 @@ class EditorToolbar extends React.Component {
|
||||
onPublishAndNew,
|
||||
currentStatus,
|
||||
isNewEntry,
|
||||
useForkWorkflow,
|
||||
useOpenAuthoring,
|
||||
t,
|
||||
} = this.props;
|
||||
if (currentStatus) {
|
||||
@ -408,7 +408,7 @@ class EditorToolbar extends React.Component {
|
||||
onClick={() => onChangeStatus('PENDING_REVIEW')}
|
||||
icon={currentStatus === status.get('PENDING_REVIEW') && 'check'}
|
||||
/>
|
||||
{useForkWorkflow ? (
|
||||
{useOpenAuthoring ? (
|
||||
''
|
||||
) : (
|
||||
<StatusDropdownItem
|
||||
@ -418,7 +418,7 @@ class EditorToolbar extends React.Component {
|
||||
/>
|
||||
)}
|
||||
</ToolbarDropdown>
|
||||
{useForkWorkflow ? (
|
||||
{useOpenAuthoring ? (
|
||||
''
|
||||
) : (
|
||||
<ToolbarDropdown
|
||||
|
@ -55,7 +55,7 @@ class Workflow extends Component {
|
||||
static propTypes = {
|
||||
collections: ImmutablePropTypes.orderedMap,
|
||||
isEditorialWorkflow: PropTypes.bool.isRequired,
|
||||
isForkWorkflow: PropTypes.bool,
|
||||
isOpenAuthoring: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
unpublishedEntries: ImmutablePropTypes.map,
|
||||
loadUnpublishedEntries: PropTypes.func.isRequired,
|
||||
@ -75,7 +75,7 @@ class Workflow extends Component {
|
||||
render() {
|
||||
const {
|
||||
isEditorialWorkflow,
|
||||
isForkWorkflow,
|
||||
isOpenAuthoring,
|
||||
isFetching,
|
||||
unpublishedEntries,
|
||||
updateUnpublishedEntryStatus,
|
||||
@ -127,7 +127,7 @@ class Workflow extends Component {
|
||||
handleChangeStatus={updateUnpublishedEntryStatus}
|
||||
handlePublish={publishUnpublishedEntry}
|
||||
handleDelete={deleteUnpublishedEntry}
|
||||
isForkWorkflow={isForkWorkflow}
|
||||
isOpenAuthoring={isOpenAuthoring}
|
||||
/>
|
||||
</WorkflowContainer>
|
||||
);
|
||||
@ -137,8 +137,8 @@ class Workflow extends Component {
|
||||
function mapStateToProps(state) {
|
||||
const { collections, config, globalUI } = state;
|
||||
const isEditorialWorkflow = config.get('publish_mode') === EDITORIAL_WORKFLOW;
|
||||
const isForkWorkflow = globalUI.get('useForkWorkflow', false);
|
||||
const returnObj = { collections, isEditorialWorkflow, isForkWorkflow };
|
||||
const isOpenAuthoring = globalUI.get('useOpenAuthoring', false);
|
||||
const returnObj = { collections, isEditorialWorkflow, isOpenAuthoring };
|
||||
|
||||
if (isEditorialWorkflow) {
|
||||
returnObj.isFetching = state.editorialWorkflow.getIn(['pages', 'isFetching'], false);
|
||||
|
@ -17,7 +17,7 @@ const WorkflowListContainer = styled.div`
|
||||
grid-template-columns: 33.3% 33.3% 33.3%;
|
||||
`;
|
||||
|
||||
const WorkflowListContainerForkWorkflow = styled.div`
|
||||
const WorkflowListContainerOpenAuthoring = styled.div`
|
||||
min-height: 60%;
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50% 0%;
|
||||
@ -134,7 +134,7 @@ class WorkflowList extends React.Component {
|
||||
handlePublish: PropTypes.func.isRequired,
|
||||
handleDelete: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired,
|
||||
isForkWorkflow: PropTypes.bool,
|
||||
isOpenAuthoring: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleChangeStatus = (newStatus, dragProps) => {
|
||||
@ -162,7 +162,7 @@ class WorkflowList extends React.Component {
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
renderColumns = (entries, column) => {
|
||||
const { isForkWorkflow } = this.props;
|
||||
const { isOpenAuthoring } = this.props;
|
||||
if (!entries) return null;
|
||||
|
||||
if (!column) {
|
||||
@ -180,8 +180,8 @@ class WorkflowList extends React.Component {
|
||||
styles.column,
|
||||
styles.columnPosition(idx),
|
||||
isHovered && styles.columnHovered,
|
||||
isForkWorkflow && currColumn === 'pending_publish' && styles.hiddenColumn,
|
||||
isForkWorkflow && currColumn === 'pending_review' && styles.hiddenRightBorder,
|
||||
isOpenAuthoring && currColumn === 'pending_publish' && styles.hiddenColumn,
|
||||
isOpenAuthoring && currColumn === 'pending_review' && styles.hiddenRightBorder,
|
||||
]}
|
||||
>
|
||||
<ColumnHeader name={currColumn}>
|
||||
@ -248,8 +248,8 @@ class WorkflowList extends React.Component {
|
||||
|
||||
render() {
|
||||
const columns = this.renderColumns(this.props.entries);
|
||||
const ListContainer = this.props.isForkWorkflow
|
||||
? WorkflowListContainerForkWorkflow
|
||||
const ListContainer = this.props.isOpenAuthoring
|
||||
? WorkflowListContainerOpenAuthoring
|
||||
: WorkflowListContainer;
|
||||
return <ListContainer>{columns}</ListContainer>;
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Map } from 'immutable';
|
||||
import { USE_FORK_WORKFLOW } from 'Actions/auth';
|
||||
import { USE_OPEN_AUTHORING } from 'Actions/auth';
|
||||
/*
|
||||
* Reducer for some global UI state that we want to share between components
|
||||
* */
|
||||
const globalUI = (state = Map({ isFetching: false, useForkWorkflow: false }), action) => {
|
||||
const globalUI = (state = Map({ isFetching: false, useOpenAuthoring: false }), action) => {
|
||||
// Generic, global loading indicator
|
||||
if (action.type.indexOf('REQUEST') > -1) {
|
||||
return state.set('isFetching', true);
|
||||
} else if (action.type.indexOf('SUCCESS') > -1 || action.type.indexOf('FAILURE') > -1) {
|
||||
return state.set('isFetching', false);
|
||||
} else if (action.type === USE_FORK_WORKFLOW) {
|
||||
return state.set('useForkWorkflow', true);
|
||||
} else if (action.type === USE_OPEN_AUTHORING) {
|
||||
return state.set('useOpenAuthoring', true);
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
Reference in New Issue
Block a user