Skip to content

Commit

Permalink
Make “Duplicate” available to all elements who canDuplicate()
Browse files Browse the repository at this point in the history
Resolves #12382
  • Loading branch information
brandonkelly committed Jan 26, 2023
1 parent 026b1ac commit 77c4e9e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Release Notes for Craft CMS 4.4 (WIP)

### Content Management
- Volume subfolders are now displayed within the element listing pane on asset indexes, rather than as nested sources in the sidebar. ([#12558](https://github.com/craftcms/cms/pull/12558), [#9171](https://github.com/craftcms/cms/discussions/9171), [#5809](https://github.com/craftcms/cms/issues/5809))
- Asset indexes now display the current subfolder path above the element listing. ([#12558](https://github.com/craftcms/cms/pull/12558))
- It’s now possible to move volume folders and assets to a new location via a new “Move…” bulk element action, rather than via drag-and-drop interactions. ([#12558](https://github.com/craftcms/cms/pull/12558))
- All element sources now have a “Duplicate” action, even if the element type’s `defineActions()` method didn’t include one. ([#12382](https://github.com/craftcms/cms/discussions/12382))
- Element index pages now track the search term in a query param, so the results can be shared. ([#8942](https://github.com/craftcms/cms/discussions/8942), [#12399](https://github.com/craftcms/cms/pull/12399))
- Entries with more than 10 revisions now include a “View all revisions” item within their revision menu, which links to a new revisions index page for the entry that paginates through all its revisions. ([#8609](https://github.com/craftcms/cms/discussions/8609))
- Entries and Categories fields now have “Maintain hierarchy” settings, which become available when a single structured source is selected. ([#8522](https://github.com/craftcms/cms/discussions/8522), [#8748](https://github.com/craftcms/cms/discussions/8748), [#11749](https://github.com/craftcms/cms/pull/11749))
Expand Down Expand Up @@ -42,8 +46,12 @@
### Extensibility
- Added the `elements/revisions` action. ([#12211](https://github.com/craftcms/cms/pull/12211))
- Console controllers that directly use `craft\console\ControllerTrait` no longer need to call `$this->checkTty()` or `$this->checkRootUser()` themselves; they are now called from `ControllerTrait::init()` and `beforeAction()`.
- Element source definitions can now include a `defaultSourcePath` key.
- Added `craft\base\Element::cpRevisionsUrl()`.
- Added `craft\base\Element::indexElements()`.
- Added `craft\base\ElementInterface::findSource()`.
- Added `craft\base\ElementInterface::getCpRevisionsUrl()`.
- Added `craft\base\ElementInterface::indexElementCount()`.
- Added `craft\console\ControllerTrait::beforeAction()`.
- Added `craft\console\ControllerTrait::init()`.
- Added `craft\console\ControllerTrait::options()`.
Expand All @@ -58,12 +66,17 @@
- Added `craft\fields\BaseOptionsField::EVENT_DEFINE_OPTIONS`. ([#12351](https://github.com/craftcms/cms/pull/12351))
- Added `craft\fields\BaseRelationField::$branchLimit`.
- Added `craft\fields\BaseRelationField::$maintainHierarchy`.
- Added `craft\models\VolumeFolder::getHasChildren()`.
- Added `craft\models\VolumeFolder::setHasChildren()`.
- Added `craft\queue\jobs\GenerateImageTransform`. ([#12340](https://github.com/craftcms/cms/pull/12340))
- Added `craft\services\Assets::createFolderQuery()`.
- Added `craft\services\Assets::foldersExist()`.
- Added `craft\services\Elements::deleteElementForSite()`.
- Added `craft\services\Elements::deleteElementsForSite()`.
- Added `craft\services\Elements::EVENT_AFTER_DELETE_FOR_SITE`. ([#12354](https://github.com/craftcms/cms/issues/12354))
- Added `craft\services\Elements::EVENT_BEFORE_DELETE_FOR_SITE`. ([#12354](https://github.com/craftcms/cms/issues/12354))
- Added `craft\services\Fields::getFieldsByType()`. ([#12381](https://github.com/craftcms/cms/discussions/12381))
- Added `craft\services\Search::normalizeSearchQuery()`.
- Added `craft\services\Users::EVENT_AFTER_DELETE_USER_PHOTO`. ([#12360](https://github.com/craftcms/cms/pull/12360))
- Added `craft\services\Users::EVENT_AFTER_SAVE_USER_PHOTO`. ([#12360](https://github.com/craftcms/cms/pull/12360))
- Added `craft\services\Users::EVENT_BEFORE_DELETE_USER_PHOTO`. ([#12360](https://github.com/craftcms/cms/pull/12360))
Expand All @@ -73,8 +86,20 @@
- Renamed `craft\elements\conditions\entries\EditableConditionRule` to `SavableConditionRule`, while preserving the original class name with an alias. ([#12266](https://github.com/craftcms/cms/pull/12266))
- Deprecated `craft\queue\jobs\GeneratePendingTransforms`. `GenerateImageTransform` should be used instead. ([#12340](https://github.com/craftcms/cms/pull/12340))
- Added `Craft.Accordion`. ([#12189](https://github.com/craftcms/cms/pull/12189))
- Added `Craft.AssetMover`.
- Added `Craft.BaseElementIndex::getSourcePathActionLabel()`.
- Added `Craft.BaseElementIndex::getSourcePathActions()`.
- Added `Craft.BaseElementIndex::getSourcePathLabel()`.
- Added `Craft.BaseElementIndex::onSourcePathChange()`.
- Added `Craft.BaseElementIndex::sourcePath`.
- Added `Craft.BaseElementSelectorModal::getElementIndexParams()`.
- Added `Craft.BaseElementSelectorModal::getIndexSettings()`.
- Added `Craft.BaseElementSelectorModal::hasSelection()`.
- Added `Craft.ElementFieldSettings`.
- Added `Craft.VolumeFolderSelectorModal`.hp
- Added `Garnish.MultiFunctionBtn`.
- The custom `activate` jQuery event will now trigger when the <kbd>Return</kbd> key is pressed.
- The custom `activate` jQuery event will no longer trigger for <kbd>Ctrl</kbd>/<kbd>Command</kbd>-clicks.
- Deprecated `Craft.CategorySelectInput`. `Craft.BaseElementSelectInput` should be used instead. ([#11749](https://github.com/craftcms/cms/pull/11749))

### System
Expand All @@ -83,3 +108,4 @@
- Assets’ alternative text values are now included as search keywords.
- Updated LitEmoji to v4. ([#12226](https://github.com/craftcms/cms/discussions/12226))
- Fixed a database deadlock error that could occur when updating a relation or structure position for an element that was simultaneously being saved. ([#9905](https://github.com/craftcms/cms/issues/9905))
- The “Duplicate” element action is no longer activatable for elements whose `canDuplicate()` method returns `false`.
6 changes: 6 additions & 0 deletions src/base/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use craft\db\Table;
use craft\elements\actions\Delete;
use craft\elements\actions\DeleteActionInterface;
use craft\elements\actions\Duplicate;
use craft\elements\actions\Edit;
use craft\elements\actions\SetStatus;
use craft\elements\actions\View;
Expand Down Expand Up @@ -908,6 +909,11 @@ public static function actions(string $source): array
)
);

// Prepend Duplicate?
if (!$hasActionType(Duplicate::class)) {
$actions->prepend(Duplicate::class);
}

// Prepend Edit?
if (!$hasActionType(Edit::class)) {
$actions->prepend([
Expand Down
26 changes: 26 additions & 0 deletions src/elements/actions/Duplicate.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ public function getTriggerLabel(): string
: Craft::t('app', 'Duplicate');
}

/**
* @inheritdoc
* @since 3.5.0
*/
public function getTriggerHtml(): ?string
{
// Only enable for duplicatable elements, per canDuplicate()
Craft::$app->getView()->registerJsWithVars(fn($type) => <<<JS
(() => {
new Craft.ElementActionTrigger({
type: $type,
validateSelection: \$selectedItems => {
for (let i = 0; i < \$selectedItems.length; i++) {
if (!Garnish.hasAttr(\$selectedItems.eq(i).find('.element'), 'data-duplicatable')) {
return false;
}
}
return true;
},
});
})();
JS, [static::class]);

return null;
}

/**
* @inheritdoc
*/
Expand Down
4 changes: 4 additions & 0 deletions src/helpers/Cp.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,10 @@ public static function elementHtml(
$attributes['data']['savable'] = true;
}

if ($elementsService->canDuplicate($element, $user)) {
$attributes['data']['duplicatable'] = true;
}

if ($elementsService->canDelete($element, $user)) {
$attributes['data']['deletable'] = true;
}
Expand Down

0 comments on commit 77c4e9e

Please sign in to comment.