You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-26 22:41:17 +02:00
Desktop: Fix returning form data from plugin dialogs (#12092)
This commit is contained in:
@@ -23,6 +23,27 @@ test.describe('pluginApi', () => {
|
|||||||
await editor.expectToHaveText('PASS');
|
await editor.expectToHaveText('PASS');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should return form data from the dialog API', async ({ startAppWithPlugins }) => {
|
||||||
|
const { app, mainWindow } = await startAppWithPlugins(['resources/test-plugins/dialogs.js']);
|
||||||
|
const mainScreen = await new MainScreen(mainWindow).setup();
|
||||||
|
await mainScreen.createNewNote('First note');
|
||||||
|
|
||||||
|
const editor = mainScreen.noteEditor;
|
||||||
|
await editor.expectToHaveText('');
|
||||||
|
|
||||||
|
await mainScreen.goToAnything.runCommand(app, 'showTestDialog');
|
||||||
|
// Wait for the iframe to load
|
||||||
|
const dialogContent = mainScreen.dialog.locator('iframe').contentFrame();
|
||||||
|
await dialogContent.locator('form').waitFor();
|
||||||
|
|
||||||
|
// Submitting the dialog should include form data in the output
|
||||||
|
await mainScreen.dialog.getByRole('button', { name: 'Okay' }).click();
|
||||||
|
await editor.expectToHaveText(JSON.stringify({
|
||||||
|
id: 'ok',
|
||||||
|
hasFormData: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
test('should be possible to create multiple toasts with the same text from a plugin', async ({ startAppWithPlugins }) => {
|
test('should be possible to create multiple toasts with the same text from a plugin', async ({ startAppWithPlugins }) => {
|
||||||
const { app, mainWindow } = await startAppWithPlugins(['resources/test-plugins/showToast.js']);
|
const { app, mainWindow } = await startAppWithPlugins(['resources/test-plugins/showToast.js']);
|
||||||
const mainScreen = await new MainScreen(mainWindow).setup();
|
const mainScreen = await new MainScreen(mainWindow).setup();
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// Allows referencing the Joplin global:
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
|
||||||
|
// Allows the `joplin-manifest` block comment:
|
||||||
|
/* eslint-disable multiline-comment-style */
|
||||||
|
|
||||||
|
/* joplin-manifest:
|
||||||
|
{
|
||||||
|
"id": "org.joplinapp.plugins.example.dialogs",
|
||||||
|
"manifest_version": 1,
|
||||||
|
"app_min_version": "3.1",
|
||||||
|
"name": "JS Bundle test",
|
||||||
|
"description": "JS Bundle Test plugin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "",
|
||||||
|
"homepage_url": "https://joplinapp.org"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
joplin.plugins.register({
|
||||||
|
onStart: async function() {
|
||||||
|
const dialogs = joplin.views.dialogs;
|
||||||
|
const dialogHandle = await dialogs.create('test-dialog');
|
||||||
|
await dialogs.setHtml(
|
||||||
|
dialogHandle,
|
||||||
|
`
|
||||||
|
<form name="main-form">
|
||||||
|
<label>Test: <input type="checkbox" name="test" checked/></label>
|
||||||
|
</form>
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
await dialogs.setButtons(dialogHandle, [
|
||||||
|
{
|
||||||
|
id: 'ok',
|
||||||
|
title: 'Okay',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
await joplin.commands.register({
|
||||||
|
name: 'showTestDialog',
|
||||||
|
label: 'showTestDialog',
|
||||||
|
iconName: 'fas fa-drum',
|
||||||
|
execute: async () => {
|
||||||
|
const result = await joplin.views.dialogs.open(dialogHandle);
|
||||||
|
await joplin.commands.execute('editor.setText', JSON.stringify({
|
||||||
|
id: result.id,
|
||||||
|
hasFormData: !!result.formData,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -46,9 +46,9 @@ export default function UserWebviewDialog(props: Props) {
|
|||||||
const buttons: ButtonSpec[] = (props.buttons ? props.buttons : defaultButtons()).map((b: ButtonSpec) => {
|
const buttons: ButtonSpec[] = (props.buttons ? props.buttons : defaultButtons()).map((b: ButtonSpec) => {
|
||||||
return {
|
return {
|
||||||
...b,
|
...b,
|
||||||
onClick: () => {
|
onClick: async () => {
|
||||||
const response: DialogResult = { id: b.id };
|
const response: DialogResult = { id: b.id };
|
||||||
const formData = webviewRef.current.formData();
|
const formData = await webviewRef.current.formData();
|
||||||
if (formData && Object.keys(formData).length) response.formData = formData;
|
if (formData && Object.keys(formData).length) response.formData = formData;
|
||||||
viewController().closeWithResponse(response);
|
viewController().closeWithResponse(response);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const useFormData = (viewRef: RefObject<HTMLIFrameElement>, postMessage: PostMes
|
|||||||
const listeners = [...formDataListenersRef.current];
|
const listeners = [...formDataListenersRef.current];
|
||||||
formDataListenersRef.current = [];
|
formDataListenersRef.current = [];
|
||||||
for (const listener of listeners) {
|
for (const listener of listeners) {
|
||||||
listener(event.data.formData);
|
listener(formData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -26,7 +26,7 @@ const useFormData = (viewRef: RefObject<HTMLIFrameElement>, postMessage: PostMes
|
|||||||
return {
|
return {
|
||||||
getFormData: () => {
|
getFormData: () => {
|
||||||
return new Promise<FormDataRecord>(resolve => {
|
return new Promise<FormDataRecord>(resolve => {
|
||||||
postMessage('getFormData', null);
|
postMessage('serializeForms', null);
|
||||||
formDataListenersRef.current.push((data) => {
|
formDataListenersRef.current.push((data) => {
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user