diff --git a/Classes/Service/UsageDetailsService.php b/Classes/Service/UsageDetailsService.php index 83fbed4aa..e05976612 100644 --- a/Classes/Service/UsageDetailsService.php +++ b/Classes/Service/UsageDetailsService.php @@ -120,6 +120,12 @@ class UsageDetailsService */ protected $packageManager; + /** + * @Flow\InjectConfiguration(path="contentDimensions", package="Neos.ContentRepository") + * @var array + */ + protected $contentDimensionsConfiguration; + private $accessibleWorkspaces = []; public function resolveUsagesForAsset(AssetInterface $asset): array @@ -176,7 +182,7 @@ protected function getNodePropertiesUsageMetadataSchema(): array [ 'name' => 'contentDimensions', 'label' => 'Content Dimensions', - 'type' => 'TEXT', + 'type' => 'JSON', ], [ 'name' => 'lastModified', @@ -222,7 +228,7 @@ protected function getNodePropertiesUsageDetails(AssetUsageInNodeProperties $usa ], [ 'name' => 'contentDimensions', - 'value' => json_encode(array_values($node->getDimensions())), + 'value' => json_encode($this->resolveDimensionValuesForNode($node)), ], ]; } @@ -230,6 +236,19 @@ protected function getNodePropertiesUsageDetails(AssetUsageInNodeProperties $usa return new AssetUsageDetails($label, $url, $metadata); } + protected function resolveDimensionValuesForNode(NodeInterface $node): array + { + $dimensionValues = []; + foreach ($node->getDimensions() as $dimensionName => $dimensionValuesForName) { + $dimensionValues[$this->contentDimensionsConfiguration[$dimensionName]['label'] ?? $dimensionName] = array_map(function ( + $dimensionValue + ) use ($dimensionName) { + return $this->contentDimensionsConfiguration[$dimensionName]['presets'][$dimensionValue]['label'] ?? $dimensionValue; + }, $dimensionValuesForName); + } + return $dimensionValues; + } + protected function getNodeFrom(AssetUsageInNodeProperties $assetUsage): ?NodeInterface { $context = $this->_contextFactory->create( diff --git a/Resources/Private/GraphQL/schema.root.graphql b/Resources/Private/GraphQL/schema.root.graphql index e348edc24..6ec52a678 100644 --- a/Resources/Private/GraphQL/schema.root.graphql +++ b/Resources/Private/GraphQL/schema.root.graphql @@ -355,6 +355,7 @@ enum UsageDetailsMetadataType { DATE DATETIME URL + JSON } """ diff --git a/Resources/Private/JavaScript/asset-usage/src/components/AssetUsageSection.tsx b/Resources/Private/JavaScript/asset-usage/src/components/AssetUsageSection.tsx index 74e4ac05d..5801e480c 100644 --- a/Resources/Private/JavaScript/asset-usage/src/components/AssetUsageSection.tsx +++ b/Resources/Private/JavaScript/asset-usage/src/components/AssetUsageSection.tsx @@ -16,12 +16,14 @@ const useStyles = createUseMediaUiStyles((theme: MediaUiTheme) => ({ usageTable: { width: '100%', marginTop: theme.spacing.full, + lineHeight: 1.5, '& th': { fontWeight: 'bold', textAlign: 'left', }, '& td, & th': { padding: theme.spacing.quarter, + verticalAlign: 'baseline', '&:first-child': { paddingLeft: 0, }, @@ -38,6 +40,15 @@ const useStyles = createUseMediaUiStyles((theme: MediaUiTheme) => ({ textDecoration: 'underline', }, }, + '& li': { + listStyleType: 'disc', + '& ul': { + paddingLeft: '1rem', + '& li': { + display: 'list-item', + }, + }, + }, }, })); @@ -45,6 +56,29 @@ interface AssetUsageSectionProps { usageDetailsGroup: UsageDetailsGroup; } +// Recursive function to render an object as a nested list +function renderObject(data: Record) { + return Array.isArray(data) ? ( + + ) : typeof data === 'object' ? ( + + ) : typeof data === 'string' ? ( + data + ) : ( + JSON.stringify(data) + ); +} + const AssetUsageSection: React.FC = ({ usageDetailsGroup }: AssetUsageSectionProps) => { const classes = useStyles(); const { translate } = useIntl(); @@ -81,6 +115,8 @@ const AssetUsageSection: React.FC = ({ usageDetailsGroup {name} + ) : type == 'JSON' ? ( + renderObject(JSON.parse(usage.value)) ) : ( usage.value )} diff --git a/Resources/Private/JavaScript/asset-usage/src/components/AssetUsagesModal.tsx b/Resources/Private/JavaScript/asset-usage/src/components/AssetUsagesModal.tsx index 4aa5a4615..53facbd30 100644 --- a/Resources/Private/JavaScript/asset-usage/src/components/AssetUsagesModal.tsx +++ b/Resources/Private/JavaScript/asset-usage/src/components/AssetUsagesModal.tsx @@ -4,7 +4,7 @@ import { useRecoilState } from 'recoil'; import { Button, Dialog } from '@neos-project/react-ui-components'; -import { useIntl, createUseMediaUiStyles, MediaUiTheme } from '@media-ui/core/src'; +import { useIntl, createUseMediaUiStyles, MediaUiTheme } from '@media-ui/core'; import { useSelectedAsset } from '@media-ui/core/src/hooks'; import assetUsageDetailsModalState from '../state/assetUsageDetailsModalState'; diff --git a/Resources/Private/JavaScript/asset-usage/src/interfaces/UsageDetails.ts b/Resources/Private/JavaScript/asset-usage/src/interfaces/UsageDetails.ts index 041fbbebb..002f5cd89 100644 --- a/Resources/Private/JavaScript/asset-usage/src/interfaces/UsageDetails.ts +++ b/Resources/Private/JavaScript/asset-usage/src/interfaces/UsageDetails.ts @@ -5,6 +5,7 @@ export enum UsageDetailsMetadataType { DATE = 'DATE', DATETIME = 'DATETIME', URL = 'URL', + JSON = 'JSON', } export interface UsageDetailsMetadataSchema { diff --git a/Resources/Private/JavaScript/core/package.json b/Resources/Private/JavaScript/core/package.json index a2f2f30f2..0550f3e72 100644 --- a/Resources/Private/JavaScript/core/package.json +++ b/Resources/Private/JavaScript/core/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "license": "GNU GPLv3", "private": true, + "main": "src/index.ts", "dependencies": { "matcher": "^5.0.0", "pubsub-js": "^1.9.3"