Skip to content

Commit 12c6874

Browse files
Rokt33rDavy-c
authored andcommitted
Improve folder creation
1 parent 5e8a3a9 commit 12c6874

2 files changed

Lines changed: 97 additions & 18 deletions

File tree

src/cloud/components/Views/Table/TableViewContentManager.tsx

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ import SortingOption, {
5656
sortingOrders,
5757
} from '../../ContentManager/SortingOption'
5858
import { FormSelectOption } from '../../../../design/components/molecules/Form/atoms/FormSelect'
59+
import FormInput from '../../../../design/components/molecules/Form/atoms/FormInput'
60+
import { useCloudApi } from '../../../lib/hooks/useCloudApi'
61+
import Spinner from '../../../../design/components/atoms/Spinner'
5962

6063
interface ContentManagerProps {
6164
team: SerializedTeam
@@ -83,7 +86,8 @@ const TableViewContentManager = ({
8386
}: ContentManagerProps) => {
8487
const { translate } = useI18n()
8588
const { openContextModal, closeAllModals } = useModal()
86-
const { openNewFolderForm, openNewDocForm } = useCloudResourceModals()
89+
const { openNewDocForm } = useCloudResourceModals()
90+
const { createFolder } = useCloudApi()
8791
const { push } = useRouter()
8892
const { preferences, setPreferences } = usePreferences()
8993
const [order, setOrder] = useState<typeof sortingOrders[number]['value']>(
@@ -252,6 +256,37 @@ const TableViewContentManager = ({
252256
[setPreferences]
253257
)
254258

259+
const [newFolderRowState, setNewFolderRowState] = useState<
260+
'idle' | 'editing' | 'submitting'
261+
>('idle')
262+
const [newFolderName, setNewFolderName] = useState('')
263+
const compositionStateRef = useRef(false)
264+
const newFolderInputRef = useRef<HTMLInputElement>(null)
265+
266+
useEffect(() => {
267+
if (newFolderInputRef.current != null) {
268+
newFolderInputRef.current.focus()
269+
}
270+
}, [newFolderRowState])
271+
272+
const createNewFolder = useCallback(async () => {
273+
setNewFolderRowState('submitting')
274+
if (currentWorkspaceId != null) {
275+
await createFolder(
276+
team,
277+
{
278+
folderName: newFolderName,
279+
description: '',
280+
workspaceId: currentWorkspaceId,
281+
parentFolderId: currentFolderId,
282+
},
283+
{ skipRedirect: true }
284+
)
285+
}
286+
setNewFolderName('')
287+
setNewFolderRowState('idle')
288+
}, [currentWorkspaceId, currentFolderId, createFolder, team, newFolderName])
289+
255290
return (
256291
<Container>
257292
<Scroller className='cm__scroller'>
@@ -492,25 +527,59 @@ const TableViewContentManager = ({
492527
onDragStart={onDragStartFolder}
493528
/>
494529
))}
530+
495531
{currentWorkspaceId != null && (
496532
<TableContentManagerRow className='content__manager--no-border'>
497-
<Button
498-
className='content__manager--no-padding'
499-
onClick={() =>
500-
openNewFolderForm(
501-
{
502-
team,
503-
parentFolderId: currentFolderId,
504-
workspaceId: currentWorkspaceId,
505-
},
506-
{ skipRedirect: true, precedingRows: [] }
507-
)
508-
}
509-
variant='transparent'
510-
iconPath={mdiPlus}
511-
>
512-
{translate(lngKeys.ModalsCreateNewFolder)}
513-
</Button>
533+
{newFolderRowState === 'idle' ? (
534+
<Button
535+
className='content__manager--no-padding'
536+
onClick={() => {
537+
setNewFolderRowState('editing')
538+
}}
539+
variant='transparent'
540+
iconPath={mdiPlus}
541+
>
542+
{translate(lngKeys.ModalsCreateNewFolder)}
543+
</Button>
544+
) : newFolderRowState === 'editing' ? (
545+
<FormInput
546+
ref={newFolderInputRef}
547+
value={newFolderName}
548+
onChange={(event) => {
549+
setNewFolderName(event.target.value)
550+
}}
551+
onCompositionStart={() => {
552+
compositionStateRef.current = true
553+
}}
554+
onCompositionEnd={() => {
555+
compositionStateRef.current = false
556+
if (newFolderInputRef.current != null) {
557+
newFolderInputRef.current.focus()
558+
}
559+
}}
560+
onKeyPress={(event) => {
561+
if (compositionStateRef.current) {
562+
return
563+
}
564+
switch (event.key) {
565+
case 'Escape':
566+
event.preventDefault()
567+
setNewFolderRowState('idle')
568+
setNewFolderName('')
569+
return
570+
case 'Enter':
571+
event.preventDefault()
572+
createNewFolder()
573+
return
574+
}
575+
}}
576+
onBlur={() => {
577+
createNewFolder()
578+
}}
579+
/>
580+
) : (
581+
<Spinner />
582+
)}
514583
</TableContentManagerRow>
515584
)}
516585
</>

src/design/components/molecules/Form/atoms/FormInput.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, {
33
MouseEventHandler,
44
FocusEventHandler,
55
KeyboardEventHandler,
6+
CompositionEventHandler,
67
} from 'react'
78
import cc from 'classcat'
89
import styled from '../../../../lib/styled'
@@ -32,6 +33,9 @@ export interface FormInputProps {
3233
onDoubleClick?: MouseEventHandler<HTMLInputElement>
3334
onContextMenu?: MouseEventHandler<HTMLInputElement>
3435
onFocus?: FocusEventHandler<HTMLInputElement>
36+
onCompositionStart?: CompositionEventHandler<HTMLInputElement>
37+
onCompositionEnd?: CompositionEventHandler<HTMLInputElement>
38+
onKeyPress?: KeyboardEventHandler<HTMLInputElement>
3539
onKeyDown?: KeyboardEventHandler<HTMLInputElement>
3640
}
3741

@@ -61,6 +65,9 @@ const FormInput = React.forwardRef<HTMLInputElement, FormInputProps>(
6165
onDoubleClick,
6266
onContextMenu,
6367
onFocus,
68+
onCompositionStart,
69+
onCompositionEnd,
70+
onKeyPress,
6471
onKeyDown,
6572
},
6673
ref
@@ -91,6 +98,9 @@ const FormInput = React.forwardRef<HTMLInputElement, FormInputProps>(
9198
onDoubleClick={onDoubleClick}
9299
onContextMenu={onContextMenu}
93100
onFocus={onFocus}
101+
onCompositionStart={onCompositionStart}
102+
onCompositionEnd={onCompositionEnd}
103+
onKeyPress={onKeyPress}
94104
onKeyDown={onKeyDown}
95105
/>
96106
)

0 commit comments

Comments
 (0)