Skip to content

Commit

Permalink
ON-43937 # FormElementFile open files in a new tab
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanButton committed Oct 8, 2024
1 parent c058ed6 commit e7ef550
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 115 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `FormElementFile` open files in a new tab

### Changed

- Tooltip `a` tags to be white in colour, and slightly grey when already visited
Expand Down
18 changes: 9 additions & 9 deletions src/components/renderer/attachments/AttachmentStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,31 @@ const AttachmentStatus = ({
isUploading,
isUploadPaused,
uploadError,
loadImageUrlError,
isLoadingImageUrl,
imageUrl,
loadAttachmentUrlError,
isLoadingAttachmentUrl,
attachmentUrl,
progress,
}: {
isUploading?: boolean
isUploadPaused?: boolean
uploadError?: Error
loadImageUrlError?: Error
isLoadingImageUrl?: boolean
imageUrl: string | null | undefined
loadAttachmentUrlError?: Error
isLoadingAttachmentUrl?: boolean
attachmentUrl: string | null | undefined
progress: number | undefined
}) => {
const isOffline = useIsOffline()

const tooltip = React.useMemo(() => {
if (isLoadingImageUrl && !imageUrl) {
if (isLoadingAttachmentUrl && !attachmentUrl) {
return 'Attempting to load file preview. File is synced with submission.'
}
if (loadImageUrlError && !imageUrl) {
if (loadAttachmentUrlError && !attachmentUrl) {
return 'File preview not available, however file is synced with submission.'
}

return 'Synced with submission.'
}, [imageUrl, isLoadingImageUrl, loadImageUrlError])
}, [attachmentUrl, isLoadingAttachmentUrl, loadAttachmentUrlError])

if (uploadError) {
return (
Expand Down
21 changes: 20 additions & 1 deletion src/components/renderer/attachments/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ interface Props {
onRemove: () => void
onDownload?: () => void
onRetry?: () => void
attachmentUrl: string | null | undefined
}

const DropdownMenu = ({ element, onRemove, onDownload, onRetry }: Props) => {
const DropdownMenu = ({
element,
onRemove,
onDownload,
onRetry,
attachmentUrl,
}: Props) => {
const dropDownRef = React.useRef(null)
const [isShowingMore, showMore, hideMore] = useBooleanState(false)

Expand Down Expand Up @@ -69,6 +76,18 @@ const DropdownMenu = ({ element, onRemove, onDownload, onRetry }: Props) => {
Download
</a>
)}
<a
href={attachmentUrl || ''}
target="_blank"
rel="noreferrer"
className="dropdown-item cypress-file-download-button"
style={{
display: 'flex',
alignItems: 'center',
}}
>
Open <MaterialIcon>open_in_new</MaterialIcon>
</a>
<a
className={clsx('dropdown-item cypress-file-remove-button', {
'ob-files__menu-remove-hidden': element.readOnly,
Expand Down
37 changes: 24 additions & 13 deletions src/components/renderer/attachments/FileCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ type Props = {
isUploading?: boolean
isUploadPaused?: boolean
uploadErrorMessage?: string
loadImageUrlError?: Error
isLoadingImageUrl?: boolean
loadAttachmentUrlError?: Error
isLoadingAttachmentUrl?: boolean
isContentTypeImage?: boolean
fileName: string
imageUrl: string | undefined | null
attachmentUrl: string | undefined | null
onRemove: () => void
onDownload?: () => void
onRetry?: () => void
Expand All @@ -30,9 +31,10 @@ function FileCard({
isUploading,
isUploadPaused,
uploadErrorMessage,
loadImageUrlError,
isLoadingImageUrl,
imageUrl,
loadAttachmentUrlError,
isLoadingAttachmentUrl,
isContentTypeImage,
attachmentUrl,
fileName,
onDownload,
onRemove,
Expand All @@ -56,16 +58,25 @@ function FileCard({
<div className="column is-one-quarter-ob">
<div className="ob-files__box">
<div className="ob-files__content">
<FileCardContent
imageUrl={imageUrl}
alt={`${element.label}: Attachment ${index + 1}`}
/>
<a
href={attachmentUrl || ''}
target="_blank"
rel="noreferrer"
className="dropdown-item cypress-file-download-button"
>
<FileCardContent
attachmentUrl={attachmentUrl}
alt={`${element.label}: Attachment ${index + 1}`}
isContentTypeImage={isContentTypeImage}
/>
</a>
</div>
<DropdownMenu
element={element}
onDownload={onDownload}
onRetry={onRetry}
onRemove={onRemove}
attachmentUrl={attachmentUrl || ''}
/>

<div className="ob-files__file-name is-size-6">
Expand All @@ -74,9 +85,9 @@ function FileCard({
isUploading={isUploading}
isUploadPaused={isUploadPaused}
uploadError={uploadError}
loadImageUrlError={loadImageUrlError}
isLoadingImageUrl={isLoadingImageUrl}
imageUrl={imageUrl}
loadAttachmentUrlError={loadAttachmentUrlError}
isLoadingAttachmentUrl={isLoadingAttachmentUrl}
attachmentUrl={attachmentUrl}
progress={progress}
/>
<ProgressBar progress={progress} isShowing={!!isUploading} />
Expand Down
10 changes: 6 additions & 4 deletions src/components/renderer/attachments/FileCardContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import * as React from 'react'
import MaterialIcon from '../../MaterialIcon'

const FileCardContent = ({
imageUrl,
attachmentUrl,
alt,
isContentTypeImage,
}: {
imageUrl: string | undefined | null
attachmentUrl: string | undefined | null
alt: string
isContentTypeImage?: boolean
}) => {
if (imageUrl) {
if (isContentTypeImage && attachmentUrl) {
return (
<div className="ob-files__content-image">
<img className="ob-files__image" src={imageUrl} alt={alt} />
<img className="ob-files__image" src={attachmentUrl} alt={alt} />
</div>
)
}
Expand Down
44 changes: 22 additions & 22 deletions src/form-elements/FormElementCamera.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ function FormElementCamera({
const {
isUploading,
uploadErrorMessage,
isLoadingImageUrl,
imageUrl,
loadImageUrlError,
isLoadingAttachmentUrl,
attachmentUrl,
loadAttachmentUrlError,
canDownload,
progress,
} = useAttachment(
Expand Down Expand Up @@ -219,7 +219,7 @@ function FormElementCamera({
(annotationDataUri: string) => {
clearIsAnnotating()

if (typeof imageUrl !== 'string') {
if (typeof attachmentUrl !== 'string') {
return
}

Expand Down Expand Up @@ -275,9 +275,9 @@ function FormElementCamera({
annotationImage.src = annotationDataUri
}
image.setAttribute('crossorigin', 'anonymous')
image.src = imageUrl
image.src = attachmentUrl
},
[clearIsAnnotating, element, imageUrl, onChange],
[attachmentUrl, clearIsAnnotating, element, onChange],
)

const progressTooltipRef = React.useRef<HTMLDivElement>(null)
Expand All @@ -296,9 +296,9 @@ function FormElementCamera({
<DisplayImage
isUploading={isUploading}
uploadErrorMessage={uploadErrorMessage}
isLoadingImageUrl={isLoadingImageUrl}
imageUrl={imageUrl}
loadImageUrlError={loadImageUrlError}
isLoadingAttachmentUrl={isLoadingAttachmentUrl}
attachmentUrl={attachmentUrl}
loadAttachmentUrlError={loadAttachmentUrlError}
isLoading={isLoading}
element={element}
onAnnotate={setIsAnnotating}
Expand Down Expand Up @@ -378,9 +378,9 @@ function FormElementCamera({
)}
</FormElementLabelContainer>

{isAnnotating && imageUrl && (
{isAnnotating && attachmentUrl && (
<AnnotationModal
imageSrc={imageUrl}
imageSrc={attachmentUrl}
onClose={clearIsAnnotating}
onSave={handleSaveAnnotation}
/>
Expand Down Expand Up @@ -423,9 +423,9 @@ export default React.memo(FormElementCamera)
const DisplayImage = React.memo(function DisplayImage({
uploadErrorMessage,
isUploading,
isLoadingImageUrl,
imageUrl,
loadImageUrlError,
isLoadingAttachmentUrl,
attachmentUrl,
loadAttachmentUrlError,
isLoading,
element,
onAnnotate,
Expand All @@ -448,37 +448,37 @@ const DisplayImage = React.memo(function DisplayImage({
)
}

if (loadImageUrlError) {
if (loadAttachmentUrlError) {
return (
<div className="figure-content" role="alert">
<h3 className="title is-3">Preview Failed</h3>
<p>{loadImageUrlError.message}</p>
<p>{loadAttachmentUrlError.message}</p>
</div>
)
}

if (isLoadingImageUrl || isLoading) {
if (isLoadingAttachmentUrl || isLoading) {
return (
<div className="figure-content has-text-centered cypress-camera-loading-image">
<OnLoading small />
</div>
)
}

if (imageUrl) {
if (attachmentUrl) {
return (
<>
<span className="ob-figure__status">
<AttachmentStatus
isLoadingImageUrl={isLoadingImageUrl}
loadImageUrlError={loadImageUrlError}
isLoadingAttachmentUrl={isLoadingAttachmentUrl}
loadAttachmentUrlError={loadAttachmentUrlError}
isUploading={isUploading}
imageUrl={imageUrl}
attachmentUrl={attachmentUrl}
progress={progress}
/>
</span>
<img
src={imageUrl}
src={attachmentUrl}
className="cypress-camera-image ob-camera__img"
crossOrigin="anonymous"
alt={`${element.label}: Attachment`}
Expand Down
7 changes: 4 additions & 3 deletions src/form-elements/FormElementFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ const FormElementFile = ({
isUploading={attachmentResult.isUploading}
isUploadPaused={disableUpload}
uploadErrorMessage={attachmentResult.uploadErrorMessage}
loadImageUrlError={attachmentResult.loadImageUrlError}
isLoadingImageUrl={attachmentResult.isLoadingImageUrl}
imageUrl={attachmentResult.imageUrl}
loadAttachmentUrlError={attachmentResult.loadAttachmentUrlError}
isLoadingAttachmentUrl={attachmentResult.isLoadingAttachmentUrl}
attachmentUrl={attachmentResult.attachmentUrl}
isContentTypeImage={attachmentResult.isContentTypeImage}
fileName={file.fileName}
onDownload={attachmentResult.canDownload ? handleDownload : undefined}
onRemove={handleRemove}
Expand Down
22 changes: 11 additions & 11 deletions src/form-elements/FormElementSignature.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ const DisplayImage = React.memo(function DisplayImage({
alt,
uploadErrorMessage,
isUploading,
isLoadingImageUrl,
imageUrl,
loadImageUrlError,
isLoadingAttachmentUrl,
attachmentUrl,
loadAttachmentUrlError,
progress,
}: ReturnType<typeof useAttachment> & {
alt: string
Expand All @@ -277,37 +277,37 @@ const DisplayImage = React.memo(function DisplayImage({
)
}

if (loadImageUrlError) {
if (loadAttachmentUrlError) {
return (
<div className="figure-content" role="alert">
<h3 className="title is-3">Preview Failed</h3>
<p>{loadImageUrlError.message}</p>
<p>{loadAttachmentUrlError.message}</p>
</div>
)
}

if (isLoadingImageUrl) {
if (isLoadingAttachmentUrl) {
return (
<div className="figure-content">
<OnLoading small className="cypress-signature-loading-image" />
</div>
)
}

if (imageUrl) {
if (attachmentUrl) {
return (
<div className="figure-content">
<span className="ob-figure__status">
<AttachmentStatus
isLoadingImageUrl={isLoadingImageUrl}
loadImageUrlError={loadImageUrlError}
isLoadingAttachmentUrl={isLoadingAttachmentUrl}
loadAttachmentUrlError={loadAttachmentUrlError}
isUploading={isUploading}
imageUrl={imageUrl}
attachmentUrl={attachmentUrl}
progress={progress}
/>
</span>
<img
src={imageUrl}
src={attachmentUrl}
className="cypress-signature-image ob-signature__img"
alt={alt}
/>
Expand Down
Loading

0 comments on commit e7ef550

Please sign in to comment.