Merge branch 'main' into feat/document-table-filters

This commit is contained in:
David Nguyen
2025-07-23 14:41:41 +10:00
committed by GitHub
82 changed files with 10660 additions and 528 deletions

View File

@ -206,8 +206,8 @@ export const AddSubjectFormPartial = ({
<p className="mt-2">
<Trans>
We will generate signing links for you, which you can send to the
recipients through your method of choice.
We will generate signing links for you, which you can send to the recipients
through your method of choice.
</Trans>
</p>
</div>

View File

@ -38,13 +38,8 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
const { type, fieldMeta } = field;
// Only render checkbox if values exist, otherwise render the empty checkbox field content.
if (
field.type === FieldType.CHECKBOX &&
field.fieldMeta?.type === 'checkbox' &&
field.fieldMeta.values &&
field.fieldMeta.values.length > 0
) {
// Render checkbox layout for checkbox fields, even if no values exist yet
if (field.type === FieldType.CHECKBOX && field.fieldMeta?.type === 'checkbox') {
let checkedValues: string[] = [];
try {
@ -55,8 +50,32 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
console.error(err);
}
// If no values exist yet, show a placeholder checkbox
if (!field.fieldMeta.values || field.fieldMeta.values.length === 0) {
return (
<div
className={cn(
'flex gap-1 py-0.5',
field.fieldMeta.direction === 'horizontal' ? 'flex-row flex-wrap' : 'flex-col gap-y-1',
)}
>
<div className="flex items-center">
<Checkbox className="h-3 w-3" disabled />
<Label className="text-foreground ml-1.5 text-xs font-normal opacity-50">
Checkbox option
</Label>
</div>
</div>
);
}
return (
<div className="flex flex-col gap-y-1 py-0.5">
<div
className={cn(
'flex gap-1 py-0.5',
field.fieldMeta.direction === 'horizontal' ? 'flex-row flex-wrap' : 'flex-col gap-y-1',
)}
>
{field.fieldMeta.values.map((item, index) => (
<div key={index} className="flex items-center">
<Checkbox

View File

@ -129,6 +129,7 @@ const getDefaultState = (fieldType: FieldType): FieldMeta => {
validationLength: 0,
required: false,
readOnly: false,
direction: 'vertical',
};
case FieldType.DROPDOWN:
return {

View File

@ -8,6 +8,7 @@ import { createPortal } from 'react-dom';
import { Rnd } from 'react-rnd';
import { useSearchParams } from 'react-router';
import { useElementBounds } from '@documenso/lib/client-only/hooks/use-element-bounds';
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta';
import { ZCheckboxFieldMeta, ZRadioFieldMeta } from '@documenso/lib/types/field-meta';
@ -81,7 +82,11 @@ export const FieldItem = ({
pageWidth: defaultWidth || 0,
});
const [settingsActive, setSettingsActive] = useState(false);
const $el = useRef(null);
const $el = useRef<HTMLDivElement>(null);
const $pageBounds = useElementBounds(
`${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.pageNumber}"]`,
);
const signerStyles = useRecipientColors(recipientIndex);
@ -233,9 +238,10 @@ export const FieldItem = ({
default={{
x: coords.pageX,
y: coords.pageY,
height: fixedSize ? '' : coords.pageHeight,
width: fixedSize ? '' : coords.pageWidth,
height: fixedSize ? 'auto' : coords.pageHeight,
width: fixedSize ? 'auto' : coords.pageWidth,
}}
maxWidth={fixedSize && $pageBounds?.width ? $pageBounds.width - coords.pageX : undefined}
bounds={`${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.pageNumber}"]`}
onDragStart={() => onFieldActivate?.()}
onResizeStart={() => onFieldActivate?.()}

View File

@ -44,6 +44,9 @@ export const CheckboxFieldAdvancedSettings = ({
const [required, setRequired] = useState(fieldState.required ?? false);
const [validationLength, setValidationLength] = useState(fieldState.validationLength ?? 0);
const [validationRule, setValidationRule] = useState(fieldState.validationRule ?? '');
const [direction, setDirection] = useState<'vertical' | 'horizontal'>(
fieldState.direction ?? 'vertical',
);
const handleToggleChange = (field: keyof CheckboxFieldMeta, value: string | boolean) => {
const readOnly = field === 'readOnly' ? Boolean(value) : Boolean(fieldState.readOnly);
@ -52,11 +55,14 @@ export const CheckboxFieldAdvancedSettings = ({
field === 'validationRule' ? String(value) : String(fieldState.validationRule);
const validationLength =
field === 'validationLength' ? Number(value) : Number(fieldState.validationLength);
const currentDirection =
field === 'direction' && String(value) === 'horizontal' ? 'horizontal' : 'vertical';
setReadOnly(readOnly);
setRequired(required);
setValidationRule(validationRule);
setValidationLength(validationLength);
setDirection(currentDirection);
const errors = validateCheckboxField(
values.map((item) => item.value),
@ -65,6 +71,7 @@ export const CheckboxFieldAdvancedSettings = ({
required,
validationRule,
validationLength,
direction: currentDirection,
type: 'checkbox',
},
);
@ -86,6 +93,7 @@ export const CheckboxFieldAdvancedSettings = ({
required,
validationRule,
validationLength,
direction: direction,
type: 'checkbox',
},
);
@ -137,6 +145,29 @@ export const CheckboxFieldAdvancedSettings = ({
onChange={(e) => handleFieldChange('label', e.target.value)}
/>
</div>
<div className="mb-2">
<Label>
<Trans>Direction</Trans>
</Label>
<Select
value={fieldState.direction ?? 'vertical'}
onValueChange={(val) => handleToggleChange('direction', val)}
>
<SelectTrigger className="text-muted-foreground bg-background mt-2 w-full">
<SelectValue placeholder={_(msg`Select direction`)} />
</SelectTrigger>
<SelectContent position="popper">
<SelectItem value="vertical">
<Trans>Vertical</Trans>
</SelectItem>
<SelectItem value="horizontal">
<Trans>Horizontal</Trans>
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex flex-row items-center gap-x-4">
<div className="flex w-2/3 flex-col">
<Label>