Skip to content

Commit

Permalink
add es document
Browse files Browse the repository at this point in the history
  • Loading branch information
4rthem committed Nov 21, 2024
1 parent 41de30a commit d7145df
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 9 deletions.
1 change: 1 addition & 0 deletions databox/api/src/Api/Model/Input/AssetInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AssetInput extends AbstractOwnerIdInput
/**
* @var Workspace
*/
#[Assert\NotNull]
public $workspace;

public ?Collection $collection = null;
Expand Down
32 changes: 32 additions & 0 deletions databox/api/src/Api/Model/Output/ESDocumentOutput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace App\Api\Model\Output;

use Alchemy\WebhookBundle\Normalizer\WebhookSerializationInterface;
use ApiPlatform\Metadata\ApiProperty;
use App\Api\Filter\Group\GroupValue;
use App\Api\Model\Output\Traits\CapabilitiesDTOTrait;
use App\Api\Model\Output\Traits\CreatedAtDTOTrait;
use App\Api\Model\Output\Traits\UpdatedAtDTOTrait;
use App\Entity\Core\Asset;
use App\Entity\Core\AssetRendition;
use App\Entity\Core\File;
use App\Entity\Core\Share;
use Symfony\Component\Serializer\Annotation\Groups;

final readonly class ESDocumentOutput
{
public function __construct(
#[Groups(['_'])]
private array $data,
)
{
}

public function getData(): array
{
return $this->data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace App\Api\Provider;

use Alchemy\AuthBundle\Security\JwtUser;
use Alchemy\AuthBundle\Security\Traits\SecurityAwareTrait;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Api\Model\Output\ESDocumentOutput;
use App\Api\Traits\ItemProviderAwareTrait;
use App\Elasticsearch\ElasticSearchClient;
use App\Entity\Core\Asset;
use App\Security\Voter\AbstractVoter;
use Doctrine\ORM\EntityManagerInterface;
use Elastica\Request;

final class AssetElasticsearchDocumentProvider implements ProviderInterface
{
use SecurityAwareTrait;
use ItemProviderAwareTrait;

public function __construct(
private readonly EntityManagerInterface $em,
private readonly ElasticSearchClient $elasticSearchClient,
) {
}

public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$asset = $this->itemProvider->provide($operation, $uriVariables, $context);
$this->denyAccessUnlessGranted(AbstractVoter::READ, $asset);
$this->denyAccessUnlessGranted(JwtUser::ROLE_TECH);

if ($asset instanceof Asset) {
$indexName = $this->elasticSearchClient->getIndexName('asset');
$response = $this->elasticSearchClient->request($indexName.'/_doc/'.$asset->getId(), [], Request::GET);

return new ESDocumentOutput($response->getData());
}

return null;
}
}
1 change: 1 addition & 0 deletions databox/api/src/Elasticsearch/ElasticSearchClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public function __construct(
private Client $client,
private Index $assetIndex,
private Index $collectionIndex,
) {
}

Expand Down
16 changes: 14 additions & 2 deletions databox/api/src/Entity/Core/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use App\Api\Model\Input\MultipleAssetInput;
use App\Api\Model\Input\PrepareDeleteAssetsInput;
use App\Api\Model\Output\AssetOutput;
use App\Api\Model\Output\ESDocumentOutput;
use App\Api\Model\Output\MultipleAssetOutput;
use App\Api\Model\Output\PrepareDeleteAssetsOutput;
use App\Api\Processor\AssetAttributeBatchUpdateProcessor;
Expand All @@ -35,6 +36,7 @@
use App\Api\Processor\RemoveAssetFromCollectionProcessor;
use App\Api\Processor\TriggerAssetWorkflowProcessor;
use App\Api\Provider\AssetCollectionProvider;
use App\Api\Provider\AssetElasticsearchDocumentProvider;
use App\Api\Provider\SearchSuggestionCollectionProvider;
use App\Controller\Core\DeleteAssetByIdsAction;
use App\Controller\Core\DeleteAssetByKeysAction;
Expand Down Expand Up @@ -66,7 +68,8 @@
new Get(
normalizationContext: [
'groups' => [self::GROUP_READ, Collection::GROUP_ABSOLUTE_TITLE],
]
],
security: 'is_granted("'.AbstractVoter::READ.'", object)',
),
new Delete(
uriTemplate: '/assets/{id}/collections/{collectionId}',
Expand Down Expand Up @@ -102,7 +105,10 @@
processor: PrepareSubstitutionProcessor::class,
),
new GetCollection(),
new Post(securityPostDenormalize: 'is_granted("CREATE", object)'),
new Post(
securityPostDenormalize: 'is_granted("CREATE", object)',
validate: true,
),
new Post(
uriTemplate: '/assets/multiple',
normalizationContext: [
Expand Down Expand Up @@ -153,6 +159,12 @@
controller: DeleteAssetByIdsAction::class,
name: 'delete_by_ids',
),
new Get(
uriTemplate: '/assets/{id}/es-document',
output: ESDocumentOutput::class,
name: 'es_document',
provider: AssetElasticsearchDocumentProvider::class,
),
],
normalizationContext: [
'groups' => [self::GROUP_LIST],
Expand Down
12 changes: 5 additions & 7 deletions databox/client/src/api/asset.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import apiClient from './api-client';
import {Asset, AssetFileVersion, Attribute, Collection, Share} from '../types';
import {
ApiCollectionResponse,
getAssetsHydraCollection,
getHydraCollection,
} from './hydra';
import {ApiCollectionResponse, getAssetsHydraCollection, getHydraCollection,} from './hydra';
import {AxiosRequestConfig} from 'axios';
import {TFacets} from '../components/Media/Asset/Facets';

Expand Down Expand Up @@ -96,9 +92,11 @@ export async function getSearchSuggestions(
}

export async function getAsset(id: string): Promise<Asset> {
const res = await apiClient.get(`/assets/${id}`);
return (await apiClient.get(`/assets/${id}`)).data;
}

return res.data;
export async function getAssetESDocument(id: string): Promise<Asset> {
return (await apiClient.get(`/assets/${id}/es-document`)).data.data;
}

export async function getAssetShares(assetId: string): Promise<Share[]> {
Expand Down
12 changes: 12 additions & 0 deletions databox/client/src/components/Dialog/Asset/AssetDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ import OperationsAsset from './OperationsAsset';
import {modalRoutes} from '../../../routes';
import {useNavigateToModal} from '../../Routing/ModalLink.tsx';
import AssetWorkflow from './AssetWorkflow.tsx';
import {useAuth} from '@alchemy/react-auth';
import AssetESDocument from "./AssetESDocument.tsx";

type Props = {};

export default function AssetDialog({}: Props) {
const {t} = useTranslation();
const {id} = useParams();
const navigateToModal = useNavigateToModal();
const {user} = useAuth();

const [data, setData] = useState<Asset>();

Expand Down Expand Up @@ -128,6 +131,15 @@ export default function AssetDialog({}: Props) {
},
enabled: data.capabilities.canEdit,
},
{
title: t('asset.manage.es_doc.title', 'ES Document'),
component: AssetESDocument,
id: 'es_doc',
props: {
data,
},
enabled: user?.roles?.includes('tech') ?? false,
},
]}
/>
);
Expand Down
50 changes: 50 additions & 0 deletions databox/client/src/components/Dialog/Asset/AssetESDocument.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {Asset, StateSetter} from '../../../types';
import {DialogTabProps} from '../Tabbed/TabbedDialog';
import ContentTab from '../Tabbed/ContentTab';
import {getAssetESDocument} from '../../../api/asset';
import {useCallback, useEffect, useState} from "react";
import RefreshIcon from '@mui/icons-material/Refresh';
import {IconButton, LinearProgress, Typography} from "@mui/material";

type Props = {
data: Asset;
setData: StateSetter<Asset>;
} & DialogTabProps;

export default function AssetESDocument({
data,
onClose,
minHeight,
}: Props) {
const [document, setDocument] = useState<object>();
const [loading, setLoading] = useState(false);

const refresh = useCallback(async () => {
setLoading(true);
try {
setDocument(await getAssetESDocument(data.id));
} finally {
setLoading(false);
}
}, [data.id]);

useEffect(() => {
refresh();
}, [refresh]);

return (
<ContentTab onClose={onClose} minHeight={minHeight}>
{loading && <LinearProgress/>}
{document ? <>
<IconButton onClick={refresh}>
<RefreshIcon />
</IconButton>
<pre style={{
fontSize: 12,
}}>
{JSON.stringify(document, null, 4)}
</pre>
</> : null}
</ContentTab>
);
}

0 comments on commit d7145df

Please sign in to comment.