mirror of
https://github.com/documenso/documenso.git
synced 2026-07-26 01:45:08 +10:00
fix: resolve follow-up issues from oxlint migration
This commit is contained in:
@@ -39,7 +39,7 @@ export function useAnalytics() {
|
||||
*
|
||||
* @param eventFlag The event to check against feature flags to determine whether tracking is enabled.
|
||||
*/
|
||||
const startSessionRecording = (eventFlag?: string) => {
|
||||
const startSessionRecording = (_eventFlag?: string) => {
|
||||
return;
|
||||
// const isSessionRecordingEnabled = featureFlags.getFlag(FEATURE_FLAG_GLOBAL_SESSION_RECORDING);
|
||||
// const isSessionRecordingEnabledForEvent = Boolean(eventFlag && featureFlags.getFlag(eventFlag));
|
||||
|
||||
@@ -40,7 +40,7 @@ export function useCopyShareLink({ onSuccess, onError }: UseCopyShareLinkOptions
|
||||
}
|
||||
|
||||
onSuccess?.();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
onError?.();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,13 +14,16 @@ export function useCopyToClipboard(): [CopiedValue, CopyFn] {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isClipboardApiSupported = Boolean(typeof ClipboardItem && navigator.clipboard.write);
|
||||
const isClipboardApiSupported =
|
||||
typeof ClipboardItem !== 'undefined' && typeof navigator.clipboard.write === 'function';
|
||||
|
||||
// Try to save to clipboard then save it in the state if worked
|
||||
try {
|
||||
isClipboardApiSupported
|
||||
? await handleClipboardApiCopy(text, blobType)
|
||||
: await handleWriteTextCopy(text);
|
||||
if (isClipboardApiSupported) {
|
||||
await handleClipboardApiCopy(text, blobType);
|
||||
} else {
|
||||
await handleWriteTextCopy(text);
|
||||
}
|
||||
|
||||
setCopiedText(await text);
|
||||
return true;
|
||||
@@ -41,7 +44,7 @@ export function useCopyToClipboard(): [CopiedValue, CopyFn] {
|
||||
const handleClipboardApiCopy = async (value: CopyValue, blobType = 'text/plain') => {
|
||||
try {
|
||||
await navigator.clipboard.write([new ClipboardItem({ [blobType]: value })]);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Fallback attempt.
|
||||
await handleWriteTextCopy(value);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ export const useEditorFields = ({
|
||||
|
||||
const getFieldByFormId = useCallback(
|
||||
(formId: string): TLocalField | undefined => {
|
||||
return localFields.find((field) => field.formId === formId) as TLocalField | undefined;
|
||||
return localFields.find((field) => field.formId === formId);
|
||||
},
|
||||
[localFields],
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
||||
import { RefObject, useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
/**
|
||||
* Calculate the width and height of a text element.
|
||||
|
||||
@@ -276,7 +276,7 @@ export const EnvelopeEditorProvider = ({
|
||||
[envelope.recipients],
|
||||
);
|
||||
|
||||
const { refetch: reloadEnvelope, isLoading: isReloadingEnvelope } = trpc.envelope.get.useQuery(
|
||||
const { refetch: reloadEnvelope, isLoading: _isReloadingEnvelope } = trpc.envelope.get.useQuery(
|
||||
{
|
||||
envelopeId: envelope.id,
|
||||
},
|
||||
|
||||
@@ -189,7 +189,7 @@ export const EnvelopeRenderProvider = ({
|
||||
}, [envelope.envelopeItems]);
|
||||
|
||||
const recipientIds = useMemo(
|
||||
() => recipients.map((recipient) => recipient.id).sort(),
|
||||
() => recipients.map((recipient) => recipient.id).sort((left, right) => left - right),
|
||||
[recipients],
|
||||
);
|
||||
|
||||
|
||||
@@ -170,5 +170,8 @@ export const convertToLocalSystemFormat = (
|
||||
};
|
||||
|
||||
export const isValidDateFormat = (dateFormat: unknown): dateFormat is ValidDateFormat => {
|
||||
return VALID_DATE_FORMAT_VALUES.includes(dateFormat as ValidDateFormat);
|
||||
return (
|
||||
typeof dateFormat === 'string' &&
|
||||
VALID_DATE_FORMAT_VALUES.some((validDateFormat) => validDateFormat === dateFormat)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,4 +73,5 @@ export const SUPPORTED_LANGUAGES: Record<string, SupportedLanguage> = {
|
||||
} satisfies Record<SupportedLanguageCodes, SupportedLanguage>;
|
||||
|
||||
export const isValidLanguageCode = (code: unknown): code is SupportedLanguageCodes =>
|
||||
SUPPORTED_LANGUAGE_CODES.includes(code as SupportedLanguageCodes);
|
||||
typeof code === 'string' &&
|
||||
SUPPORTED_LANGUAGE_CODES.some((languageCode) => languageCode === code);
|
||||
|
||||
@@ -91,11 +91,11 @@ export class InngestJobProvider extends BaseJobProvider {
|
||||
return {
|
||||
wait: step.sleep,
|
||||
logger: {
|
||||
info: ctx.logger.info,
|
||||
debug: ctx.logger.debug,
|
||||
error: ctx.logger.error,
|
||||
warn: ctx.logger.warn,
|
||||
log: ctx.logger.info,
|
||||
info: (...args) => ctx.logger.info(...args),
|
||||
debug: (...args) => ctx.logger.debug(...args),
|
||||
error: (...args) => ctx.logger.error(...args),
|
||||
warn: (...args) => ctx.logger.warn(...args),
|
||||
log: (...args) => ctx.logger.info(...args),
|
||||
},
|
||||
runTask: async (cacheKey, callback) => {
|
||||
const result = await step.run(cacheKey, callback);
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { TExecuteWebhookJobDefinition } from './execute-webhook';
|
||||
|
||||
export const run = async ({
|
||||
payload,
|
||||
io,
|
||||
io: _io,
|
||||
}: {
|
||||
payload: TExecuteWebhookJobDefinition;
|
||||
io: JobRunIO;
|
||||
@@ -28,10 +28,11 @@ export const run = async ({
|
||||
createdAt: new Date().toISOString(),
|
||||
webhookEndpoint: url,
|
||||
};
|
||||
const requestBody: Prisma.InputJsonValue = JSON.parse(JSON.stringify(payloadData));
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payloadData),
|
||||
body: JSON.stringify(requestBody),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Documenso-Secret': secret ?? '',
|
||||
@@ -44,7 +45,7 @@ export const run = async ({
|
||||
|
||||
try {
|
||||
responseBody = JSON.parse(body);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
responseBody = body;
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ export const run = async ({
|
||||
url,
|
||||
event,
|
||||
status: response.ok ? WebhookCallStatus.SUCCESS : WebhookCallStatus.FAILED,
|
||||
requestBody: payloadData as Prisma.InputJsonValue,
|
||||
requestBody,
|
||||
responseCode: response.status,
|
||||
responseBody,
|
||||
responseHeaders: Object.fromEntries(response.headers.entries()),
|
||||
|
||||
@@ -91,9 +91,13 @@ export const adminFindUnsealedDocuments = async ({
|
||||
]);
|
||||
|
||||
const count = Number(countResult[0]?.count ?? 0);
|
||||
const formattedData: AdminUnsealedDocument[] = data.map((document) => ({
|
||||
...document,
|
||||
id: String(document.id),
|
||||
}));
|
||||
|
||||
return {
|
||||
data: data as unknown as AdminUnsealedDocument[],
|
||||
data: formattedData,
|
||||
count,
|
||||
currentPage: Math.max(page, 1),
|
||||
perPage,
|
||||
|
||||
@@ -32,7 +32,7 @@ export type TeamInsights = {
|
||||
|
||||
export type UserInsights = {
|
||||
id: number;
|
||||
name: string;
|
||||
name: string | null;
|
||||
email: string;
|
||||
documentCount: number;
|
||||
signedDocumentCount: number;
|
||||
@@ -98,7 +98,7 @@ export async function getOrganisationDetailedInsights({
|
||||
case 'documents':
|
||||
return await getDocumentInsights(organisationId, offset, perPage, createdAtFrom);
|
||||
default:
|
||||
throw new Error(`Invalid view: ${view}`);
|
||||
throw new Error('Invalid view');
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -149,9 +149,14 @@ async function getTeamInsights(
|
||||
|
||||
const [teams, countResult] = await Promise.all([teamsQuery.execute(), countQuery.execute()]);
|
||||
const count = Number(countResult[0]?.count || 0);
|
||||
const teamInsights: TeamInsights[] = teams.map((team) => ({
|
||||
...team,
|
||||
memberCount: Number(team.memberCount),
|
||||
documentCount: Number(team.documentCount),
|
||||
}));
|
||||
|
||||
return {
|
||||
teams: teams as TeamInsights[],
|
||||
teams: teamInsights,
|
||||
users: [],
|
||||
documents: [],
|
||||
totalPages: Math.ceil(Number(count) / perPage),
|
||||
@@ -208,10 +213,15 @@ async function getUserInsights(
|
||||
|
||||
const [users, countResult] = await Promise.all([usersQuery.execute(), countQuery.execute()]);
|
||||
const count = Number(countResult[0]?.count || 0);
|
||||
const userInsights: UserInsights[] = users.map((user) => ({
|
||||
...user,
|
||||
documentCount: Number(user.documentCount),
|
||||
signedDocumentCount: Number(user.signedDocumentCount),
|
||||
}));
|
||||
|
||||
return {
|
||||
teams: [],
|
||||
users: users as UserInsights[],
|
||||
users: userInsights,
|
||||
documents: [],
|
||||
totalPages: Math.ceil(Number(count) / perPage),
|
||||
};
|
||||
@@ -223,18 +233,13 @@ async function getDocumentInsights(
|
||||
perPage: number,
|
||||
createdAtFrom: Date | null,
|
||||
): Promise<OrganisationDetailedInsights> {
|
||||
let documentsQuery = kyselyPrisma.$kysely
|
||||
const documentsQuery = kyselyPrisma.$kysely
|
||||
.selectFrom('Envelope as e')
|
||||
.innerJoin('Team as t', 'e.teamId', 't.id')
|
||||
.where('t.organisationId', '=', organisationId)
|
||||
.where('e.deletedAt', 'is', null)
|
||||
.where(() => sql`e.type = ${EnvelopeType.DOCUMENT}::"EnvelopeType"`);
|
||||
|
||||
if (createdAtFrom) {
|
||||
documentsQuery = documentsQuery.where('e.createdAt', '>=', createdAtFrom);
|
||||
}
|
||||
|
||||
documentsQuery = documentsQuery
|
||||
.where(() => sql`e.type = ${EnvelopeType.DOCUMENT}::"EnvelopeType"`)
|
||||
.$if(!!createdAtFrom, (qb) => qb.where('e.createdAt', '>=', createdAtFrom!))
|
||||
.select([
|
||||
'e.id as id',
|
||||
'e.title as title',
|
||||
@@ -247,33 +252,33 @@ async function getDocumentInsights(
|
||||
.limit(perPage)
|
||||
.offset(offset);
|
||||
|
||||
let countQuery = kyselyPrisma.$kysely
|
||||
const countQuery = kyselyPrisma.$kysely
|
||||
.selectFrom('Envelope as e')
|
||||
.innerJoin('Team as t', 'e.teamId', 't.id')
|
||||
.where('t.organisationId', '=', organisationId)
|
||||
.where('e.deletedAt', 'is', null)
|
||||
.where(() => sql`e.type = ${EnvelopeType.DOCUMENT}::"EnvelopeType"`);
|
||||
|
||||
if (createdAtFrom) {
|
||||
countQuery = countQuery.where('e.createdAt', '>=', createdAtFrom);
|
||||
}
|
||||
|
||||
countQuery = countQuery.select(({ fn }) => [fn.countAll().as('count')]);
|
||||
.where(() => sql`e.type = ${EnvelopeType.DOCUMENT}::"EnvelopeType"`)
|
||||
.$if(!!createdAtFrom, (qb) => qb.where('e.createdAt', '>=', createdAtFrom!))
|
||||
.select(sql<number>`count(*)`.as('count'));
|
||||
|
||||
const [documents, countResult] = await Promise.all([
|
||||
documentsQuery.execute(),
|
||||
countQuery.execute(),
|
||||
countQuery.executeTakeFirst(),
|
||||
]);
|
||||
|
||||
const count = Number((countResult[0] as { count: number })?.count || 0);
|
||||
const count = Number(countResult?.count || 0);
|
||||
const documentInsights: DocumentInsights[] = documents.map((document) => ({
|
||||
title: document.title,
|
||||
status: document.status,
|
||||
createdAt: document.createdAt,
|
||||
completedAt: document.completedAt,
|
||||
teamName: document.teamName,
|
||||
id: String(document.id),
|
||||
}));
|
||||
|
||||
return {
|
||||
teams: [],
|
||||
users: [],
|
||||
documents: documents.map((doc) => ({
|
||||
...doc,
|
||||
id: String((doc as { id: number }).id),
|
||||
})) as DocumentInsights[],
|
||||
documents: documentInsights,
|
||||
totalPages: Math.ceil(Number(count) / perPage),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export type PdfToImagesOptions = {
|
||||
export const pdfToImages = async (pdfBytes: Uint8Array, options: PdfToImagesOptions = {}) => {
|
||||
const { scale = 2 } = options;
|
||||
|
||||
const task = await pdfjsLib.getDocument({
|
||||
const task = pdfjsLib.getDocument({
|
||||
data: pdfBytes,
|
||||
CanvasFactory: SkiaCanvasFactory,
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import { omit } from 'remeda';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { ZFieldMetaSchema } from '../../types/field-meta';
|
||||
import {
|
||||
ZWebhookDocumentSchema,
|
||||
mapEnvelopeToWebhookDocumentPayload,
|
||||
@@ -158,7 +159,7 @@ export const duplicateEnvelope = async ({ id, userId, teamId }: DuplicateEnvelop
|
||||
height: field.height,
|
||||
customText: '',
|
||||
inserted: false,
|
||||
fieldMeta: field.fieldMeta as PrismaJson.FieldMeta,
|
||||
fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined,
|
||||
})),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@ export type GetRecipientEnvelopeByTokenOptions = {
|
||||
export const getEnvelopeForDirectTemplateSigning = async ({
|
||||
token,
|
||||
userId,
|
||||
accessAuth,
|
||||
accessAuth: _accessAuth,
|
||||
}: GetRecipientEnvelopeByTokenOptions): Promise<EnvelopeForSigningResponse> => {
|
||||
if (!token) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
|
||||
@@ -193,12 +193,12 @@ export const updateEnvelope = async ({
|
||||
isDeepEqual(documentGlobalActionAuth, newGlobalActionAuth);
|
||||
const isDocumentVisibilitySame =
|
||||
data.visibility === undefined || data.visibility === envelope.visibility;
|
||||
const isFolderSame = data.folderId === undefined || data.folderId === envelope.folderId;
|
||||
const isTemplateTypeSame =
|
||||
const _isFolderSame = data.folderId === undefined || data.folderId === envelope.folderId;
|
||||
const _isTemplateTypeSame =
|
||||
data.templateType === undefined || data.templateType === envelope.templateType;
|
||||
const isPublicDescriptionSame =
|
||||
const _isPublicDescriptionSame =
|
||||
data.publicDescription === undefined || data.publicDescription === envelope.publicDescription;
|
||||
const isPublicTitleSame =
|
||||
const _isPublicTitleSame =
|
||||
data.publicTitle === undefined || data.publicTitle === envelope.publicTitle;
|
||||
|
||||
const auditLogs: CreateDocumentAuditLogDataResponse[] = [];
|
||||
|
||||
@@ -27,6 +27,7 @@ Konva.Util['createCanvasElement'] = () => {
|
||||
get: () => node,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return node as unknown as HTMLCanvasElement;
|
||||
};
|
||||
|
||||
@@ -34,6 +35,7 @@ Konva.Util.createImageElement = () => {
|
||||
const node = new Image();
|
||||
node.toString = () => '[object HTMLImageElement]';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return node as unknown as HTMLImageElement;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app';
|
||||
* Adds a rejection stamp to each page of a PDF document.
|
||||
* The stamp is placed in the center of the page.
|
||||
*/
|
||||
export async function addRejectionStampToPdf(pdf: PDF, reason: string): Promise<PDF> {
|
||||
export async function addRejectionStampToPdf(pdf: PDF, _reason: string): Promise<PDF> {
|
||||
const pages = pdf.getPages();
|
||||
|
||||
const fontBytes = await fetch(`${NEXT_PRIVATE_INTERNAL_WEBAPP_URL()}/fonts/noto-sans.ttf`).then(
|
||||
|
||||
@@ -694,10 +694,10 @@ const setTextFieldFontSize = (textField: PDFTextField, font: PDFFont, fontSize:
|
||||
|
||||
try {
|
||||
textField.setFontSize(fontSize);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
let da = textField.acroField.getDefaultAppearance() ?? '';
|
||||
|
||||
da += `\n ${setFontAndSize(font.name, fontSize)}`;
|
||||
da += `\n ${String(setFontAndSize(font.name, fontSize))}`;
|
||||
|
||||
textField.acroField.setDefaultAppearance(da);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ const parser = new UAParser();
|
||||
const textMutedForegroundLight = '#929DAE';
|
||||
const textForeground = '#000';
|
||||
const textMutedForeground = '#64748B';
|
||||
const textBase = 10;
|
||||
const _textBase = 10;
|
||||
const textSm = 9;
|
||||
const textXs = 8;
|
||||
const fontMedium = '500';
|
||||
|
||||
@@ -75,13 +75,13 @@ const getDevice = (userAgent?: string | null): string => {
|
||||
return `${result.os.name} - ${result.browser.name} ${result.browser.version}`;
|
||||
};
|
||||
|
||||
const textMutedForegroundLight = '#929DAE';
|
||||
const textForeground = '#000';
|
||||
const _textMutedForegroundLight = '#929DAE';
|
||||
const _textForeground = '#000';
|
||||
const textMutedForeground = '#64748B';
|
||||
const textRejectedRed = '#dc2626';
|
||||
const textBase = 10;
|
||||
const textSm = 9;
|
||||
const textXs = 8;
|
||||
const _textXs = 8;
|
||||
const fontMedium = '500';
|
||||
|
||||
const columnWidthPercentages = [30, 30, 40];
|
||||
|
||||
@@ -33,7 +33,7 @@ export const setAvatarImage = async ({
|
||||
userId,
|
||||
target,
|
||||
bytes,
|
||||
requestMetadata,
|
||||
requestMetadata: _requestMetadata,
|
||||
}: SetAvatarImageOptions) => {
|
||||
let oldAvatarImageId: string | null = null;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export const testCredentialsHandler = async (req: Request) => {
|
||||
return Response.json({
|
||||
name: result.team?.name ?? result.user.name,
|
||||
});
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return Response.json(
|
||||
{
|
||||
message: 'Internal Server Error',
|
||||
|
||||
@@ -99,7 +99,7 @@ export const deleteTeamEmail = async ({ userId, userEmail, teamId }: DeleteTeamE
|
||||
html,
|
||||
text,
|
||||
});
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Todo: Teams - Alert us.
|
||||
// We don't want to prevent a user from revoking access because an email could not be sent.
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const deletedServiceAccountEmail = () => {
|
||||
const { hostname } = new URL(process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000');
|
||||
|
||||
return `deleted-account@${hostname}`;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return LEGACY_DELETED_ACCOUNT_EMAIL;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ export const legacyServiceAccountEmail = () => {
|
||||
const { hostname } = new URL(process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000');
|
||||
|
||||
return `serviceaccount@${hostname}`;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
return LEGACY_SERVICE_ACCOUNT_EMAIL;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -545,5 +545,5 @@ export const generateSampleWebhookPayload = (
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported event type: ${event}`);
|
||||
throw new Error('Unsupported event type');
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ export const validateApiToken = async ({ authorization }: ValidateApiTokenOption
|
||||
}
|
||||
|
||||
return await getApiTokenByToken({ token });
|
||||
} catch (err) {
|
||||
} catch {
|
||||
throw new Error(`Failed to validate API token`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -418,5 +418,3 @@ export const ZEnvelopeFieldAndMetaSchema = z.discriminatedUnion('type', [
|
||||
fieldMeta: ZDropdownFieldMeta.optional().default(FIELD_DROPDOWN_META_DEFAULT_VALUES),
|
||||
}),
|
||||
]);
|
||||
|
||||
type TEnvelopeFieldAndMeta = z.infer<typeof ZEnvelopeFieldAndMetaSchema>;
|
||||
|
||||
@@ -11,7 +11,7 @@ export const MIN_FIELD_WIDTH_PX = 36;
|
||||
|
||||
export type FieldToRender = Pick<
|
||||
Field,
|
||||
'envelopeItemId' | 'recipientId' | 'type' | 'page' | 'customText' | 'inserted' | 'recipientId'
|
||||
'envelopeItemId' | 'recipientId' | 'type' | 'page' | 'customText' | 'inserted'
|
||||
> & {
|
||||
renderId: string; // A unique ID for the field in the render.
|
||||
width: number;
|
||||
|
||||
@@ -30,7 +30,8 @@ export const renderCheckboxFieldElement = (
|
||||
|
||||
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
|
||||
|
||||
const checkboxMeta: TCheckboxFieldMeta | null = (field.fieldMeta as TCheckboxFieldMeta) || null;
|
||||
const checkboxMeta: TCheckboxFieldMeta | null =
|
||||
field.fieldMeta?.type === 'checkbox' ? field.fieldMeta : null;
|
||||
const checkboxValues = checkboxMeta?.values || [];
|
||||
|
||||
const isFirstRender = !pageLayer.findOne(`#${field.renderId}`);
|
||||
@@ -131,6 +132,7 @@ export const renderCheckboxFieldElement = (
|
||||
});
|
||||
|
||||
const checkedValues: number[] = field.customText ? parseCheckboxCustomText(field.customText) : [];
|
||||
const isReadOnly = checkboxMeta?.readOnly ?? false;
|
||||
|
||||
checkboxValues.forEach(({ value, checked }, index) => {
|
||||
const isCheckboxChecked = match(mode)
|
||||
@@ -138,7 +140,7 @@ export const renderCheckboxFieldElement = (
|
||||
.with('sign', () => checkedValues.includes(index))
|
||||
.with('export', () => {
|
||||
// If it's read-only, check the originally checked state.
|
||||
if (checkboxMeta.readOnly) {
|
||||
if (isReadOnly) {
|
||||
return checked;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ export const renderDropdownFieldElement = (
|
||||
|
||||
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
|
||||
|
||||
const dropdownMeta: TDropdownFieldMeta | null = (field.fieldMeta as TDropdownFieldMeta) || null;
|
||||
const dropdownMeta: TDropdownFieldMeta | null =
|
||||
field.fieldMeta?.type === 'dropdown' ? field.fieldMeta : null;
|
||||
|
||||
let selectedValue = translations?.[FieldType.DROPDOWN] || 'Select Option';
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export type FieldRenderMode = 'edit' | 'sign' | 'export';
|
||||
|
||||
export type FieldToRender = Pick<
|
||||
Field,
|
||||
'envelopeItemId' | 'recipientId' | 'type' | 'page' | 'customText' | 'inserted' | 'recipientId'
|
||||
'envelopeItemId' | 'recipientId' | 'type' | 'page' | 'customText' | 'inserted'
|
||||
> & {
|
||||
renderId: string; // A unique ID for the field in the render.
|
||||
width: number;
|
||||
|
||||
@@ -20,12 +20,29 @@ import { calculateFieldPosition } from './field-renderer';
|
||||
|
||||
const DEFAULT_TEXT_X_PADDING = 6;
|
||||
|
||||
const getGenericTextFieldMeta = (field: FieldToRender): GenericTextFieldTypeMetas | undefined => {
|
||||
const fieldMeta = field.fieldMeta;
|
||||
|
||||
if (
|
||||
fieldMeta?.type === 'initials' ||
|
||||
fieldMeta?.type === 'name' ||
|
||||
fieldMeta?.type === 'email' ||
|
||||
fieldMeta?.type === 'date' ||
|
||||
fieldMeta?.type === 'text' ||
|
||||
fieldMeta?.type === 'number'
|
||||
) {
|
||||
return fieldMeta;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const upsertFieldText = (field: FieldToRender, options: RenderFieldElementOptions): Konva.Text => {
|
||||
const { pageWidth, pageHeight, mode = 'edit', pageLayer, translations } = options;
|
||||
|
||||
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
|
||||
|
||||
const fieldMeta = field.fieldMeta as GenericTextFieldTypeMetas | undefined;
|
||||
const fieldMeta = getGenericTextFieldMeta(field);
|
||||
|
||||
const fieldTypeName = translations?.[field.type] || field.type;
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ export const renderRadioFieldElement = (
|
||||
) => {
|
||||
const { pageWidth, pageHeight, pageLayer, mode, color } = options;
|
||||
|
||||
const radioMeta: TRadioFieldMeta | null = (field.fieldMeta as TRadioFieldMeta) || null;
|
||||
const radioMeta: TRadioFieldMeta | null =
|
||||
field.fieldMeta?.type === 'radio' ? field.fieldMeta : null;
|
||||
const radioValues = radioMeta?.values || [];
|
||||
|
||||
const isFirstRender = !pageLayer.findOne(`#${field.renderId}`);
|
||||
@@ -122,6 +123,7 @@ export const renderRadioFieldElement = (
|
||||
});
|
||||
|
||||
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
|
||||
const isReadOnly = radioMeta?.readOnly ?? false;
|
||||
|
||||
radioValues.forEach(({ value, checked }, index) => {
|
||||
const isRadioValueChecked = match(mode)
|
||||
@@ -129,7 +131,7 @@ export const renderRadioFieldElement = (
|
||||
.with('sign', () => index.toString() === field.customText)
|
||||
.with('export', () => {
|
||||
// If it's read-only, check the originally checked state.
|
||||
if (radioMeta.readOnly) {
|
||||
if (isReadOnly) {
|
||||
return checked;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export type GetFileOptions = {
|
||||
*
|
||||
* - Lucas, 2025-11-04
|
||||
*/
|
||||
const getFile = async ({ type, data }: GetFileOptions) => {
|
||||
const _getFile = async ({ type, data }: GetFileOptions) => {
|
||||
return await match(type)
|
||||
.with(DocumentDataType.BYTES, () => getFileFromBytes(data))
|
||||
.with(DocumentDataType.BYTES_64, () => getFileFromBytes64(data))
|
||||
|
||||
@@ -26,7 +26,7 @@ export const getEnvelopeItemPdfUrl = (options: EnvelopeItemPdfUrlOptions) => {
|
||||
const version = options.version;
|
||||
|
||||
return token
|
||||
? `${NEXT_PUBLIC_WEBAPP_URL()}/api/files/token/${token}/envelopeItem/${id}/download/${version}${presignToken ? `?presignToken=${presignToken}` : ''}`
|
||||
? `${NEXT_PUBLIC_WEBAPP_URL()}/api/files/token/${token}/envelopeItem/${id}/download/${version}`
|
||||
: `${NEXT_PUBLIC_WEBAPP_URL()}/api/files/envelope/${envelopeId}/envelopeItem/${id}/download/${version}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ export const validateFieldsUninserted = (): boolean => {
|
||||
const innerDiv = element.querySelector('div');
|
||||
const hasError = innerDiv?.getAttribute('data-error') === 'true';
|
||||
|
||||
if (hasError) {
|
||||
errorElements.push(element as HTMLElement);
|
||||
if (hasError && element instanceof HTMLElement) {
|
||||
errorElements.push(element);
|
||||
} else {
|
||||
element.removeAttribute('data-error');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user