-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NEW adds 'Duplicate' action to elements
- Duplicates element. - Adds ' (Copy)' to the Title. - Reorder duplicate to position after the cloned element.
- Loading branch information
jcarter
committed
Jan 9, 2020
1 parent
51da698
commit de7d25f
Showing
14 changed files
with
171 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* global window */ | ||
import React from 'react'; | ||
import { compose } from 'redux'; | ||
import AbstractAction from 'components/ElementActions/AbstractAction'; | ||
import duplicateBlockMutation from 'state/editor/duplicateBlockMutation'; | ||
import i18n from 'i18n'; | ||
|
||
/** | ||
* Adds the elemental menu action to duplicate a block | ||
*/ | ||
const DuplicateAction = (MenuComponent) => (props) => { | ||
const handleClick = (event) => { | ||
event.stopPropagation(); | ||
|
||
const { element: { ID: id }, actions: { handleDuplicateBlock } } = props; | ||
|
||
if (handleDuplicateBlock) { | ||
handleDuplicateBlock(id).then(() => { | ||
const preview = window.jQuery('.cms-preview'); | ||
preview.entwine('ss.preview')._loadUrl(preview.find('iframe').attr('src')); | ||
}); | ||
} | ||
}; | ||
|
||
const newProps = { | ||
title: i18n._t('ElementArchiveAction.DUPLICATE', 'Duplicate'), | ||
className: 'element-editor__actions-duplicate', | ||
onClick: handleClick, | ||
toggle: props.toggle, | ||
}; | ||
|
||
return ( | ||
<MenuComponent {...props}> | ||
{props.children} | ||
|
||
<AbstractAction {...newProps} /> | ||
</MenuComponent> | ||
); | ||
}; | ||
|
||
export { DuplicateAction as Component }; | ||
|
||
export default compose(duplicateBlockMutation, DuplicateAction); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { graphql } from 'react-apollo'; | ||
import gql from 'graphql-tag'; | ||
import { config as readBlocksConfig, query as readBlocksQuery } from './readBlocksForAreaQuery'; | ||
|
||
// GraphQL query for duplicating a specific block | ||
const mutation = gql` | ||
mutation DuplicateBlock($blockId: ID!) { | ||
duplicateBlock(ID: $blockId) { | ||
ID | ||
} | ||
} | ||
`; | ||
|
||
const config = { | ||
props: ({ mutate, ownProps: { actions } }) => { | ||
const handleDuplicateBlock = (blockId) => mutate({ | ||
variables: { blockId }, | ||
}); | ||
|
||
return { | ||
actions: { | ||
...actions, | ||
handleDuplicateBlock, | ||
}, | ||
}; | ||
}, | ||
options: ({ areaId }) => ({ | ||
// Refetch versions after mutation is completed | ||
refetchQueries: [{ | ||
query: readBlocksQuery, | ||
variables: readBlocksConfig.options({ areaId }).variables | ||
}] | ||
}), | ||
}; | ||
|
||
export { mutation, config }; | ||
|
||
export default graphql(mutation, config); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
namespace DNADesign\Elemental\GraphQL; | ||
|
||
use DNADesign\Elemental\Models\BaseElement; | ||
use DNADesign\Elemental\Models\ElementalArea; | ||
use DNADesign\Elemental\Services\ReorderElements; | ||
use GraphQL\Type\Definition\ResolveInfo; | ||
use GraphQL\Type\Definition\Type; | ||
use InvalidArgumentException; | ||
use Exception; | ||
use SilverStripe\Core\Injector\Injector; | ||
use SilverStripe\GraphQL\MutationCreator; | ||
use SilverStripe\GraphQL\OperationResolver; | ||
use SilverStripe\GraphQL\Scaffolding\StaticSchema; | ||
|
||
class DuplicateElementMutation extends MutationCreator implements OperationResolver | ||
{ | ||
public function attributes() | ||
{ | ||
return [ | ||
'name' => 'duplicateBlock', | ||
'description' => 'Duplicate an Element in this ElementalArea' | ||
]; | ||
} | ||
|
||
public function type() | ||
{ | ||
return $this->manager->getType(StaticSchema::inst()->typeNameForDataObject(BaseElement::class)); | ||
} | ||
|
||
public function args() | ||
{ | ||
return [ | ||
'ID' => ['type' => Type::nonNull(Type::id())], | ||
]; | ||
} | ||
|
||
public function resolve($object, array $args, $context, ResolveInfo $info) | ||
{ | ||
// load element to clone | ||
$elementID = $args['ID']; | ||
$element = BaseElement::get_by_id($elementID); | ||
if (!$element) { | ||
throw new InvalidArgumentException("Invalid BaseElementID: $elementID"); | ||
} | ||
|
||
// check can edit the elemental area | ||
$areaID = $element->ParentID; | ||
$area = ElementalArea::get_by_id($areaID); | ||
if (!$area) { | ||
throw new InvalidArgumentException("Invalid ParentID on BaseElement: $elementID"); | ||
} | ||
if (!$area->canEdit($context['currentUser'])) { | ||
throw new InvalidArgumentException( | ||
"The current user has insufficient permission to edit ElementalArea: $areaID" | ||
); | ||
} | ||
|
||
try { | ||
// clone element | ||
$clone = $element->duplicate(false); | ||
$clone->Title .= ' (Copy)'; | ||
$clone->Sort = 0; // must be zeroed for reorder to work | ||
$area->Elements()->add($clone); | ||
|
||
// reorder | ||
$reorderer = Injector::inst()->create(ReorderElements::class, $clone); | ||
$reorderer->reorder($elementID); | ||
|
||
return $clone; | ||
} catch (Exception $e) { | ||
throw new Exception("Something went wrong when duplicating element: $elementID"); | ||
} | ||
} | ||
} |