refactor: consolidate thumbnail rendering onto UIRedesignStaging base
Apply useFileThumbnail + DocumentThumbnail to FileEditorThumbnail, rebased onto UIRedesignStaging. Also carry forward the FileEditorFileName truncation fix from main (#6310).
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import React from "react";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import FileEditorFileName from "@app/components/fileEditor/FileEditorFileName";
|
||||
import type { StirlingFileStub } from "@app/types/fileContext";
|
||||
import type { FileId } from "@app/types/file";
|
||||
|
||||
const buildFileStub = (
|
||||
overrides: Partial<StirlingFileStub> = {},
|
||||
): StirlingFileStub => ({
|
||||
id: "file-1" as FileId,
|
||||
name: "report.pdf",
|
||||
type: "application/pdf",
|
||||
size: 1024,
|
||||
lastModified: 0,
|
||||
isLeaf: true,
|
||||
originalFileId: "file-1",
|
||||
versionNumber: 1,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const renderName = (file: StirlingFileStub) =>
|
||||
render(
|
||||
<MantineProvider>
|
||||
<FileEditorFileName file={file} />
|
||||
</MantineProvider>,
|
||||
);
|
||||
|
||||
describe("FileEditorFileName (core / web)", () => {
|
||||
test.each([
|
||||
{ name: "not-saved", file: buildFileStub() },
|
||||
{
|
||||
name: "dirty",
|
||||
file: buildFileStub({ localFilePath: "/tmp/report.pdf", isDirty: true }),
|
||||
},
|
||||
{
|
||||
name: "saved",
|
||||
file: buildFileStub({ localFilePath: "/tmp/report.pdf", isDirty: false }),
|
||||
},
|
||||
])("does not render a save indicator ($name)", ({ file }) => {
|
||||
renderName(file);
|
||||
|
||||
expect(screen.queryByLabelText("fileNotSavedToDisk")).toBeNull();
|
||||
expect(screen.queryByLabelText("unsavedChanges")).toBeNull();
|
||||
expect(screen.queryByLabelText("fileSavedToDisk")).toBeNull();
|
||||
});
|
||||
|
||||
test("renders the filename", () => {
|
||||
renderName(buildFileStub({ name: "invoice.pdf" }));
|
||||
expect(screen.getByText("invoice.pdf")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,13 +1,18 @@
|
||||
import React from "react";
|
||||
import { StirlingFileStub } from "@app/types/fileContext";
|
||||
import { PrivateContent } from "@app/components/shared/PrivateContent";
|
||||
import { truncateCenter } from "@app/utils/textUtils";
|
||||
|
||||
interface FileEditorFileNameProps {
|
||||
file: StirlingFileStub;
|
||||
maxLength?: number;
|
||||
}
|
||||
|
||||
const FileEditorFileName = ({ file }: FileEditorFileNameProps) => (
|
||||
<PrivateContent>{file.name}</PrivateContent>
|
||||
const FileEditorFileName = ({
|
||||
file,
|
||||
maxLength = 40,
|
||||
}: FileEditorFileNameProps) => (
|
||||
<PrivateContent>{truncateCenter(file.name, maxLength)}</PrivateContent>
|
||||
);
|
||||
|
||||
export default FileEditorFileName;
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
||||
import { StirlingFileStub } from "@app/types/fileContext";
|
||||
import { zipFileService } from "@app/services/zipFileService";
|
||||
import { useFileThumbnail } from "@app/hooks/useFileThumbnail";
|
||||
|
||||
import styles from "@app/components/fileEditor/FileEditorThumbnail.module.css";
|
||||
import { useFileContext } from "@app/contexts/FileContext";
|
||||
@@ -43,6 +42,7 @@ import UploadToServerModal from "@app/components/shared/UploadToServerModal";
|
||||
import ShareFileModal from "@app/components/shared/ShareFileModal";
|
||||
import { useAppConfig } from "@app/contexts/AppConfigContext";
|
||||
import { truncateCenter } from "@app/utils/textUtils";
|
||||
import { useFileThumbnail } from "@app/hooks/useFileThumbnail";
|
||||
import DocumentThumbnail from "@app/components/shared/filePreview/DocumentThumbnail";
|
||||
|
||||
interface FileEditorThumbnailProps {
|
||||
@@ -86,11 +86,6 @@ const FileEditorThumbnail = ({
|
||||
} = useFileContext();
|
||||
const { state, selectors } = useFileState();
|
||||
const isMobile = useIsMobile();
|
||||
const {
|
||||
isEncrypted,
|
||||
thumbnail: displayThumbnail,
|
||||
isGenerating: isThumbGenerating,
|
||||
} = useFileThumbnail(file);
|
||||
|
||||
const actualFile = useMemo(
|
||||
() => activeFiles.find((f) => f.fileId === file.id),
|
||||
@@ -102,6 +97,11 @@ const FileEditorThumbnail = ({
|
||||
|
||||
const hasError = state.ui.errorFileIds.includes(file.id);
|
||||
const pageCount = file.processedFile?.totalPages || 0;
|
||||
const {
|
||||
isEncrypted,
|
||||
thumbnail: displayThumbnail,
|
||||
isGenerating: isThumbGenerating,
|
||||
} = useFileThumbnail(file);
|
||||
|
||||
// Aspect ratio from page dimensions, falling back to letter size
|
||||
const firstPage = file.processedFile?.pages?.[0];
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import React from "react";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import FileEditorFileName from "@app/components/fileEditor/FileEditorFileName";
|
||||
import type { StirlingFileStub } from "@app/types/fileContext";
|
||||
import type { FileId } from "@app/types/file";
|
||||
|
||||
const buildFileStub = (
|
||||
overrides: Partial<StirlingFileStub> = {},
|
||||
): StirlingFileStub => ({
|
||||
id: "file-1" as FileId,
|
||||
name: "report.pdf",
|
||||
type: "application/pdf",
|
||||
size: 1024,
|
||||
lastModified: 0,
|
||||
isLeaf: true,
|
||||
originalFileId: "file-1",
|
||||
versionNumber: 1,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const renderName = (file: StirlingFileStub) =>
|
||||
render(
|
||||
<MantineProvider>
|
||||
<FileEditorFileName file={file} />
|
||||
</MantineProvider>,
|
||||
);
|
||||
|
||||
describe("FileEditorFileName (desktop)", () => {
|
||||
test("renders red 'not saved' indicator when file has no local path", () => {
|
||||
renderName(buildFileStub());
|
||||
|
||||
const indicator = screen.getByLabelText("fileNotSavedToDisk");
|
||||
expect(indicator).toBeInTheDocument();
|
||||
expect(indicator).toHaveStyle({
|
||||
backgroundColor: "var(--mantine-color-red-6)",
|
||||
});
|
||||
expect(screen.queryByLabelText("unsavedChanges")).toBeNull();
|
||||
expect(screen.queryByLabelText("fileSavedToDisk")).toBeNull();
|
||||
});
|
||||
|
||||
test("renders yellow 'unsaved changes' indicator when file is dirty", () => {
|
||||
renderName(
|
||||
buildFileStub({ localFilePath: "/tmp/report.pdf", isDirty: true }),
|
||||
);
|
||||
|
||||
const indicator = screen.getByLabelText("unsavedChanges");
|
||||
expect(indicator).toBeInTheDocument();
|
||||
expect(indicator).toHaveStyle({
|
||||
backgroundColor: "var(--mantine-color-yellow-6)",
|
||||
});
|
||||
expect(screen.queryByLabelText("fileNotSavedToDisk")).toBeNull();
|
||||
expect(screen.queryByLabelText("fileSavedToDisk")).toBeNull();
|
||||
});
|
||||
|
||||
test("renders green 'saved' indicator when file is persisted and clean", () => {
|
||||
renderName(
|
||||
buildFileStub({ localFilePath: "/tmp/report.pdf", isDirty: false }),
|
||||
);
|
||||
|
||||
const indicator = screen.getByLabelText("fileSavedToDisk");
|
||||
expect(indicator).toBeInTheDocument();
|
||||
expect(indicator).toHaveStyle({
|
||||
backgroundColor: "var(--mantine-color-green-6)",
|
||||
});
|
||||
expect(screen.queryByLabelText("fileNotSavedToDisk")).toBeNull();
|
||||
expect(screen.queryByLabelText("unsavedChanges")).toBeNull();
|
||||
});
|
||||
|
||||
test("renders the filename alongside the indicator", () => {
|
||||
renderName(buildFileStub({ name: "invoice.pdf" }));
|
||||
expect(screen.getByText("invoice.pdf")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -3,17 +3,22 @@ import { Tooltip } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StirlingFileStub } from "@app/types/fileContext";
|
||||
import { PrivateContent } from "@app/components/shared/PrivateContent";
|
||||
import { truncateCenter } from "@app/utils/textUtils";
|
||||
|
||||
interface FileEditorFileNameProps {
|
||||
file: StirlingFileStub;
|
||||
maxLength?: number;
|
||||
}
|
||||
|
||||
const FileEditorFileName = ({ file }: FileEditorFileNameProps) => {
|
||||
const FileEditorFileName = ({
|
||||
file,
|
||||
maxLength = 40,
|
||||
}: FileEditorFileNameProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<PrivateContent>{file.name}</PrivateContent>
|
||||
<PrivateContent>{truncateCenter(file.name, maxLength)}</PrivateContent>
|
||||
{!file.localFilePath && (
|
||||
<Tooltip label={t("fileNotSavedToDisk", "Not saved to disk")}>
|
||||
<span
|
||||
|
||||
Reference in New Issue
Block a user