Skip to content

Commit

Permalink
PS-675 databox fixes & replace source file feat (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
4rthem authored Oct 8, 2024
1 parent 7b0206a commit 3009ba2
Show file tree
Hide file tree
Showing 27 changed files with 370 additions and 146 deletions.
2 changes: 1 addition & 1 deletion dashboard/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"vite-plugin-svgr": "^4.2.0"
},
"devDependencies": {
"@types/node": "^18.19.54",
"@types/node": "^18.19.55",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
Expand Down
40 changes: 40 additions & 0 deletions databox/api/src/Api/Processor/PrepareSubstitutionProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace App\Api\Processor;

use Alchemy\AuthBundle\Security\Traits\SecurityAwareTrait;
use Alchemy\CoreBundle\Util\DoctrineUtil;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Api\Model\Input\Attribute\AssetAttributeBatchUpdateInput;
use App\Attribute\BatchAttributeManager;
use App\Entity\Core\Asset;
use App\Security\Voter\AssetVoter;
use Doctrine\ORM\EntityManagerInterface;
use Ramsey\Uuid\Uuid;

final class PrepareSubstitutionProcessor implements ProcessorInterface
{
use SecurityAwareTrait;

public function __construct(
private readonly BatchAttributeManager $batchAttributeManager,
private readonly EntityManagerInterface $em,
) {
}

/**
* @param Asset $data
*/
public function process($data, Operation $operation, array $uriVariables = [], array $context = []): Asset
{
$data->setPendingUploadToken(Uuid::uuid4()->toString());

$this->em->persist($data);
$this->em->flush();

return $data;
}
}
2 changes: 1 addition & 1 deletion databox/api/src/Asset/RenditionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function buildRendition(RenditionDefinition $renditionDefinition, Asset $
$renditionDefinition,
$file,
$buildHash,
$outputFile?->getBuildHashes() ?? $buildHash,
$outputFile?->getBuildHashes(),
);
$this->em->flush();
} finally {
Expand Down
1 change: 1 addition & 0 deletions databox/api/src/Border/UploaderClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function ackAsset(string $baseUrl, string $id, string $token): void
'headers' => [
'Authorization' => 'AssetToken '.$token,
],
'json' => [],
]);
}

Expand Down
11 changes: 11 additions & 0 deletions databox/api/src/Entity/Core/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use App\Api\Processor\MoveAssetProcessor;
use App\Api\Processor\MultipleAssetCreateProcessor;
use App\Api\Processor\PrepareDeleteAssetProcessor;
use App\Api\Processor\PrepareSubstitutionProcessor;
use App\Api\Processor\RemoveAssetFromCollectionProcessor;
use App\Api\Processor\TriggerAssetWorkflowProcessor;
use App\Api\Provider\AssetCollectionProvider;
Expand Down Expand Up @@ -90,6 +91,16 @@
input: AssetAttributeBatchUpdateInput::class,
processor: AssetAttributeBatchUpdateProcessor::class,
),
new Put(
uriTemplate: '/assets/{id}/prepare-substitution',
normalizationContext: [
'groups' => [self::GROUP_READ],
],
security: 'is_granted("'.AbstractVoter::EDIT.'", object)',
output: AssetOutput::class,
provider: AssetCollectionProvider::class,
processor: PrepareSubstitutionProcessor::class,
),
new GetCollection(),
new Post(securityPostDenormalize: 'is_granted("CREATE", object)'),
new Post(
Expand Down
7 changes: 7 additions & 0 deletions databox/client/src/api/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ export async function prepareDeleteAssets(
return res.data;
}

export async function prepareAssetSubstitution(
id: string
): Promise<Asset> {
const res = await apiClient.put(`/assets/${id}/prepare-substitution`, {});
return res.data;
}

export async function putAsset(id: string, data: Partial<any>): Promise<Asset> {
const res = await apiClient.put(`/assets/${id}`, data, {
headers: {
Expand Down
19 changes: 14 additions & 5 deletions databox/client/src/api/uploader/file.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {UploadedFile, uploadMultipartFile} from './multiPartUpload';
import config from '../../config';
import uploaderClient from '../uploader-client';
import {promiseConcurrency} from '../../lib/promises';
import {oauthClient} from '../api-client';
import {RawAxiosRequestHeaders} from 'axios';
import {multipartUpload} from "../../../../../lib/js/api/src/multiPartUpload.ts";

interface MyHeaders extends RawAxiosRequestHeaders {
Authorization?: string;
Expand All @@ -23,14 +23,17 @@ export async function makeAuthorizationHeaders(): Promise<MyHeaders> {

type FormData = Record<string, any> | undefined;

type UploadedFile = {
data?: Record<string, any>;
file: File;
};
export async function UploadFiles(
userId: string,
files: UploadedFile[],
formData?: FormData
): Promise<void> {
const targetSlug = config.uploaderTargetSlug;
const assets = await promiseConcurrency(
files.map(f => () => UploadFile(targetSlug, userId, f)),
files.map(f => () => UploadFile(targetSlug, f)),
2
);

Expand All @@ -39,10 +42,16 @@ export async function UploadFiles(

export async function UploadFile(
targetSlug: string,
userId: string,
uploadedFile: UploadedFile
): Promise<string> {
return await uploadMultipartFile(targetSlug, userId, uploadedFile);
const multipart = await multipartUpload(uploaderClient, uploadedFile.file, {
});

return (await uploaderClient.post(`/assets`, {
targetSlug,
multipart,
data: uploadedFile.data,
})).data.id;
}

export async function CommitUpload(
Expand Down
111 changes: 0 additions & 111 deletions databox/client/src/api/uploader/multiPartUpload.ts

This file was deleted.

60 changes: 58 additions & 2 deletions databox/client/src/components/AssetList/AssetContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {ActionsContext, ReloadFunc} from './types.ts';
import {useAssetActions} from '../../hooks/useAssetActions.ts';
import ContextMenu from '../Ui/ContextMenu.tsx';
import {ContextMenuContext} from '../../hooks/useContextMenu.ts';
import InfoIcon from '@mui/icons-material/Info';
import FileCopyIcon from "@mui/icons-material/FileCopy";
import DriveFileMoveIcon from '@mui/icons-material/DriveFileMove';
import ChangeCircleIcon from '@mui/icons-material/ChangeCircle';

type Props<Item extends AssetOrAssetContainer> = {
contextMenu: ContextMenuContext<{
Expand All @@ -36,8 +40,8 @@ export default function AssetContextMenu<Item extends AssetOrAssetContainer>({
const {asset, item} = contextMenu.data;
const {id, original} = asset;

const {onDelete, onOpen, onDownload, onEdit, onEditAttr, can} =
useAssetActions({asset, onAction: onClose, actionsContext});
const {onDelete, onOpen, onDownload, onInfo, onEdit, onMove, onCopy, onReplace, onEditAttr, can} =
useAssetActions({asset, onAction: onClose, actionsContext, reload});

const openUrl = (url: string) => {
document.location.href = url;
Expand Down Expand Up @@ -83,6 +87,14 @@ export default function AssetContextMenu<Item extends AssetOrAssetContainer>({
<ListItemText primary={a.label || a.type} />
</MenuItem>
))}
<MenuItem onClick={onInfo}>
<ListItemIcon>
<InfoIcon />
</ListItemIcon>
<ListItemText
primary={t('asset.actions.info', 'Info')}
/>
</MenuItem>
{can.download && (
<MenuItem onClick={onDownload}>
<ListItemIcon>
Expand All @@ -106,6 +118,32 @@ export default function AssetContextMenu<Item extends AssetOrAssetContainer>({
) : (
''
)}
{actionsContext.move ? (
<MenuItem
disabled={!can.edit}
onClick={can.edit ? onMove : undefined}
>
<ListItemIcon>
<DriveFileMoveIcon />
</ListItemIcon>
<ListItemText primary={t('asset.actions.move', 'Move')} />
</MenuItem>
) : (
''
)}
{actionsContext.copy ? (
<MenuItem
disabled={!can.share}
onClick={can.share ? onCopy : undefined}
>
<ListItemIcon>
<FileCopyIcon />
</ListItemIcon>
<ListItemText primary={t('asset.actions.copy', 'Copy')} />
</MenuItem>
) : (
''
)}
{actionsContext.edit ? (
<MenuItem
disabled={!can.editAttributes}
Expand All @@ -124,6 +162,24 @@ export default function AssetContextMenu<Item extends AssetOrAssetContainer>({
) : (
''
)}
{actionsContext.replace ? (
<MenuItem
disabled={!can.edit}
onClick={can.edit ? onReplace : undefined}
>
<ListItemIcon>
<ChangeCircleIcon />
</ListItemIcon>
<ListItemText
primary={t(
'asset.actions.replace_source_file',
'Replace source file'
)}
/>
</MenuItem>
) : (
''
)}
<Divider key={'d'} />
{actionsContext.delete ? (
<MenuItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default function SelectionActions<Item extends AssetOrAssetContainer>({
assetIds: selectedAssets.map(i => i.id),
workspaceId: wsId!,
onComplete: () => {
reload && reload();
reload?.();
},
});
};
Expand Down Expand Up @@ -236,15 +236,15 @@ export default function SelectionActions<Item extends AssetOrAssetContainer>({
openModal(DeleteAssetsConfirm, {
assetIds: selectedAssets.map(i => i.id),
onDelete: () => {
reload && reload();
reload?.();
},
});
},
onCopy: () => {
openModal(CopyAssetsDialog, {
assets: selectedAssets,
onComplete: () => {
reload && reload();
reload?.();
},
});
},
Expand Down
4 changes: 4 additions & 0 deletions databox/client/src/components/AssetList/actionContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ export function createDefaultActionsContext<
edit: true,
share: true,
delete: true,
open: true,
move: true,
copy: true,
replace: true,
};
}
Loading

0 comments on commit 3009ba2

Please sign in to comment.