Support opening PDFs in a new tab
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import type { Attachment, Piece } from "backend/database";
|
import type { Attachment, Piece } from "backend/database";
|
||||||
import { AttachmentId, PieceId } from "common";
|
import { PieceId } from "common";
|
||||||
import { ACCEPTED_EXTENSIONS } from "common/MediaType";
|
import { ACCEPTED_EXTENSIONS } from "common/MediaType";
|
||||||
import { ELYSIA_FORM_DATA } from "elysia";
|
import { ELYSIA_FORM_DATA } from "elysia";
|
||||||
import { FormEventHandler, useId, useReducer, useRef, useState } from "react";
|
import { FormEventHandler, MouseEvent, useCallback, useId, useReducer, useRef, useState } from "react";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
import { client } from "../client";
|
import { client } from "../client";
|
||||||
import { FileReducer } from "../FileReducer";
|
import { FileReducer } from "../FileReducer";
|
||||||
@@ -125,11 +125,36 @@ namespace Attachments {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Attachments(props: Attachments.Props) {
|
function Attachments(props: Attachments.Props) {
|
||||||
|
return (
|
||||||
|
<table className="grow">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="p-1 border">Nazwa pliku</th>
|
||||||
|
<th className="p-1 border">Typ</th>
|
||||||
|
<th className="p-1 border">Dodano</th>
|
||||||
|
<th className="p-1 border">Zmodyfikowano</th>
|
||||||
|
<th className="p-1 border">Pobierz</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{props.attachments.map((attachment) => <AttachmentRow key={attachment.attachmentId} attachment={attachment} />)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const download = (attachmentId: AttachmentId) => async () => {
|
namespace AttachmentRow {
|
||||||
|
export interface Props {
|
||||||
|
readonly attachment: Attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function AttachmentRow(props: AttachmentRow.Props) {
|
||||||
|
|
||||||
|
const download = useCallback(async () => {
|
||||||
const { error, data: _data } = await client
|
const { error, data: _data } = await client
|
||||||
.piece({ pieceId: props.pieceId })
|
.piece({ pieceId: props.attachment.pieceId })
|
||||||
.attachment({ attachmentId })
|
.attachment({ attachmentId: props.attachment.attachmentId })
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
if (error !== null) {
|
if (error !== null) {
|
||||||
@@ -144,52 +169,64 @@ function Attachments(props: Attachments.Props) {
|
|||||||
a.download = data.filename;
|
a.download = data.filename;
|
||||||
a.click();
|
a.click();
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
};
|
}, [props.attachment.attachmentId, props.attachment.pieceId]);
|
||||||
|
|
||||||
|
const open = useCallback(async () => {
|
||||||
|
const { error, data: _data } = await client
|
||||||
|
.piece({ pieceId: props.attachment.pieceId })
|
||||||
|
.attachment({ attachmentId: props.attachment.attachmentId })
|
||||||
|
.get();
|
||||||
|
|
||||||
|
if (error !== null) {
|
||||||
|
console.error(error.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = _data as unknown as typeof _data[ELYSIA_FORM_DATA];
|
||||||
|
const url = URL.createObjectURL(data.data);
|
||||||
|
window.open(url, "_target");
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, [props.attachment.attachmentId, props.attachment.pieceId, props.attachment.mediaType]);
|
||||||
|
|
||||||
|
const onOpen = useCallback((event: MouseEvent<HTMLAnchorElement>) => {
|
||||||
|
if (props.attachment.mediaType !== "application/pdf") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
open();
|
||||||
|
}, [props.attachment.mediaType, open]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table className="grow">
|
<tr>
|
||||||
<thead>
|
<td className="p-1 border">
|
||||||
<tr>
|
{props.attachment.mediaType === "application/vnd.recordare.musicxml"
|
||||||
<th className="p-1 border">Nazwa pliku</th>
|
|| props.attachment.mediaType === "application/vnd.recordare.musicxml+xml"
|
||||||
<th className="p-1 border">Typ</th>
|
|| props.attachment.mediaType === "application/pdf" ? (
|
||||||
<th className="p-1 border">Dodano</th>
|
<Link className="underline" to={`attachment/${props.attachment.attachmentId}`} onClick={onOpen}>
|
||||||
<th className="p-1 border">Zmodyfikowano</th>
|
{props.attachment.filename}
|
||||||
<th className="p-1 border">Pobierz</th>
|
</Link>
|
||||||
</tr>
|
) : (
|
||||||
</thead>
|
props.attachment.filename
|
||||||
<tbody>
|
)}
|
||||||
{props.attachments.map((attachment) => (
|
</td>
|
||||||
<tr key={attachment.attachmentId}>
|
<td className="p-1 border">{props.attachment.mediaType}</td>
|
||||||
<td className="p-1 border">
|
<td className="p-1 border text-center font-mono text-sm">
|
||||||
{attachment.mediaType === "application/vnd.recordare.musicxml"
|
{props.attachment.createdAt}
|
||||||
|| attachment.mediaType === "application/vnd.recordare.musicxml+xml" ? (
|
{props.attachment.createdBy !== null && <><br />przez {props.attachment.createdBy}</>}
|
||||||
<Link className="underline" to={`attachment/${attachment.attachmentId}`}>
|
</td>
|
||||||
{attachment.filename}
|
<td className="p-1 border text-center font-mono text-sm">
|
||||||
</Link>
|
{props.attachment.modifiedAt === null && props.attachment.modifiedBy === null ? "\u2014"
|
||||||
) : (
|
: props.attachment.modifiedAt !== null && props.attachment.modifiedBy === null ? props.attachment.modifiedAt
|
||||||
attachment.filename
|
: props.attachment.modifiedAt === null ? `przez ${props.attachment.createdBy}`
|
||||||
)}
|
: <>{props.attachment.createdAt}<br />przez {props.attachment.createdBy}</>}
|
||||||
</td>
|
</td>
|
||||||
<td className="p-1 border">{attachment.mediaType}</td>
|
<td className="p-1 border text-center">
|
||||||
<td className="p-1 border text-center font-mono text-sm">
|
<Button type="button" onClick={download}>
|
||||||
{attachment.createdAt}
|
Pobierz
|
||||||
{attachment.createdBy !== null && <><br />przez {attachment.createdBy}</>}
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td className="p-1 border text-center font-mono text-sm">
|
</tr>
|
||||||
{attachment.modifiedAt === null && attachment.modifiedBy === null ? "\u2014"
|
|
||||||
: attachment.modifiedAt !== null && attachment.modifiedBy === null ? attachment.modifiedAt
|
|
||||||
: attachment.modifiedAt === null ? `przez ${attachment.createdBy}`
|
|
||||||
: <>{attachment.createdAt}<br />przez {attachment.createdBy}</>}
|
|
||||||
</td>
|
|
||||||
<td className="p-1 border text-center">
|
|
||||||
<Button type="button" onClick={download(attachment.attachmentId)}>
|
|
||||||
Pobierz
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user