Compare commits

...
Author SHA1 Message Date
David Nguyen e8796a7d86 refactor: organise recipient utils 2023-09-12 12:33:04 +10:00
David Nguyen fbf32404a6 feat: add avatar email fallback 2023-09-11 16:58:41 +10:00
Lucas Smith 975d52a07e Merge pull request #362 from documenso/fix/hide-user-selection
fix: hide popover when user selects a recipient
2023-09-11 12:27:50 +10:00
Ephraim Atta-Duncan f8a193c0f8 refactor: replace whole implementation with a state 2023-09-09 10:56:45 +00:00
Ephraim Atta-Duncan 9186cb4d7b fix: hide popover when user selects a recipients 2023-09-09 10:42:03 +00:00
Mythie 933076fa3f fix: update devcontainer 2023-09-09 15:49:40 +10:00
Mythie abc91f7eac fix: update devcontainer 2023-09-09 15:44:10 +10:00
Mythie 35acf05997 feat: add devcontainer 2023-09-09 04:38:37 +00:00
11 changed files with 75 additions and 26 deletions
+20
View File
@@ -0,0 +1,20 @@
{
"name": "Documenso",
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"enableNonRootDocker": "true",
"moby": "true"
},
"ghcr.io/devcontainers/features/node:1": {}
},
"onCreateCommand": "./.devcontainer/on-create.sh",
"forwardPorts": [
3000,
54320,
9000,
2500,
1100
]
}
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Start the database and mailserver
docker compose -f ./docker/compose-without-app.yml up -d
# Install dependencies
npm install
# Copy the env file
cp .env.example .env
# Source the env file, export the variables
set -a
source .env
set +a
# Run the migrations
npm run -w @documenso/prisma prisma:migrate-dev
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
npm run dev
@@ -15,7 +15,7 @@ export type StackAvatarProps = {
type: 'unsigned' | 'waiting' | 'opened' | 'completed'; type: 'unsigned' | 'waiting' | 'opened' | 'completed';
}; };
export const StackAvatar = ({ first, zIndex, fallbackText, type }: StackAvatarProps) => { export const StackAvatar = ({ first, zIndex, fallbackText = '', type }: StackAvatarProps) => {
let classes = ''; let classes = '';
let zIndexClass = ''; let zIndexClass = '';
const firstClass = first ? '' : '-ml-3'; const firstClass = first ? '' : '-ml-3';
@@ -48,7 +48,7 @@ export const StackAvatar = ({ first, zIndex, fallbackText, type }: StackAvatarPr
${firstClass} ${firstClass}
dark:border-border h-10 w-10 border-2 border-solid border-white`} dark:border-border h-10 w-10 border-2 border-solid border-white`}
> >
<AvatarFallback className={classes}>{fallbackText ?? 'UK'}</AvatarFallback> <AvatarFallback className={classes}>{fallbackText}</AvatarFallback>
</Avatar> </Avatar>
); );
}; };
@@ -1,5 +1,5 @@
import { initials } from '@documenso/lib/client-only/recipient-initials';
import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
import { Recipient } from '@documenso/prisma/client'; import { Recipient } from '@documenso/prisma/client';
import { import {
Tooltip, Tooltip,
@@ -56,7 +56,7 @@ export const StackAvatarsWithTooltip = ({
first={true} first={true}
key={recipient.id} key={recipient.id}
type={getRecipientType(recipient)} type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)} fallbackText={recipientAbbreviation(recipient)}
/> />
<span className="text-sm text-gray-500">{recipient.email}</span> <span className="text-sm text-gray-500">{recipient.email}</span>
</div> </div>
@@ -73,7 +73,7 @@ export const StackAvatarsWithTooltip = ({
first={true} first={true}
key={recipient.id} key={recipient.id}
type={getRecipientType(recipient)} type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)} fallbackText={recipientAbbreviation(recipient)}
/> />
<span className="text-sm text-gray-500">{recipient.email}</span> <span className="text-sm text-gray-500">{recipient.email}</span>
</div> </div>
@@ -90,7 +90,7 @@ export const StackAvatarsWithTooltip = ({
first={true} first={true}
key={recipient.id} key={recipient.id}
type={getRecipientType(recipient)} type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)} fallbackText={recipientAbbreviation(recipient)}
/> />
<span className="text-sm text-gray-500">{recipient.email}</span> <span className="text-sm text-gray-500">{recipient.email}</span>
</div> </div>
@@ -107,7 +107,7 @@ export const StackAvatarsWithTooltip = ({
first={true} first={true}
key={recipient.id} key={recipient.id}
type={getRecipientType(recipient)} type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)} fallbackText={recipientAbbreviation(recipient)}
/> />
<span className="text-sm text-gray-500">{recipient.email}</span> <span className="text-sm text-gray-500">{recipient.email}</span>
</div> </div>
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { initials } from '@documenso/lib/client-only/recipient-initials';
import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
import { Recipient } from '@documenso/prisma/client'; import { Recipient } from '@documenso/prisma/client';
import { StackAvatar } from './stack-avatar'; import { StackAvatar } from './stack-avatar';
@@ -26,7 +26,7 @@ export function StackAvatars({ recipients }: { recipients: Recipient[] }) {
first={first} first={first}
zIndex={String(zIndex - index * 10)} zIndex={String(zIndex - index * 10)}
type={lastItemText && index === 4 ? 'unsigned' : getRecipientType(recipient)} type={lastItemText && index === 4 ? 'unsigned' : getRecipientType(recipient)}
fallbackText={lastItemText ? lastItemText : initials(recipient.name)} fallbackText={lastItemText ? lastItemText : recipientAbbreviation(recipient)}
/> />
); );
}); });
@@ -15,6 +15,7 @@ import {
import { signOut } from 'next-auth/react'; import { signOut } from 'next-auth/react';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { recipientInitials } from '@documenso/lib/utils/recipient-formatter';
import { User } from '@documenso/prisma/client'; import { User } from '@documenso/prisma/client';
import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar'; import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
@@ -40,19 +41,16 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => {
const isBillingEnabled = getFlag('app_billing'); const isBillingEnabled = getFlag('app_billing');
const initials = const avatarFallback = user.name
user.name ? recipientInitials(user.name)
?.split(' ') : user.email.slice(0, 1).toUpperCase();
.map((name: string) => name.slice(0, 1).toUpperCase())
.slice(0, 2)
.join('') ?? 'UK';
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-10 w-10 rounded-full"> <Button variant="ghost" className="relative h-10 w-10 rounded-full">
<Avatar className="h-10 w-10"> <Avatar className="h-10 w-10">
<AvatarFallback>{initials}</AvatarFallback> <AvatarFallback>{avatarFallback}</AvatarFallback>
</Avatar> </Avatar>
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
+1 -1
View File
@@ -2,7 +2,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"build": "turbo run build", "build": "turbo run build",
"dev": "turbo run dev --filter=@documenso/{web,marketing}", "dev": "turbo run dev --filter=@documenso/web --filter=@documenso/marketing",
"start": "cd apps && cd web && next start", "start": "cd apps && cd web && next start",
"lint": "turbo run lint", "lint": "turbo run lint",
"format": "prettier --write \"**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts,mdx}\"", "format": "prettier --write \"**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts,mdx}\"",
@@ -1,6 +0,0 @@
export const initials = (text: string) =>
text
?.split(' ')
.map((name: string) => name.slice(0, 1).toUpperCase())
.slice(0, 2)
.join('') ?? 'UK';
+12
View File
@@ -0,0 +1,12 @@
import { Recipient } from '@documenso/prisma/client';
export const recipientInitials = (text: string) =>
text
.split(' ')
.map((name: string) => name.slice(0, 1).toUpperCase())
.slice(0, 2)
.join('');
export const recipientAbbreviation = (recipient: Recipient) => {
return recipientInitials(recipient.name) || recipient.email.slice(0, 1).toUpperCase();
};
@@ -102,6 +102,7 @@ export const AddFieldsFormPartial = ({
const [selectedField, setSelectedField] = useState<FieldType | null>(null); const [selectedField, setSelectedField] = useState<FieldType | null>(null);
const [selectedSigner, setSelectedSigner] = useState<Recipient | null>(null); const [selectedSigner, setSelectedSigner] = useState<Recipient | null>(null);
const [showRecipientsSelector, setShowRecipientsSelector] = useState(false);
const hasSelectedSignerBeenSent = selectedSigner?.sendStatus === SendStatus.SENT; const hasSelectedSignerBeenSent = selectedSigner?.sendStatus === SendStatus.SENT;
@@ -314,7 +315,7 @@ export const AddFieldsFormPartial = ({
))} ))}
{!hideRecipients && ( {!hideRecipients && (
<Popover> <Popover open={showRecipientsSelector} onOpenChange={setShowRecipientsSelector}>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
type="button" type="button"
@@ -324,7 +325,7 @@ export const AddFieldsFormPartial = ({
> >
{selectedSigner?.email && ( {selectedSigner?.email && (
<span className="flex-1 truncate text-left"> <span className="flex-1 truncate text-left">
{selectedSigner?.email} ({selectedSigner?.email}) {selectedSigner?.name} ({selectedSigner?.email})
</span> </span>
)} )}
@@ -348,7 +349,10 @@ export const AddFieldsFormPartial = ({
className={cn({ className={cn({
'text-muted-foreground': recipient.sendStatus === SendStatus.SENT, 'text-muted-foreground': recipient.sendStatus === SendStatus.SENT,
})} })}
onSelect={() => setSelectedSigner(recipient)} onSelect={() => {
setSelectedSigner(recipient);
setShowRecipientsSelector(false);
}}
> >
{recipient.sendStatus !== SendStatus.SENT ? ( {recipient.sendStatus !== SendStatus.SENT ? (
<Check <Check