2024-08-06 17:53:55 +02:00
|
|
|
import {
|
|
|
|
AccessTime,
|
|
|
|
CalendarMonth,
|
|
|
|
ExpandMore,
|
|
|
|
Gesture,
|
|
|
|
PictureAsPdf,
|
|
|
|
Badge,
|
|
|
|
Work,
|
|
|
|
Close
|
|
|
|
} from '@mui/icons-material'
|
|
|
|
import {
|
|
|
|
Box,
|
|
|
|
Typography,
|
|
|
|
Accordion,
|
|
|
|
AccordionDetails,
|
|
|
|
AccordionSummary,
|
|
|
|
CircularProgress,
|
|
|
|
FormControl,
|
|
|
|
InputLabel,
|
|
|
|
MenuItem,
|
|
|
|
Select
|
|
|
|
} from '@mui/material'
|
2024-06-29 00:43:08 +02:00
|
|
|
import styles from './style.module.scss'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
|
2024-08-06 17:53:55 +02:00
|
|
|
import * as PDFJS from 'pdfjs-dist'
|
|
|
|
import { ProfileMetadata, User } from '../../types'
|
|
|
|
import {
|
|
|
|
PdfFile,
|
|
|
|
DrawTool,
|
|
|
|
MouseState,
|
|
|
|
PdfPage,
|
|
|
|
DrawnField,
|
|
|
|
MarkType
|
|
|
|
} from '../../types/drawing'
|
|
|
|
import { truncate } from 'lodash'
|
|
|
|
import { hexToNpub } from '../../utils'
|
2024-07-16 12:36:18 +03:00
|
|
|
import { toPdfFiles } from '../../utils/pdf.ts'
|
2024-08-06 17:53:55 +02:00
|
|
|
PDFJS.GlobalWorkerOptions.workerSrc =
|
|
|
|
'node_modules/pdfjs-dist/build/pdf.worker.mjs'
|
2024-06-29 00:43:08 +02:00
|
|
|
|
|
|
|
interface Props {
|
2024-07-16 12:36:18 +03:00
|
|
|
selectedFiles: File[]
|
2024-07-11 16:16:36 +02:00
|
|
|
users: User[]
|
|
|
|
metadata: { [key: string]: ProfileMetadata }
|
|
|
|
onDrawFieldsChange: (pdfFiles: PdfFile[]) => void
|
2024-06-29 00:43:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export const DrawPDFFields = (props: Props) => {
|
|
|
|
const { selectedFiles } = props
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
const [pdfFiles, setPdfFiles] = useState<PdfFile[]>([])
|
|
|
|
const [parsingPdf, setParsingPdf] = useState<boolean>(false)
|
|
|
|
const [showDrawToolBox, setShowDrawToolBox] = useState<boolean>(false)
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
const [selectedTool, setSelectedTool] = useState<DrawTool | null>()
|
|
|
|
const [toolbox] = useState<DrawTool[]>([
|
|
|
|
{
|
2024-07-11 16:16:36 +02:00
|
|
|
identifier: MarkType.SIGNATURE,
|
2024-08-06 17:53:55 +02:00
|
|
|
icon: <Gesture />,
|
2024-07-11 16:16:36 +02:00
|
|
|
label: 'Signature',
|
|
|
|
active: false
|
2024-06-29 00:43:08 +02:00
|
|
|
},
|
|
|
|
{
|
2024-07-11 16:16:36 +02:00
|
|
|
identifier: MarkType.FULLNAME,
|
2024-08-06 17:53:55 +02:00
|
|
|
icon: <Badge />,
|
2024-07-11 16:16:36 +02:00
|
|
|
label: 'Full Name',
|
|
|
|
active: true
|
2024-06-29 00:43:08 +02:00
|
|
|
},
|
|
|
|
{
|
2024-07-11 16:16:36 +02:00
|
|
|
identifier: MarkType.JOBTITLE,
|
2024-08-06 17:53:55 +02:00
|
|
|
icon: <Work />,
|
2024-07-11 16:16:36 +02:00
|
|
|
label: 'Job Title',
|
|
|
|
active: false
|
2024-06-29 00:43:08 +02:00
|
|
|
},
|
|
|
|
{
|
2024-07-11 16:16:36 +02:00
|
|
|
identifier: MarkType.DATE,
|
2024-08-06 17:53:55 +02:00
|
|
|
icon: <CalendarMonth />,
|
2024-07-11 16:16:36 +02:00
|
|
|
label: 'Date',
|
|
|
|
active: false
|
2024-06-29 00:43:08 +02:00
|
|
|
},
|
|
|
|
{
|
2024-07-11 16:16:36 +02:00
|
|
|
identifier: MarkType.DATETIME,
|
2024-08-06 17:53:55 +02:00
|
|
|
icon: <AccessTime />,
|
2024-07-11 16:16:36 +02:00
|
|
|
label: 'Datetime',
|
|
|
|
active: false
|
2024-08-06 17:53:55 +02:00
|
|
|
}
|
2024-06-29 00:43:08 +02:00
|
|
|
])
|
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
const [mouseState, setMouseState] = useState<MouseState>({
|
|
|
|
clicked: false
|
|
|
|
})
|
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (selectedFiles) {
|
|
|
|
setParsingPdf(true)
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
parsePdfPages().finally(() => {
|
|
|
|
setParsingPdf(false)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}, [selectedFiles])
|
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (pdfFiles) props.onDrawFieldsChange(pdfFiles)
|
|
|
|
}, [pdfFiles])
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Drawing events
|
|
|
|
*/
|
2024-08-06 17:53:55 +02:00
|
|
|
useEffect(() => {
|
2024-07-11 16:16:36 +02:00
|
|
|
// window.addEventListener('mousedown', onMouseDown);
|
2024-08-06 17:53:55 +02:00
|
|
|
window.addEventListener('mouseup', onMouseUp)
|
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
return () => {
|
|
|
|
// window.removeEventListener('mousedown', onMouseDown);
|
2024-08-06 17:53:55 +02:00
|
|
|
window.removeEventListener('mouseup', onMouseUp)
|
2024-07-11 16:16:36 +02:00
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
const refreshPdfFiles = () => {
|
|
|
|
setPdfFiles([...pdfFiles])
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Fired only when left click and mouse over pdf page
|
|
|
|
* Creates new drawnElement and pushes in the array
|
|
|
|
* It is re rendered and visible right away
|
2024-08-06 12:43:46 +03:00
|
|
|
*
|
2024-07-12 15:07:36 +02:00
|
|
|
* @param event Mouse event
|
|
|
|
* @param page PdfPage where press happened
|
|
|
|
*/
|
2024-07-11 16:16:36 +02:00
|
|
|
const onMouseDown = (event: any, page: PdfPage) => {
|
|
|
|
// Proceed only if left click
|
|
|
|
if (event.button !== 0) return
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
// Only allow drawing if mouse is not over other drawn element
|
|
|
|
const isOverPdfImageWrapper = event.target.tagName === 'IMG'
|
|
|
|
|
|
|
|
if (!selectedTool || !isOverPdfImageWrapper) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-08-05 11:55:20 +00:00
|
|
|
const { mouseX, mouseY } = getMouseCoordinates(event)
|
2024-07-11 16:16:36 +02:00
|
|
|
|
|
|
|
const newField: DrawnField = {
|
|
|
|
left: mouseX,
|
|
|
|
top: mouseY,
|
|
|
|
width: 0,
|
|
|
|
height: 0,
|
|
|
|
counterpart: '',
|
|
|
|
type: selectedTool.identifier
|
|
|
|
}
|
|
|
|
|
|
|
|
page.drawnFields.push(newField)
|
|
|
|
|
|
|
|
setMouseState((prev) => {
|
|
|
|
return {
|
|
|
|
...prev,
|
|
|
|
clicked: true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Drawing is finished, resets all the variables used to draw
|
|
|
|
* @param event Mouse event
|
|
|
|
*/
|
2024-08-05 14:11:15 +03:00
|
|
|
const onMouseUp = () => {
|
2024-07-11 16:16:36 +02:00
|
|
|
setMouseState((prev) => {
|
|
|
|
return {
|
|
|
|
...prev,
|
|
|
|
clicked: false,
|
|
|
|
dragging: false,
|
|
|
|
resizing: false
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* After {@link onMouseDown} create an drawing element, this function gets called on every pixel moved
|
|
|
|
* which alters the newly created drawing element, resizing it while mouse move
|
|
|
|
* @param event Mouse event
|
|
|
|
* @param page PdfPage where moving is happening
|
|
|
|
*/
|
2024-07-11 16:16:36 +02:00
|
|
|
const onMouseMove = (event: any, page: PdfPage) => {
|
|
|
|
if (mouseState.clicked && selectedTool) {
|
2024-08-06 17:53:55 +02:00
|
|
|
const lastElementIndex = page.drawnFields.length - 1
|
2024-07-11 16:16:36 +02:00
|
|
|
const lastDrawnField = page.drawnFields[lastElementIndex]
|
|
|
|
|
2024-08-05 11:55:20 +00:00
|
|
|
const { mouseX, mouseY } = getMouseCoordinates(event)
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
const width = mouseX - lastDrawnField.left
|
|
|
|
const height = mouseY - lastDrawnField.top
|
|
|
|
|
|
|
|
lastDrawnField.width = width
|
|
|
|
lastDrawnField.height = height
|
|
|
|
|
|
|
|
const currentDrawnFields = page.drawnFields
|
|
|
|
|
|
|
|
currentDrawnFields[lastElementIndex] = lastDrawnField
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
refreshPdfFiles()
|
|
|
|
}
|
2024-08-06 17:53:55 +02:00
|
|
|
}
|
2024-07-11 16:16:36 +02:00
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Fired when event happens on the drawn element which will be moved
|
|
|
|
* mouse coordinates relative to drawn element will be stored
|
|
|
|
* so when we start moving, offset can be calculated
|
|
|
|
* mouseX - offsetX
|
|
|
|
* mouseY - offsetY
|
2024-08-06 12:43:46 +03:00
|
|
|
*
|
2024-07-12 15:07:36 +02:00
|
|
|
* @param event Mouse event
|
|
|
|
* @param drawnField Which we are moving
|
|
|
|
*/
|
2024-08-05 14:11:15 +03:00
|
|
|
const onDrawnFieldMouseDown = (event: any) => {
|
2024-07-11 16:16:36 +02:00
|
|
|
event.stopPropagation()
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
// Proceed only if left click
|
|
|
|
if (event.button !== 0) return
|
|
|
|
|
|
|
|
const drawingRectangleCoords = getMouseCoordinates(event)
|
|
|
|
|
|
|
|
setMouseState({
|
|
|
|
dragging: true,
|
|
|
|
clicked: false,
|
|
|
|
coordsInWrapper: {
|
|
|
|
mouseX: drawingRectangleCoords.mouseX,
|
|
|
|
mouseY: drawingRectangleCoords.mouseY
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Moves the drawnElement by the mouse position (mouse can grab anywhere on the drawn element)
|
|
|
|
* @param event Mouse event
|
|
|
|
* @param drawnField which we are moving
|
|
|
|
*/
|
2024-08-05 11:55:20 +00:00
|
|
|
const onDranwFieldMouseMove = (event: any, drawnField: DrawnField) => {
|
2024-07-11 16:16:36 +02:00
|
|
|
if (mouseState.dragging) {
|
2024-08-06 17:53:55 +02:00
|
|
|
const { mouseX, mouseY, rect } = getMouseCoordinates(
|
|
|
|
event,
|
|
|
|
event.target.parentNode
|
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
const coordsOffset = mouseState.coordsInWrapper
|
|
|
|
|
|
|
|
if (coordsOffset) {
|
|
|
|
let left = mouseX - coordsOffset.mouseX
|
|
|
|
let top = mouseY - coordsOffset.mouseY
|
|
|
|
|
|
|
|
const rightLimit = rect.width - drawnField.width - 3
|
|
|
|
const bottomLimit = rect.height - drawnField.height - 3
|
|
|
|
|
|
|
|
if (left < 0) left = 0
|
|
|
|
if (top < 0) top = 0
|
|
|
|
if (left > rightLimit) left = rightLimit
|
|
|
|
if (top > bottomLimit) top = bottomLimit
|
2024-08-05 11:55:20 +00:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
drawnField.left = left
|
|
|
|
drawnField.top = top
|
|
|
|
|
|
|
|
refreshPdfFiles()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
2024-08-05 11:55:20 +00:00
|
|
|
* Fired when clicked on the resize handle, sets the state for a resize action
|
2024-07-12 15:07:36 +02:00
|
|
|
* @param event Mouse event
|
|
|
|
* @param drawnField which we are resizing
|
|
|
|
*/
|
2024-08-05 14:11:15 +03:00
|
|
|
const onResizeHandleMouseDown = (event: any) => {
|
2024-07-11 16:16:36 +02:00
|
|
|
// Proceed only if left click
|
|
|
|
if (event.button !== 0) return
|
|
|
|
|
|
|
|
event.stopPropagation()
|
|
|
|
|
|
|
|
setMouseState({
|
|
|
|
resizing: true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Resizes the drawn element by the mouse position
|
|
|
|
* @param event Mouse event
|
|
|
|
* @param drawnField which we are resizing
|
|
|
|
*/
|
2024-07-11 16:16:36 +02:00
|
|
|
const onResizeHandleMouseMove = (event: any, drawnField: DrawnField) => {
|
|
|
|
if (mouseState.resizing) {
|
2024-08-06 17:53:55 +02:00
|
|
|
const { mouseX, mouseY } = getMouseCoordinates(
|
|
|
|
event,
|
|
|
|
event.target.parentNode.parentNode
|
|
|
|
)
|
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
const width = mouseX - drawnField.left
|
|
|
|
const height = mouseY - drawnField.top
|
|
|
|
|
|
|
|
drawnField.width = width
|
|
|
|
drawnField.height = height
|
|
|
|
|
|
|
|
refreshPdfFiles()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Removes the drawn element using the indexes in the params
|
|
|
|
* @param event Mouse event
|
|
|
|
* @param pdfFileIndex pdf file index
|
|
|
|
* @param pdfPageIndex pdf page index
|
|
|
|
* @param drawnFileIndex drawn file index
|
|
|
|
*/
|
2024-08-06 17:53:55 +02:00
|
|
|
const onRemoveHandleMouseDown = (
|
|
|
|
event: any,
|
|
|
|
pdfFileIndex: number,
|
|
|
|
pdfPageIndex: number,
|
|
|
|
drawnFileIndex: number
|
|
|
|
) => {
|
2024-07-11 16:16:36 +02:00
|
|
|
event.stopPropagation()
|
2024-08-06 17:53:55 +02:00
|
|
|
|
|
|
|
pdfFiles[pdfFileIndex].pages[pdfPageIndex].drawnFields.splice(
|
|
|
|
drawnFileIndex,
|
|
|
|
1
|
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Used to stop mouse click propagating to the parent elements
|
|
|
|
* so select can work properly
|
|
|
|
* @param event Mouse event
|
|
|
|
*/
|
2024-07-11 16:16:36 +02:00
|
|
|
const onUserSelectHandleMouseDown = (event: any) => {
|
|
|
|
event.stopPropagation()
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the mouse coordinates relative to a element in the `event` param
|
|
|
|
* @param event MouseEvent
|
|
|
|
* @param customTarget mouse coordinates relative to this element, if not provided
|
|
|
|
* event.target will be used
|
|
|
|
*/
|
|
|
|
const getMouseCoordinates = (event: any, customTarget?: any) => {
|
|
|
|
const target = customTarget ? customTarget : event.target
|
2024-08-06 17:53:55 +02:00
|
|
|
const rect = target.getBoundingClientRect()
|
|
|
|
const mouseX = event.clientX - rect.left //x position within the element.
|
|
|
|
const mouseY = event.clientY - rect.top //y position within the element.
|
2024-07-11 16:16:36 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
mouseX,
|
|
|
|
mouseY,
|
|
|
|
rect
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Reads the pdf binary files and converts it's pages to images
|
|
|
|
* creates the pdfFiles object and sets to a state
|
|
|
|
*/
|
2024-06-29 00:43:08 +02:00
|
|
|
const parsePdfPages = async () => {
|
2024-08-06 17:53:55 +02:00
|
|
|
const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles)
|
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
setPdfFiles(pdfFiles)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-08-06 12:43:46 +03:00
|
|
|
*
|
2024-07-12 15:07:36 +02:00
|
|
|
* @returns if expanded pdf accordion is present
|
|
|
|
*/
|
2024-06-29 00:43:08 +02:00
|
|
|
const hasExpandedPdf = () => {
|
2024-08-06 17:53:55 +02:00
|
|
|
return !!pdfFiles.filter((pdfFile) => !!pdfFile.expanded).length
|
2024-06-29 00:43:08 +02:00
|
|
|
}
|
|
|
|
|
2024-06-29 00:46:35 +02:00
|
|
|
const handleAccordionExpandChange = (expanded: boolean, pdfFile: PdfFile) => {
|
2024-06-29 00:43:08 +02:00
|
|
|
pdfFile.expanded = expanded
|
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
refreshPdfFiles()
|
2024-06-29 00:43:08 +02:00
|
|
|
setShowDrawToolBox(hasExpandedPdf())
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Changes the drawing tool
|
|
|
|
* @param drawTool to draw with
|
|
|
|
*/
|
2024-06-29 00:43:08 +02:00
|
|
|
const handleToolSelect = (drawTool: DrawTool) => {
|
|
|
|
// If clicked on the same tool, unselect
|
|
|
|
if (drawTool.identifier === selectedTool?.identifier) {
|
|
|
|
setSelectedTool(null)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
setSelectedTool(drawTool)
|
|
|
|
}
|
|
|
|
|
2024-07-12 15:07:36 +02:00
|
|
|
/**
|
|
|
|
* Renders the pdf pages and drawing elements
|
|
|
|
*/
|
2024-07-11 16:16:36 +02:00
|
|
|
const getPdfPages = (pdfFile: PdfFile, pdfFileIndex: number) => {
|
|
|
|
return (
|
2024-08-06 17:53:55 +02:00
|
|
|
<Box
|
|
|
|
sx={{
|
|
|
|
width: '100%'
|
|
|
|
}}
|
|
|
|
>
|
2024-07-11 16:16:36 +02:00
|
|
|
{pdfFile.pages.map((page, pdfPageIndex: number) => {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
key={pdfPageIndex}
|
|
|
|
style={{
|
|
|
|
border: '1px solid #c4c4c4',
|
|
|
|
marginBottom: '10px'
|
|
|
|
}}
|
|
|
|
className={`${styles.pdfImageWrapper} ${selectedTool ? styles.drawing : ''}`}
|
2024-08-06 17:53:55 +02:00
|
|
|
onMouseMove={(event) => {
|
|
|
|
onMouseMove(event, page)
|
|
|
|
}}
|
|
|
|
onMouseDown={(event) => {
|
|
|
|
onMouseDown(event, page)
|
|
|
|
}}
|
2024-07-11 16:16:36 +02:00
|
|
|
>
|
2024-08-06 17:53:55 +02:00
|
|
|
<img
|
|
|
|
draggable="false"
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
src={page.image}
|
|
|
|
/>
|
2024-07-11 16:16:36 +02:00
|
|
|
|
|
|
|
{page.drawnFields.map((drawnField, drawnFieldIndex: number) => {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
key={drawnFieldIndex}
|
2024-08-05 14:11:15 +03:00
|
|
|
onMouseDown={onDrawnFieldMouseDown}
|
2024-08-06 17:53:55 +02:00
|
|
|
onMouseMove={(event) => {
|
|
|
|
onDranwFieldMouseMove(event, drawnField)
|
|
|
|
}}
|
2024-07-11 16:16:36 +02:00
|
|
|
className={styles.drawingRectangle}
|
|
|
|
style={{
|
|
|
|
left: `${drawnField.left}px`,
|
|
|
|
top: `${drawnField.top}px`,
|
|
|
|
width: `${drawnField.width}px`,
|
|
|
|
height: `${drawnField.height}px`,
|
|
|
|
pointerEvents: mouseState.clicked ? 'none' : 'all'
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<span
|
2024-08-05 14:11:15 +03:00
|
|
|
onMouseDown={onResizeHandleMouseDown}
|
2024-08-06 17:53:55 +02:00
|
|
|
onMouseMove={(event) => {
|
|
|
|
onResizeHandleMouseMove(event, drawnField)
|
|
|
|
}}
|
2024-07-11 16:16:36 +02:00
|
|
|
className={styles.resizeHandle}
|
|
|
|
></span>
|
|
|
|
<span
|
2024-08-06 17:53:55 +02:00
|
|
|
onMouseDown={(event) => {
|
|
|
|
onRemoveHandleMouseDown(
|
|
|
|
event,
|
|
|
|
pdfFileIndex,
|
|
|
|
pdfPageIndex,
|
|
|
|
drawnFieldIndex
|
|
|
|
)
|
|
|
|
}}
|
2024-07-11 16:16:36 +02:00
|
|
|
className={styles.removeHandle}
|
|
|
|
>
|
2024-08-06 17:53:55 +02:00
|
|
|
<Close fontSize="small" />
|
2024-07-11 16:16:36 +02:00
|
|
|
</span>
|
2024-08-06 17:53:55 +02:00
|
|
|
<div
|
2024-08-05 14:11:15 +03:00
|
|
|
onMouseDown={onUserSelectHandleMouseDown}
|
2024-07-11 16:16:36 +02:00
|
|
|
className={styles.userSelect}
|
|
|
|
>
|
2024-08-06 17:53:55 +02:00
|
|
|
<FormControl fullWidth size="small">
|
2024-07-11 16:16:36 +02:00
|
|
|
<InputLabel id="counterparts">Counterpart</InputLabel>
|
|
|
|
<Select
|
|
|
|
value={drawnField.counterpart}
|
2024-08-06 17:53:55 +02:00
|
|
|
onChange={(event) => {
|
|
|
|
drawnField.counterpart = event.target.value
|
|
|
|
refreshPdfFiles()
|
|
|
|
}}
|
2024-07-11 16:16:36 +02:00
|
|
|
labelId="counterparts"
|
|
|
|
label="Counterparts"
|
|
|
|
>
|
|
|
|
{props.users.map((user, index) => {
|
2024-08-06 17:53:55 +02:00
|
|
|
let displayValue = truncate(
|
|
|
|
hexToNpub(user.pubkey),
|
|
|
|
{
|
|
|
|
length: 16
|
|
|
|
}
|
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
|
|
|
|
const metadata = props.metadata[user.pubkey]
|
|
|
|
|
|
|
|
if (metadata) {
|
2024-08-06 17:53:55 +02:00
|
|
|
displayValue = truncate(
|
|
|
|
metadata.name ||
|
|
|
|
metadata.display_name ||
|
|
|
|
metadata.username,
|
|
|
|
{
|
|
|
|
length: 16
|
|
|
|
}
|
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
}
|
|
|
|
|
2024-08-06 17:53:55 +02:00
|
|
|
return (
|
|
|
|
<MenuItem
|
|
|
|
key={index}
|
|
|
|
value={hexToNpub(user.pubkey)}
|
|
|
|
>
|
|
|
|
{displayValue}
|
|
|
|
</MenuItem>
|
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
})}
|
|
|
|
</Select>
|
|
|
|
</FormControl>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
</Box>
|
2024-08-06 17:53:55 +02:00
|
|
|
)
|
2024-07-11 16:16:36 +02:00
|
|
|
}
|
|
|
|
|
2024-06-29 00:43:08 +02:00
|
|
|
if (parsingPdf) {
|
|
|
|
return (
|
|
|
|
<Box sx={{ width: '100%', textAlign: 'center' }}>
|
2024-08-06 17:53:55 +02:00
|
|
|
<CircularProgress />
|
2024-06-29 00:43:08 +02:00
|
|
|
</Box>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pdfFiles.length) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Box>
|
|
|
|
<Box sx={{ mt: 1 }}>
|
|
|
|
<Typography sx={{ mb: 1 }}>Draw fields on the PDFs:</Typography>
|
2024-08-06 17:53:55 +02:00
|
|
|
|
2024-07-11 16:16:36 +02:00
|
|
|
{pdfFiles.map((pdfFile, pdfFileIndex: number) => {
|
2024-06-29 00:43:08 +02:00
|
|
|
return (
|
2024-08-06 17:53:55 +02:00
|
|
|
<Accordion
|
|
|
|
key={pdfFileIndex}
|
|
|
|
expanded={pdfFile.expanded}
|
|
|
|
onChange={(_event, expanded) => {
|
|
|
|
handleAccordionExpandChange(expanded, pdfFile)
|
|
|
|
}}
|
|
|
|
>
|
2024-06-29 00:43:08 +02:00
|
|
|
<AccordionSummary
|
|
|
|
expandIcon={<ExpandMore />}
|
2024-07-11 16:16:36 +02:00
|
|
|
aria-controls={`panel${pdfFileIndex}-content`}
|
|
|
|
id={`panel${pdfFileIndex}header`}
|
2024-06-29 00:43:08 +02:00
|
|
|
>
|
2024-08-06 17:53:55 +02:00
|
|
|
<PictureAsPdf sx={{ mr: 1 }} />
|
2024-06-29 00:43:08 +02:00
|
|
|
{pdfFile.file.name}
|
|
|
|
</AccordionSummary>
|
|
|
|
<AccordionDetails>
|
2024-07-11 16:16:36 +02:00
|
|
|
{getPdfPages(pdfFile, pdfFileIndex)}
|
2024-06-29 00:43:08 +02:00
|
|
|
</AccordionDetails>
|
2024-08-06 17:53:55 +02:00
|
|
|
</Accordion>
|
2024-06-29 00:43:08 +02:00
|
|
|
)
|
|
|
|
})}
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
{showDrawToolBox && (
|
|
|
|
<Box className={styles.drawToolBoxContainer}>
|
|
|
|
<Box className={styles.drawToolBox}>
|
2024-08-06 17:53:55 +02:00
|
|
|
{toolbox
|
|
|
|
.filter((drawTool) => drawTool.active)
|
|
|
|
.map((drawTool: DrawTool, index: number) => {
|
|
|
|
return (
|
|
|
|
<Box
|
|
|
|
key={index}
|
|
|
|
onClick={() => {
|
|
|
|
handleToolSelect(drawTool)
|
|
|
|
}}
|
|
|
|
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`}
|
|
|
|
>
|
|
|
|
{drawTool.icon}
|
|
|
|
{drawTool.label}
|
|
|
|
</Box>
|
|
|
|
)
|
|
|
|
})}
|
2024-06-29 00:43:08 +02:00
|
|
|
</Box>
|
|
|
|
</Box>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
)
|
|
|
|
}
|