Add history (undo/redo) to text variable editors (#9889)
https://github.com/user-attachments/assets/83689fd9-1b00-49ff-938a-748822baf15f
This commit is contained in:
committed by
GitHub
parent
180f6c28a4
commit
7195614926
@ -39,6 +39,7 @@
|
|||||||
"@tiptap/core": "^2.10.4",
|
"@tiptap/core": "^2.10.4",
|
||||||
"@tiptap/extension-document": "^2.10.4",
|
"@tiptap/extension-document": "^2.10.4",
|
||||||
"@tiptap/extension-hard-break": "^2.10.4",
|
"@tiptap/extension-hard-break": "^2.10.4",
|
||||||
|
"@tiptap/extension-history": "^2.10.4",
|
||||||
"@tiptap/extension-paragraph": "^2.10.4",
|
"@tiptap/extension-paragraph": "^2.10.4",
|
||||||
"@tiptap/extension-placeholder": "^2.10.4",
|
"@tiptap/extension-placeholder": "^2.10.4",
|
||||||
"@tiptap/extension-text": "^2.10.4",
|
"@tiptap/extension-text": "^2.10.4",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { expect } from '@storybook/jest';
|
import { expect } from '@storybook/jest';
|
||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { fn, userEvent, waitFor, within } from '@storybook/test';
|
import { fn, userEvent, waitFor, within } from '@storybook/test';
|
||||||
|
import { getUserDevice } from 'twenty-ui';
|
||||||
import { FormRawJsonFieldInput } from '../FormRawJsonFieldInput';
|
import { FormRawJsonFieldInput } from '../FormRawJsonFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormRawJsonFieldInput> = {
|
const meta: Meta<typeof FormRawJsonFieldInput> = {
|
||||||
@ -256,3 +257,54 @@ export const AcceptsJsonEncodedNewline: Story = {
|
|||||||
expect(args.onPersist).toHaveBeenCalledWith('"a\\nb"');
|
expect(args.onPersist).toHaveBeenCalledWith('"a\\nb"');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const HasHistory: Story = {
|
||||||
|
args: {
|
||||||
|
placeholder: 'Enter valid json',
|
||||||
|
VariablePicker: ({ onVariableSelect }) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
onVariableSelect('{{test}}');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add variable
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onPersist: fn(),
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const controlKey = getUserDevice() === 'mac' ? 'Meta' : 'Control';
|
||||||
|
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const editor = canvasElement.querySelector('.ProseMirror > p');
|
||||||
|
expect(editor).toBeVisible();
|
||||||
|
|
||||||
|
const addVariableButton = await canvas.findByRole('button', {
|
||||||
|
name: 'Add variable',
|
||||||
|
});
|
||||||
|
|
||||||
|
await userEvent.type(editor, '{{ "a": ');
|
||||||
|
|
||||||
|
await userEvent.click(addVariableButton);
|
||||||
|
|
||||||
|
await userEvent.type(editor, ' }');
|
||||||
|
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith('{ "a": {{test}} }');
|
||||||
|
|
||||||
|
await userEvent.type(editor, `{${controlKey}>}z{/${controlKey}}`);
|
||||||
|
|
||||||
|
expect(editor).toHaveTextContent('');
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith(null);
|
||||||
|
|
||||||
|
await userEvent.type(
|
||||||
|
editor,
|
||||||
|
`{Shift>}{${controlKey}>}z{/${controlKey}}{/Shift}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(editor).toHaveTextContent('{ "a": test }');
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith('{ "a": {{test}} }');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { expect, fn, userEvent, within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
|
import { getUserDevice } from 'twenty-ui';
|
||||||
import { FormTextFieldInput } from '../FormTextFieldInput';
|
import { FormTextFieldInput } from '../FormTextFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormTextFieldInput> = {
|
const meta: Meta<typeof FormTextFieldInput> = {
|
||||||
@ -87,3 +88,53 @@ export const Disabled: Story = {
|
|||||||
expect(defaultValue).toBeVisible();
|
expect(defaultValue).toBeVisible();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const HasHistory: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Text',
|
||||||
|
placeholder: 'Text field...',
|
||||||
|
VariablePicker: ({ onVariableSelect }) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
onVariableSelect('{{test}}');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add variable
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onPersist: fn(),
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const controlKey = getUserDevice() === 'mac' ? 'Meta' : 'Control';
|
||||||
|
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const editor = canvasElement.querySelector('.ProseMirror > p');
|
||||||
|
expect(editor).toBeVisible();
|
||||||
|
|
||||||
|
const addVariableButton = await canvas.findByRole('button', {
|
||||||
|
name: 'Add variable',
|
||||||
|
});
|
||||||
|
|
||||||
|
await userEvent.type(editor, 'Hello World ');
|
||||||
|
|
||||||
|
await userEvent.click(addVariableButton);
|
||||||
|
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith('Hello World {{test}}');
|
||||||
|
|
||||||
|
await userEvent.type(editor, `{${controlKey}>}z{/${controlKey}}`);
|
||||||
|
|
||||||
|
expect(editor).toHaveTextContent('');
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith('');
|
||||||
|
|
||||||
|
await userEvent.type(
|
||||||
|
editor,
|
||||||
|
`{Shift>}{${controlKey}>}z{/${controlKey}}{/Shift}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(editor).toHaveTextContent('Hello World test');
|
||||||
|
expect(args.onPersist).toHaveBeenLastCalledWith('Hello World {{test}}');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { initializeEditorContent } from '@/workflow/workflow-variables/utils/ini
|
|||||||
import { VariableTag } from '@/workflow/workflow-variables/utils/variableTag';
|
import { VariableTag } from '@/workflow/workflow-variables/utils/variableTag';
|
||||||
import Document from '@tiptap/extension-document';
|
import Document from '@tiptap/extension-document';
|
||||||
import HardBreak from '@tiptap/extension-hard-break';
|
import HardBreak from '@tiptap/extension-hard-break';
|
||||||
|
import History from '@tiptap/extension-history';
|
||||||
import Paragraph from '@tiptap/extension-paragraph';
|
import Paragraph from '@tiptap/extension-paragraph';
|
||||||
import { default as Placeholder } from '@tiptap/extension-placeholder';
|
import { default as Placeholder } from '@tiptap/extension-placeholder';
|
||||||
import Text from '@tiptap/extension-text';
|
import Text from '@tiptap/extension-text';
|
||||||
@ -42,6 +43,7 @@ export const useTextVariableEditor = ({
|
|||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
History,
|
||||||
],
|
],
|
||||||
editable: !readonly,
|
editable: !readonly,
|
||||||
onCreate: ({ editor }) => {
|
onCreate: ({ editor }) => {
|
||||||
|
|||||||
11
yarn.lock
11
yarn.lock
@ -15818,6 +15818,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@tiptap/extension-history@npm:^2.10.4":
|
||||||
|
version: 2.11.3
|
||||||
|
resolution: "@tiptap/extension-history@npm:2.11.3"
|
||||||
|
peerDependencies:
|
||||||
|
"@tiptap/core": ^2.7.0
|
||||||
|
"@tiptap/pm": ^2.7.0
|
||||||
|
checksum: 10c0/6542366ee742b42003d31693d471d43d06c2625729f6fd22997a992c53450514fa81b7d19c227a3c7e9b7255a98e9b7606b64cc48c9f681035d97574c7f6360c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@tiptap/extension-history@npm:^2.7.1":
|
"@tiptap/extension-history@npm:^2.7.1":
|
||||||
version: 2.10.4
|
version: 2.10.4
|
||||||
resolution: "@tiptap/extension-history@npm:2.10.4"
|
resolution: "@tiptap/extension-history@npm:2.10.4"
|
||||||
@ -45813,6 +45823,7 @@ __metadata:
|
|||||||
"@tiptap/core": "npm:^2.10.4"
|
"@tiptap/core": "npm:^2.10.4"
|
||||||
"@tiptap/extension-document": "npm:^2.10.4"
|
"@tiptap/extension-document": "npm:^2.10.4"
|
||||||
"@tiptap/extension-hard-break": "npm:^2.10.4"
|
"@tiptap/extension-hard-break": "npm:^2.10.4"
|
||||||
|
"@tiptap/extension-history": "npm:^2.10.4"
|
||||||
"@tiptap/extension-paragraph": "npm:^2.10.4"
|
"@tiptap/extension-paragraph": "npm:^2.10.4"
|
||||||
"@tiptap/extension-placeholder": "npm:^2.10.4"
|
"@tiptap/extension-placeholder": "npm:^2.10.4"
|
||||||
"@tiptap/extension-text": "npm:^2.10.4"
|
"@tiptap/extension-text": "npm:^2.10.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user