Skip to content

Commit

Permalink
Merge pull request #14482 from craftcms/feature/cms-1248-show-in-fold…
Browse files Browse the repository at this point in the history
…er-asset-action

Show in folder asset action
  • Loading branch information
brandonkelly authored Feb 29, 2024
2 parents 7909266 + 50dda31 commit 86b20ea
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
> [!WARNING]
> When licensing issues occur on public domains, the control panel will now become temporarily inaccessible for logged-in users, alerting them to the problems and giving them an opportunity to resolve them. (The front end will not be impacted.)
- It’s now possible to update expired licenses from the Updates utility, on non-public domains.
- It’s now possible to update expired licenses from the Updates utility, on non-public domains.
- The GraphQL API is now available for Craft Solo installs.
- It’s now possible to toggle the details sidebar on full edit pages. ([#14432](https://github.com/craftcms/cms/pull/14432))
- Element slideouts now show validation summaries at the top of each tab. ([#14436](https://github.com/craftcms/cms/pull/14436))
- Added the “Show in folder” asset action. ([#14227](https://github.com/craftcms/cms/discussions/14227))
- Color fields now have a “Presets” settings. ([#14463](https://github.com/craftcms/cms/discussions/14463))
- Inline-editable Matrix blocks now show their entry type icon/name even if the field only has one entry type selected. ([#14458](https://github.com/craftcms/cms/discussions/14458))
- Added support for eager-loading addresses’ and entries’ owner elements via `owner` and `primaryOwner` eager-loading handles.
Expand Down
35 changes: 35 additions & 0 deletions src/controllers/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use craft\helpers\FileHelper;
use craft\helpers\ImageTransforms;
use craft\helpers\StringHelper;
use craft\helpers\UrlHelper;
use craft\i18n\Formatter;
use craft\imagetransforms\ImageTransformer;
use craft\models\ImageTransform;
Expand Down Expand Up @@ -1346,4 +1347,38 @@ public function actionGenerateFallbackTransform(string $transform): Response
'inline' => true,
]);
}

/**
* Show in folder action.
* Find asset by id and Return source path info for each folder up until the one the asset is in.
*
* @return Response
* @throws BadRequestHttpException
* @throws InvalidConfigException
* @throws \yii\web\MethodNotAllowedHttpException
*/
public function actionShowInFolder(): Response
{
$this->requireCpRequest();

$assetId = Craft::$app->getRequest()->getRequiredParam('assetId');

$asset = Asset::findOne($assetId);
if ($asset === null) {
throw new BadRequestHttpException("Invalid asset ID: $assetId");
}

// get the folder for selected asset
$folder = $asset->getFolder();
$sourcePath[] = $folder->getSourcePathInfo();

$uri = StringHelper::ensureLeft(UrlHelper::prependCpTrigger($sourcePath[0]['uri']), '/');
$url = UrlHelper::urlWithParams($uri, [
'search' => $asset->filename,
'includeSubfolders' => '0',
'sourcePathStep' => "folder:$folder->uid",
]);

return $this->redirect($url);
}
}
12 changes: 12 additions & 0 deletions src/elements/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,18 @@ protected function safeActionMenuItems(): array
$this->id,
]);

// Show in Folder
if ($user->can("viewAssets:{$this->getVolume()->uid}")) {
$viewItems[] = [
'type' => MenuItemType::Link,
'icon' => 'magnifying-glass',
'label' => Craft::t('app', 'Show in folder'),
'url' => UrlHelper::actionUrl('assets/show-in-folder', [
'assetId' => $this->id,
]),
];
}

$viewIndex = Collection::make($items)->search(fn(array $item) => str_starts_with($item['id'] ?? '', 'action-view-'));
array_splice($items, $viewIndex !== false ? $viewIndex + 1 : 0, 0, $viewItems);

Expand Down
1 change: 1 addition & 0 deletions src/translations/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,7 @@
'Show field handles in edit forms' => 'Show field handles in edit forms',
'Show full exception views when Dev Mode is disabled' => 'Show full exception views when Dev Mode is disabled',
'Show in element cards' => 'Show in element cards',
'Show in folder' => 'Show in folder',
'Show nav' => 'Show nav',
'Show nested sources' => 'Show nested sources',
'Show sidebar' => 'Show sidebar',
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js.map

Large diffs are not rendered by default.

22 changes: 20 additions & 2 deletions src/web/assets/cp/src/js/AssetIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,22 @@ Craft.AssetIndex = Craft.BaseElementIndex.extend(
_uploadTotalFiles: 0,
_uploadFileProgress: {},
_currentUploaderSettings: {},
_includeSubfolders: null,

init: function (elementType, $container, settings) {
settings = Object.assign({}, Craft.AssetIndex.defaults, settings);
this.base(elementType, $container, settings);
this.setSettings(settings, Craft.BaseElementIndex.defaults);

if (this.settings.context === 'index') {
// remember whether includeSubfolders was set in the query string,
// before the URL is updated
const queryParams = Craft.getQueryParams();
if (queryParams.includeSubfolders !== undefined) {
this._includeSubfolders = !!parseInt(queryParams.includeSubfolders);
}
}

this.base(elementType, $container, this.settings);

if (this.settings.context === 'index') {
this.itemDrag = new Garnish.DragDrop({
Expand Down Expand Up @@ -362,7 +374,13 @@ Craft.AssetIndex = Craft.BaseElementIndex.extend(
.removeClass('hidden');
}

var checked = this.getSelectedSourceState('includeSubfolders', false);
let checked;
if (this._includeSubfolders !== null) {
checked = this._includeSubfolders;
this._includeSubfolders = null;
} else {
checked = this.getSelectedSourceState('includeSubfolders', false);
}
this.$includeSubfoldersCheckbox.prop('checked', checked);

this.$includeSubfoldersContainer.velocity(
Expand Down
6 changes: 5 additions & 1 deletion src/web/assets/cp/src/js/BaseElementIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,11 @@ Craft.BaseElementIndex = Garnish.Base.extend(
// source path is selected
let stepKey;
if (this.settings.context === 'index') {
stepKey = this.getSelectedSourceState('sourcePathStep');
if (queryParams.sourcePathStep !== undefined) {
stepKey = queryParams.sourcePathStep;
} else {
stepKey = this.getSelectedSourceState('sourcePathStep');
}
} else {
stepKey = this.instanceState.sourcePathStep || null;
}
Expand Down

0 comments on commit 86b20ea

Please sign in to comment.