Desktop: Resolves #5934: Use same notebook dialog when creating a new notebook too

fix_ci
Laurent Cozic 2021-12-31 07:26:06 +01:00
parent b5b02d8d7b
commit e813d15ef2
4 changed files with 56 additions and 40 deletions

View File

@ -8,25 +8,31 @@ import StyledInput from '../style/StyledInput';
import { IconSelector, ChangeEvent } from './IconSelector'; import { IconSelector, ChangeEvent } from './IconSelector';
import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect'; import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect';
import Folder from '@joplin/lib/models/Folder'; 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 Button from '../Button/Button';
import bridge from '../../services/bridge';
interface Props { interface Props {
themeId: number; themeId: number;
dispatch: Function; dispatch: Function;
folderId: string; folderId: string;
parentId: string;
} }
export default function(props: Props) { export default function(props: Props) {
const [folderTitle, setFolderTitle] = useState(''); const [folderTitle, setFolderTitle] = useState('');
const [folderIcon, setFolderIcon] = useState<FolderIcon>(); const [folderIcon, setFolderIcon] = useState<FolderIcon>();
const isNew = !props.folderId;
useAsyncEffect(async (event: AsyncEffectEvent) => { useAsyncEffect(async (event: AsyncEffectEvent) => {
if (isNew) return;
const folder = await Folder.load(props.folderId); const folder = await Folder.load(props.folderId);
if (event.cancelled) return; if (event.cancelled) return;
setFolderTitle(folder.title); setFolderTitle(folder.title);
setFolderIcon(Folder.unserializeIcon(folder.icon)); setFolderIcon(Folder.unserializeIcon(folder.icon));
}, [props.folderId]); }, [props.folderId, isNew]);
const onClose = useCallback(() => { const onClose = useCallback(() => {
props.dispatch({ props.dispatch({
@ -42,15 +48,29 @@ export default function(props: Props) {
} }
if (event.buttonName === 'ok') { if (event.buttonName === 'ok') {
await Folder.save({ const folder: FolderEntity = {
id: props.folderId,
title: folderTitle, title: folderTitle,
icon: Folder.serializeIcon(folderIcon), 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; return;
} }
}, [onClose, folderTitle, folderIcon, props.folderId]); }, [onClose, folderTitle, folderIcon, props.folderId, props.parentId]);
const onFolderTitleChange = useCallback((event: any) => { const onFolderTitleChange = useCallback((event: any) => {
setFolderTitle(event.target.value); setFolderTitle(event.target.value);
@ -96,10 +116,12 @@ export default function(props: Props) {
); );
} }
const dialogTitle = isNew ? _('Create notebook') : _('Edit notebook');
function renderDialogWrapper() { function renderDialogWrapper() {
return ( return (
<div className="dialog-root"> <div className="dialog-root">
<DialogTitle title={_('Edit notebook')}/> <DialogTitle title={dialogTitle}/>
{renderContent()} {renderContent()}
<DialogButtonRow <DialogButtonRow
themeId={props.themeId} themeId={props.themeId}

View File

@ -1,7 +1,6 @@
import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; import CommandService, { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
import Folder from '@joplin/lib/models/Folder'; import { Options } from './openFolderDialog';
const bridge = require('@electron/remote').require('./bridge').default;
export const declaration: CommandDeclaration = { export const declaration: CommandDeclaration = {
name: 'newFolder', name: 'newFolder',
@ -9,35 +8,15 @@ export const declaration: CommandDeclaration = {
iconName: 'fa-book', iconName: 'fa-book',
}; };
export const runtime = (comp: any): CommandRuntime => { export const runtime = (): CommandRuntime => {
return { return {
execute: async (_context: CommandContext, parentId: string = null) => { execute: async (_context: CommandContext, parentId: string = null) => {
comp.setState({ const options: Options = {
promptOptions: { isNew: true,
label: _('Notebook title:'), parentId: parentId,
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);
}
if (folder) { void CommandService.instance().execute('openFolderDialog', options);
comp.props.dispatch({
type: 'FOLDER_SELECT',
id: folder.id,
});
}
}
comp.setState({ promptOptions: null });
},
},
});
}, },
}; };
}; };

View File

@ -1,6 +1,12 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService'; import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
export interface Options {
isNew?: boolean;
folderId?: string;
parentId?: string;
}
export const declaration: CommandDeclaration = { export const declaration: CommandDeclaration = {
name: 'openFolderDialog', name: 'openFolderDialog',
label: () => _('Edit'), label: () => _('Edit'),
@ -8,13 +14,22 @@ export const declaration: CommandDeclaration = {
export const runtime = (): CommandRuntime => { export const runtime = (): CommandRuntime => {
return { 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({ context.dispatch({
type: 'DIALOG_OPEN', type: 'DIALOG_OPEN',
name: 'editFolder', name: 'editFolder',
isOpen: true, isOpen: true,
props: { props: {
folderId, folderId: options.folderId,
parentId: options.parentId,
}, },
}); });
}, },

View File

@ -294,7 +294,7 @@ class SidebarComponent extends React.Component<Props, State> {
); );
if (itemType === BaseModel.TYPE_FOLDER && !item.encryption_applied) { 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' })); menu.append(new MenuItem({ type: 'separator' }));