fix: trimmed long file names for better UX (#760)

Fixes #755 

### Notes for Reviewers
- The max length of the title is set to be `16`
- If the length of the title is <16 it returns the original one.
- Or else the title will be the first 8 characters (start) and last 8
characters (end)
- The truncated file name will look like `start...end`

### Screenshot for reference


![image](https://github.com/documenso/documenso/assets/88539464/565e4868-7bb1-4b46-9cb0-886d542b8a01)

---------

Co-authored-by: Catalin Pit <25515812+catalinpit@users.noreply.github.com>
This commit is contained in:
Mohith Gadireddy
2023-12-29 15:48:19 +05:30
committed by GitHub
parent 8f5634268d
commit 341481d6db
4 changed files with 25 additions and 5 deletions

View File

@ -15,6 +15,8 @@ import { DocumentDownloadButton } from '@documenso/ui/components/document/docume
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button'; import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
import { SigningCard3D } from '@documenso/ui/components/signing-card'; import { SigningCard3D } from '@documenso/ui/components/signing-card';
import { truncateTitle } from '~/helpers/truncate-title';
export type CompletedSigningPageProps = { export type CompletedSigningPageProps = {
params: { params: {
token?: string; token?: string;
@ -36,6 +38,8 @@ export default async function CompletedSigningPage({
return notFound(); return notFound();
} }
const truncatedTitle = truncateTitle(document.title);
const { documentData } = document; const { documentData } = document;
const [fields, recipient] = await Promise.all([ const [fields, recipient] = await Promise.all([
@ -89,7 +93,7 @@ export default async function CompletedSigningPage({
<h2 className="mt-6 max-w-[35ch] text-center text-2xl font-semibold leading-normal md:text-3xl lg:text-4xl"> <h2 className="mt-6 max-w-[35ch] text-center text-2xl font-semibold leading-normal md:text-3xl lg:text-4xl">
You have signed You have signed
<span className="mt-1.5 block">"{document.title}"</span> <span className="mt-1.5 block">"{truncatedTitle}"</span>
</h2> </h2>
{match({ status: document.status, deletedAt: document.deletedAt }) {match({ status: document.status, deletedAt: document.deletedAt })

View File

@ -17,6 +17,8 @@ import { Card, CardContent } from '@documenso/ui/primitives/card';
import { ElementVisible } from '@documenso/ui/primitives/element-visible'; import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer'; import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
import { truncateTitle } from '~/helpers/truncate-title';
import { DateField } from './date-field'; import { DateField } from './date-field';
import { EmailField } from './email-field'; import { EmailField } from './email-field';
import { SigningForm } from './form'; import { SigningForm } from './form';
@ -51,6 +53,8 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
return notFound(); return notFound();
} }
const truncatedTitle = truncateTitle(document.title);
const { documentData } = document; const { documentData } = document;
const { user } = await getServerComponentSession(); const { user } = await getServerComponentSession();
@ -82,7 +86,7 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
> >
<div className="mx-auto w-full max-w-screen-xl"> <div className="mx-auto w-full max-w-screen-xl">
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}> <h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title} {truncatedTitle}
</h1> </h1>
<div className="mt-2.5 flex items-center gap-x-6"> <div className="mt-2.5 flex items-center gap-x-6">

View File

@ -1,6 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { Document, Field } from '@documenso/prisma/client'; import type { Document, Field } from '@documenso/prisma/client';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { import {
Dialog, Dialog,
@ -9,6 +9,8 @@ import {
DialogTrigger, DialogTrigger,
} from '@documenso/ui/primitives/dialog'; } from '@documenso/ui/primitives/dialog';
import { truncateTitle } from '~/helpers/truncate-title';
export type SignDialogProps = { export type SignDialogProps = {
isSubmitting: boolean; isSubmitting: boolean;
document: Document; document: Document;
@ -23,7 +25,7 @@ export const SignDialog = ({
onSignatureComplete, onSignatureComplete,
}: SignDialogProps) => { }: SignDialogProps) => {
const [showDialog, setShowDialog] = useState(false); const [showDialog, setShowDialog] = useState(false);
const truncatedTitle = truncateTitle(document.title);
const isComplete = fields.every((field) => field.inserted); const isComplete = fields.every((field) => field.inserted);
return ( return (
@ -43,7 +45,7 @@ export const SignDialog = ({
<div className="text-center"> <div className="text-center">
<div className="text-xl font-semibold text-neutral-800">Sign Document</div> <div className="text-xl font-semibold text-neutral-800">Sign Document</div>
<div className="text-muted-foreground mx-auto w-4/5 py-2 text-center"> <div className="text-muted-foreground mx-auto w-4/5 py-2 text-center">
You are about to finish signing "{document.title}". Are you sure? You are about to finish signing "{truncatedTitle}". Are you sure?
</div> </div>
</div> </div>

View File

@ -0,0 +1,10 @@
export const truncateTitle = (title: string, maxLength: number = 16) => {
if (title.length <= maxLength) {
return title;
}
const start = title.slice(0, maxLength / 2);
const end = title.slice(-maxLength / 2);
return `${start}.....${end}`;
};