Support opening PDFs in a new tab

This commit is contained in:
2024-11-30 10:43:33 +01:00
parent 26bcfc684a
commit 2e3f90de19

View File

@@ -1,8 +1,8 @@
import type { Attachment, Piece } from "backend/database";
import { AttachmentId, PieceId } from "common";
import { PieceId } from "common";
import { ACCEPTED_EXTENSIONS } from "common/MediaType";
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 { client } from "../client";
import { FileReducer } from "../FileReducer";
@@ -125,11 +125,36 @@ namespace Attachments {
}
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
.piece({ pieceId: props.pieceId })
.attachment({ attachmentId })
.piece({ pieceId: props.attachment.pieceId })
.attachment({ attachmentId: props.attachment.attachmentId })
.get();
if (error !== null) {
@@ -144,52 +169,64 @@ function Attachments(props: Attachments.Props) {
a.download = data.filename;
a.click();
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 (
<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) => (
<tr key={attachment.attachmentId}>
<td className="p-1 border">
{attachment.mediaType === "application/vnd.recordare.musicxml"
|| attachment.mediaType === "application/vnd.recordare.musicxml+xml" ? (
<Link className="underline" to={`attachment/${attachment.attachmentId}`}>
{attachment.filename}
</Link>
) : (
attachment.filename
)}
</td>
<td className="p-1 border">{attachment.mediaType}</td>
<td className="p-1 border text-center font-mono text-sm">
{attachment.createdAt}
{attachment.createdBy !== null && <><br />przez {attachment.createdBy}</>}
</td>
<td className="p-1 border text-center font-mono text-sm">
{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>
<tr>
<td className="p-1 border">
{props.attachment.mediaType === "application/vnd.recordare.musicxml"
|| props.attachment.mediaType === "application/vnd.recordare.musicxml+xml"
|| props.attachment.mediaType === "application/pdf" ? (
<Link className="underline" to={`attachment/${props.attachment.attachmentId}`} onClick={onOpen}>
{props.attachment.filename}
</Link>
) : (
props.attachment.filename
)}
</td>
<td className="p-1 border">{props.attachment.mediaType}</td>
<td className="p-1 border text-center font-mono text-sm">
{props.attachment.createdAt}
{props.attachment.createdBy !== null && <><br />przez {props.attachment.createdBy}</>}
</td>
<td className="p-1 border text-center font-mono text-sm">
{props.attachment.modifiedAt === null && props.attachment.modifiedBy === null ? "\u2014"
: props.attachment.modifiedAt !== null && props.attachment.modifiedBy === null ? props.attachment.modifiedAt
: props.attachment.modifiedAt === null ? `przez ${props.attachment.createdBy}`
: <>{props.attachment.createdAt}<br />przez {props.attachment.createdBy}</>}
</td>
<td className="p-1 border text-center">
<Button type="button" onClick={download}>
Pobierz
</Button>
</td>
</tr>
);
}