mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 16:39:02 +01:00
chore(react/type_widget): port attachment detail
This commit is contained in:
parent
3171413a18
commit
ae1954c320
@ -18,7 +18,7 @@ import Image from "./type_widgets/Image";
|
||||
import { ReadOnlyCode, EditableCode } from "./type_widgets/code/Code";
|
||||
import Mermaid from "./type_widgets/Mermaid";
|
||||
import MindMap from "./type_widgets/MindMap";
|
||||
import { AttachmentList } from "./type_widgets/Attachment";
|
||||
import { AttachmentDetail, AttachmentList } from "./type_widgets/Attachment";
|
||||
|
||||
/**
|
||||
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
|
||||
@ -100,6 +100,7 @@ function getCorrespondingWidget(noteType: ExtendedNoteType | undefined, props: T
|
||||
case "mermaid": return <Mermaid {...props} />
|
||||
case "mindMap": return <MindMap {...props} />
|
||||
case "attachmentList": return <AttachmentList {...props} />
|
||||
case "attachmentDetail": return <AttachmentDetail {...props} />
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,16 +95,4 @@ export default class AttachmentDetailWidget extends BasicWidget {
|
||||
throw new Error(t("attachment_detail_2.unrecognized_role", { role: this.attachment.role }));
|
||||
}
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||
const attachmentRow = loadResults.getAttachmentRows().find((att) => att.attachmentId === this.attachment.attachmentId);
|
||||
|
||||
if (attachmentRow) {
|
||||
if (attachmentRow.isDeleted) {
|
||||
this.toggleInt(false);
|
||||
} else {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region Attachment detail */
|
||||
/* #region Attachment info */
|
||||
.attachment-detail-widget {
|
||||
height: 100%;
|
||||
}
|
||||
@ -82,4 +82,23 @@
|
||||
.attachment-detail-wrapper.scheduled-for-deletion .attachment-content-wrapper img {
|
||||
filter: contrast(10%);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region Attachment detail */
|
||||
.attachment-detail {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.attachment-detail .links-wrapper {
|
||||
font-size: larger;
|
||||
padding: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.attachment-detail .attachment-wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
/* #endregion */
|
||||
@ -11,7 +11,11 @@ import Alert from "../react/Alert";
|
||||
import utils from "../../services/utils";
|
||||
import content_renderer from "../../services/content_renderer";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import froca from "../../services/froca";
|
||||
|
||||
/**
|
||||
* Displays the full list of attachments of a note and allows the user to interact with them.
|
||||
*/
|
||||
export function AttachmentList({ note }: TypeWidgetProps) {
|
||||
const [ attachments, setAttachments ] = useState<FAttachment[]>([]);
|
||||
|
||||
@ -33,7 +37,7 @@ export function AttachmentList({ note }: TypeWidgetProps) {
|
||||
|
||||
<div className="attachment-list-wrapper">
|
||||
{attachments.length ? (
|
||||
attachments.map(attachment => <AttachmentDetail key={attachment.attachmentId} attachment={attachment} />)
|
||||
attachments.map(attachment => <AttachmentInfo key={attachment.attachmentId} attachment={attachment} />)
|
||||
) : (
|
||||
<Alert type="info">
|
||||
{t("attachment_list.no_attachments")}
|
||||
@ -69,7 +73,46 @@ function AttachmentListHeader({ noteId }: { noteId: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
function AttachmentDetail({ attachment, isFullDetail }: { attachment: FAttachment, isFullDetail?: boolean }) {
|
||||
/**
|
||||
* Displays information about a single attachment.
|
||||
*/
|
||||
export function AttachmentDetail({ note, viewScope }: TypeWidgetProps) {
|
||||
const [ attachment, setAttachment ] = useState<FAttachment | null | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (!viewScope?.attachmentId) return;
|
||||
froca.getAttachment(viewScope.attachmentId).then(setAttachment);
|
||||
}, [ viewScope ]);
|
||||
|
||||
return (
|
||||
<div className="attachment-detail note-detail-printable">
|
||||
<div className="links-wrapper use-tn-links">
|
||||
{t("attachment_detail.owning_note")}{" "}
|
||||
<NoteLink notePath={note.noteId} />
|
||||
{t("attachment_detail.you_can_also_open")}{" "}
|
||||
<NoteLink
|
||||
notePath={note.noteId}
|
||||
viewScope={{ viewMode: "attachments" }}
|
||||
title={t("attachment_detail.list_of_all_attachments")}
|
||||
/>
|
||||
<HelpButton
|
||||
helpPage="0vhv7lsOLy82"
|
||||
title={t("attachment_list.open_help_page")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="attachment-wrapper">
|
||||
{attachment !== null ? (
|
||||
attachment && <AttachmentInfo attachment={attachment} isFullDetail />
|
||||
) : (
|
||||
<strong>{t("attachment_detail.attachment_deleted")}</strong>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function AttachmentInfo({ attachment, isFullDetail }: { attachment: FAttachment, isFullDetail?: boolean }) {
|
||||
const contentWrapper = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import AttachmentDetailWidget from "../attachment_detail.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="attachment-detail note-detail-printable">
|
||||
<style>
|
||||
.attachment-detail {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.attachment-detail .links-wrapper {
|
||||
font-size: larger;
|
||||
padding: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.attachment-detail .attachment-wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="links-wrapper use-tn-links"></div>
|
||||
|
||||
<div class="attachment-wrapper"></div>
|
||||
</div>`;
|
||||
|
||||
export default class AttachmentDetailTypeWidget extends TypeWidget {
|
||||
$wrapper!: JQuery<HTMLElement>;
|
||||
$linksWrapper!: JQuery<HTMLElement>;
|
||||
|
||||
static getType() {
|
||||
return "attachmentDetail";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$wrapper = this.$widget.find(".attachment-wrapper");
|
||||
this.$linksWrapper = this.$widget.find(".links-wrapper");
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note: Parameters<TypeWidget["doRefresh"]>[0]) {
|
||||
this.$wrapper.empty();
|
||||
this.children = [];
|
||||
|
||||
const $helpButton = $(`
|
||||
<button class="attachment-help-button icon-action bx bx-help-circle"
|
||||
type="button" data-help-page="attachments.html"
|
||||
title="${t("attachment_detail.open_help_page")}"
|
||||
</button>
|
||||
`);
|
||||
utils.initHelpButtons($helpButton);
|
||||
|
||||
this.$linksWrapper.empty().append(
|
||||
t("attachment_detail.owning_note"),
|
||||
await linkService.createLink(this.noteId),
|
||||
t("attachment_detail.you_can_also_open"),
|
||||
await linkService.createLink(this.noteId, {
|
||||
title: t("attachment_detail.list_of_all_attachments"),
|
||||
viewScope: {
|
||||
viewMode: "attachments"
|
||||
}
|
||||
}),
|
||||
$helpButton
|
||||
);
|
||||
|
||||
const attachment = this.attachmentId ? await froca.getAttachment(this.attachmentId, true) : null;
|
||||
|
||||
if (!attachment) {
|
||||
this.$wrapper.html("<strong>" + t("attachment_detail.attachment_deleted") + "</strong>");
|
||||
return;
|
||||
}
|
||||
|
||||
const attachmentDetailWidget = new AttachmentDetailWidget(attachment, true);
|
||||
this.child(attachmentDetailWidget);
|
||||
|
||||
this.$wrapper.append(attachmentDetailWidget.render());
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||
const attachmentRow = loadResults.getAttachmentRows().find((att) => att.attachmentId === this.attachmentId);
|
||||
|
||||
if (attachmentRow?.isDeleted) {
|
||||
this.refresh(); // all other updates are handled within AttachmentDetailWidget
|
||||
}
|
||||
}
|
||||
|
||||
get attachmentId() {
|
||||
return this?.noteContext?.viewScope?.attachmentId;
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import AttachmentDetailWidget from "../attachment_detail.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
`;
|
||||
|
||||
export default class AttachmentListTypeWidget extends TypeWidget {
|
||||
$list!: JQuery<HTMLElement>;
|
||||
$linksWrapper!: JQuery<HTMLElement>;
|
||||
renderedAttachmentIds!: Set<string>;
|
||||
|
||||
static getType() {
|
||||
return "attachmentList";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$list = this.$widget.find(".attachment-list-wrapper");
|
||||
this.$linksWrapper = this.$widget.find(".links-wrapper");
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note: Parameters<TypeWidget["doRefresh"]>[0]) {
|
||||
this.$list.empty();
|
||||
this.children = [];
|
||||
this.renderedAttachmentIds = new Set();
|
||||
|
||||
const attachments = await note.getAttachments();
|
||||
|
||||
for (const attachment of attachments) {
|
||||
const attachmentDetailWidget = new AttachmentDetailWidget(attachment, false);
|
||||
|
||||
this.child(attachmentDetailWidget);
|
||||
|
||||
this.renderedAttachmentIds.add(attachment.attachmentId);
|
||||
|
||||
this.$list.append(attachmentDetailWidget.render());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user