feat: add "Upload and link file" button to linking panel
This commit is contained in:
@@ -94,6 +94,7 @@ const FileViewWithoutProtection = ({ application, viewControllerManager, file }:
|
|||||||
<LinkedItemsButton
|
<LinkedItemsButton
|
||||||
filesController={viewControllerManager.filesController}
|
filesController={viewControllerManager.filesController}
|
||||||
linkingController={viewControllerManager.linkingController}
|
linkingController={viewControllerManager.linkingController}
|
||||||
|
featuresController={viewControllerManager.featuresController}
|
||||||
/>
|
/>
|
||||||
<RoundIconButton
|
<RoundIconButton
|
||||||
label="File information panel"
|
label="File information panel"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { FeaturesController } from '@/Controllers/FeaturesController'
|
||||||
import { FilesController } from '@/Controllers/FilesController'
|
import { FilesController } from '@/Controllers/FilesController'
|
||||||
import { LinkingController } from '@/Controllers/LinkingController'
|
import { LinkingController } from '@/Controllers/LinkingController'
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
@@ -11,9 +12,10 @@ type Props = {
|
|||||||
linkingController: LinkingController
|
linkingController: LinkingController
|
||||||
onClickPreprocessing?: () => Promise<void>
|
onClickPreprocessing?: () => Promise<void>
|
||||||
filesController: FilesController
|
filesController: FilesController
|
||||||
|
featuresController: FeaturesController
|
||||||
}
|
}
|
||||||
|
|
||||||
const LinkedItemsButton = ({ linkingController, filesController, onClickPreprocessing }: Props) => {
|
const LinkedItemsButton = ({ linkingController, filesController, onClickPreprocessing, featuresController }: Props) => {
|
||||||
const { isLinkingPanelOpen, setIsLinkingPanelOpen } = linkingController
|
const { isLinkingPanelOpen, setIsLinkingPanelOpen } = linkingController
|
||||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ const LinkedItemsButton = ({ linkingController, filesController, onClickPreproce
|
|||||||
isOpen={isLinkingPanelOpen}
|
isOpen={isLinkingPanelOpen}
|
||||||
linkingController={linkingController}
|
linkingController={linkingController}
|
||||||
filesController={filesController}
|
filesController={filesController}
|
||||||
|
featuresController={featuresController}
|
||||||
/>
|
/>
|
||||||
</Popover>
|
</Popover>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { FeaturesController } from '@/Controllers/FeaturesController'
|
||||||
import { FilesController } from '@/Controllers/FilesController'
|
import { FilesController } from '@/Controllers/FilesController'
|
||||||
import { LinkableItem, LinkingController } from '@/Controllers/LinkingController'
|
import { LinkableItem, LinkingController } from '@/Controllers/LinkingController'
|
||||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||||
@@ -6,7 +7,7 @@ import { formatSizeToReadableString } from '@standardnotes/filepicker'
|
|||||||
import { FileItem } from '@standardnotes/snjs'
|
import { FileItem } from '@standardnotes/snjs'
|
||||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { ChangeEventHandler, useEffect, useRef, useState } from 'react'
|
||||||
import { PopoverFileItemActionType } from '../AttachedFilesPopover/PopoverFileItemAction'
|
import { PopoverFileItemActionType } from '../AttachedFilesPopover/PopoverFileItemAction'
|
||||||
import ClearInputButton from '../ClearInputButton/ClearInputButton'
|
import ClearInputButton from '../ClearInputButton/ClearInputButton'
|
||||||
import Icon from '../Icon/Icon'
|
import Icon from '../Icon/Icon'
|
||||||
@@ -158,10 +159,12 @@ const LinkedItemsSectionItem = ({
|
|||||||
const LinkedItemsPanel = ({
|
const LinkedItemsPanel = ({
|
||||||
linkingController,
|
linkingController,
|
||||||
filesController,
|
filesController,
|
||||||
|
featuresController,
|
||||||
isOpen,
|
isOpen,
|
||||||
}: {
|
}: {
|
||||||
linkingController: LinkingController
|
linkingController: LinkingController
|
||||||
filesController: FilesController
|
filesController: FilesController
|
||||||
|
featuresController: FeaturesController
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@@ -181,6 +184,9 @@ const LinkedItemsPanel = ({
|
|||||||
isEntitledToNoteLinking,
|
isEntitledToNoteLinking,
|
||||||
} = linkingController
|
} = linkingController
|
||||||
|
|
||||||
|
const { hasFiles } = featuresController
|
||||||
|
|
||||||
|
const fileInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
const searchInputRef = useRef<HTMLInputElement | null>(null)
|
const searchInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
const [searchQuery, setSearchQuery] = useState('')
|
const [searchQuery, setSearchQuery] = useState('')
|
||||||
const isSearching = !!searchQuery.length
|
const isSearching = !!searchQuery.length
|
||||||
@@ -192,6 +198,30 @@ const LinkedItemsPanel = ({
|
|||||||
}
|
}
|
||||||
}, [isOpen])
|
}, [isOpen])
|
||||||
|
|
||||||
|
const handleFileInputChange: ChangeEventHandler<HTMLInputElement> = (event) => {
|
||||||
|
const files = event.currentTarget.files
|
||||||
|
|
||||||
|
if (!files) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
filesController.uploadNewFile(files[i]).then((uploadedFiles) => {
|
||||||
|
if (uploadedFiles) {
|
||||||
|
void linkItemToSelectedItem(uploadedFiles[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectAndUploadFiles = () => {
|
||||||
|
if (!fileInputRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInputRef.current.click()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<form
|
<form
|
||||||
@@ -284,10 +314,24 @@ const LinkedItemsPanel = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!!linkedFiles.length && (
|
{(!!linkedFiles.length || hasFiles) && (
|
||||||
<div>
|
<div>
|
||||||
<div className="mt-3 mb-1 px-3 text-menu-item font-semibold uppercase text-passive-0">Linked Files</div>
|
<div className="mt-3 mb-1 px-3 text-menu-item font-semibold uppercase text-passive-0">Linked Files</div>
|
||||||
<div className="my-1">
|
<div className="my-1">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
className="absolute top-0 left-0 -z-50 h-px w-px opacity-0"
|
||||||
|
multiple
|
||||||
|
ref={fileInputRef}
|
||||||
|
onChange={handleFileInputChange}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="flex w-full cursor-pointer items-center gap-3 bg-transparent px-3 py-2 text-left text-sm text-text hover:bg-info-backdrop hover:text-foreground focus:bg-info-backdrop focus:shadow-none"
|
||||||
|
onClick={selectAndUploadFiles}
|
||||||
|
>
|
||||||
|
<Icon type="add" />
|
||||||
|
Upload and link file(s)
|
||||||
|
</button>
|
||||||
{linkedFiles.map((link) => (
|
{linkedFiles.map((link) => (
|
||||||
<LinkedItemsSectionItem
|
<LinkedItemsSectionItem
|
||||||
key={link.id}
|
key={link.id}
|
||||||
|
|||||||
@@ -999,6 +999,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
|||||||
filesController={this.viewControllerManager.filesController}
|
filesController={this.viewControllerManager.filesController}
|
||||||
linkingController={this.viewControllerManager.linkingController}
|
linkingController={this.viewControllerManager.linkingController}
|
||||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||||
|
featuresController={this.viewControllerManager.featuresController}
|
||||||
/>
|
/>
|
||||||
<ChangeEditorButton
|
<ChangeEditorButton
|
||||||
application={this.application}
|
application={this.application}
|
||||||
|
|||||||
Reference in New Issue
Block a user