diff --git a/packages/app-desktop/gui/EditFolderDialog/Dialog.tsx b/packages/app-desktop/gui/EditFolderDialog/Dialog.tsx index 7dcd5e9e47..e9711be695 100644 --- a/packages/app-desktop/gui/EditFolderDialog/Dialog.tsx +++ b/packages/app-desktop/gui/EditFolderDialog/Dialog.tsx @@ -8,25 +8,31 @@ import StyledInput from '../style/StyledInput'; import { IconSelector, ChangeEvent } from './IconSelector'; import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect'; import Folder from '@joplin/lib/models/Folder'; -import { FolderIcon } from '@joplin/lib/services/database/types'; +import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types'; import Button from '../Button/Button'; +import bridge from '../../services/bridge'; interface Props { themeId: number; dispatch: Function; folderId: string; + parentId: string; } export default function(props: Props) { const [folderTitle, setFolderTitle] = useState(''); const [folderIcon, setFolderIcon] = useState(); + const isNew = !props.folderId; + useAsyncEffect(async (event: AsyncEffectEvent) => { + if (isNew) return; + const folder = await Folder.load(props.folderId); if (event.cancelled) return; setFolderTitle(folder.title); setFolderIcon(Folder.unserializeIcon(folder.icon)); - }, [props.folderId]); + }, [props.folderId, isNew]); const onClose = useCallback(() => { props.dispatch({ @@ -42,15 +48,29 @@ export default function(props: Props) { } if (event.buttonName === 'ok') { - await Folder.save({ - id: props.folderId, + const folder: FolderEntity = { title: folderTitle, icon: Folder.serializeIcon(folderIcon), - }); - onClose(); + }; + + if (!isNew) folder.id = props.folderId; + if (props.parentId) folder.parent_id = props.parentId; + + try { + const savedFolder = await Folder.save(folder, { userSideValidation: true }); + onClose(); + + props.dispatch({ + type: 'FOLDER_SELECT', + id: savedFolder.id, + }); + } catch (error) { + bridge().showErrorMessageBox(error.message); + } + return; } - }, [onClose, folderTitle, folderIcon, props.folderId]); + }, [onClose, folderTitle, folderIcon, props.folderId, props.parentId]); const onFolderTitleChange = useCallback((event: any) => { setFolderTitle(event.target.value); @@ -96,10 +116,12 @@ export default function(props: Props) { ); } + const dialogTitle = isNew ? _('Create notebook') : _('Edit notebook'); + function renderDialogWrapper() { return (
- + {renderContent()} { +export const runtime = (): CommandRuntime => { return { execute: async (_context: CommandContext, parentId: string = null) => { - comp.setState({ - promptOptions: { - label: _('Notebook title:'), - onClose: async (answer: string) => { - if (answer) { - let folder = null; - try { - const toSave: any = { title: answer }; - if (parentId) toSave.parent_id = parentId; - folder = await Folder.save(toSave, { userSideValidation: true }); - } catch (error) { - bridge().showErrorMessageBox(error.message); - } + const options: Options = { + isNew: true, + parentId: parentId, + }; - if (folder) { - comp.props.dispatch({ - type: 'FOLDER_SELECT', - id: folder.id, - }); - } - } - - comp.setState({ promptOptions: null }); - }, - }, - }); + void CommandService.instance().execute('openFolderDialog', options); }, }; }; diff --git a/packages/app-desktop/gui/MainScreen/commands/openFolderDialog.ts b/packages/app-desktop/gui/MainScreen/commands/openFolderDialog.ts index 4317302501..dc405b065f 100644 --- a/packages/app-desktop/gui/MainScreen/commands/openFolderDialog.ts +++ b/packages/app-desktop/gui/MainScreen/commands/openFolderDialog.ts @@ -1,6 +1,12 @@ import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService'; import { _ } from '@joplin/lib/locale'; +export interface Options { + isNew?: boolean; + folderId?: string; + parentId?: string; +} + export const declaration: CommandDeclaration = { name: 'openFolderDialog', label: () => _('Edit'), @@ -8,13 +14,22 @@ export const declaration: CommandDeclaration = { export const runtime = (): CommandRuntime => { return { - execute: async (context: CommandContext, folderId: string) => { + execute: async (context: CommandContext, options: Options = null) => { + options = { + isNew: false, + ...options, + }; + + if (options.isNew && !('parentId' in options)) throw new Error('parentId mst be specified when creating a new folder'); + if (!options.isNew && !('folderId' in options)) throw new Error('folderId property is required'); + context.dispatch({ type: 'DIALOG_OPEN', name: 'editFolder', isOpen: true, props: { - folderId, + folderId: options.folderId, + parentId: options.parentId, }, }); }, diff --git a/packages/app-desktop/gui/Sidebar/Sidebar.tsx b/packages/app-desktop/gui/Sidebar/Sidebar.tsx index d182d0401a..0233be4b49 100644 --- a/packages/app-desktop/gui/Sidebar/Sidebar.tsx +++ b/packages/app-desktop/gui/Sidebar/Sidebar.tsx @@ -294,7 +294,7 @@ class SidebarComponent extends React.Component { ); if (itemType === BaseModel.TYPE_FOLDER && !item.encryption_applied) { - menu.append(new MenuItem(menuUtils.commandToStatefulMenuItem('openFolderDialog', itemId))); + menu.append(new MenuItem(menuUtils.commandToStatefulMenuItem('openFolderDialog', { folderId: itemId }))); menu.append(new MenuItem({ type: 'separator' }));