diff --git a/packages/twenty-front/package.json b/packages/twenty-front/package.json index 0815aa19c..3b444a647 100644 --- a/packages/twenty-front/package.json +++ b/packages/twenty-front/package.json @@ -39,6 +39,7 @@ "@tiptap/core": "^2.10.4", "@tiptap/extension-document": "^2.10.4", "@tiptap/extension-hard-break": "^2.10.4", + "@tiptap/extension-history": "^2.10.4", "@tiptap/extension-paragraph": "^2.10.4", "@tiptap/extension-placeholder": "^2.10.4", "@tiptap/extension-text": "^2.10.4", diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormRawJsonFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormRawJsonFieldInput.stories.tsx index 902a9fbce..e334790be 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormRawJsonFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormRawJsonFieldInput.stories.tsx @@ -1,6 +1,7 @@ import { expect } from '@storybook/jest'; import { Meta, StoryObj } from '@storybook/react'; import { fn, userEvent, waitFor, within } from '@storybook/test'; +import { getUserDevice } from 'twenty-ui'; import { FormRawJsonFieldInput } from '../FormRawJsonFieldInput'; const meta: Meta = { @@ -256,3 +257,54 @@ export const AcceptsJsonEncodedNewline: Story = { expect(args.onPersist).toHaveBeenCalledWith('"a\\nb"'); }, }; + +export const HasHistory: Story = { + args: { + placeholder: 'Enter valid json', + VariablePicker: ({ onVariableSelect }) => { + return ( + + ); + }, + 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}} }'); + }, +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormTextFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormTextFieldInput.stories.tsx index 3348085a8..f0cb749bc 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormTextFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormTextFieldInput.stories.tsx @@ -1,5 +1,6 @@ import { Meta, StoryObj } from '@storybook/react'; import { expect, fn, userEvent, within } from '@storybook/test'; +import { getUserDevice } from 'twenty-ui'; import { FormTextFieldInput } from '../FormTextFieldInput'; const meta: Meta = { @@ -87,3 +88,53 @@ export const Disabled: Story = { expect(defaultValue).toBeVisible(); }, }; + +export const HasHistory: Story = { + args: { + label: 'Text', + placeholder: 'Text field...', + VariablePicker: ({ onVariableSelect }) => { + return ( + + ); + }, + 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}}'); + }, +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/hooks/useTextVariableEditor.ts b/packages/twenty-front/src/modules/object-record/record-field/form-types/hooks/useTextVariableEditor.ts index 6b8582a84..232454437 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/hooks/useTextVariableEditor.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/hooks/useTextVariableEditor.ts @@ -2,6 +2,7 @@ import { initializeEditorContent } from '@/workflow/workflow-variables/utils/ini import { VariableTag } from '@/workflow/workflow-variables/utils/variableTag'; import Document from '@tiptap/extension-document'; import HardBreak from '@tiptap/extension-hard-break'; +import History from '@tiptap/extension-history'; import Paragraph from '@tiptap/extension-paragraph'; import { default as Placeholder } from '@tiptap/extension-placeholder'; import Text from '@tiptap/extension-text'; @@ -42,6 +43,7 @@ export const useTextVariableEditor = ({ }), ] : []), + History, ], editable: !readonly, onCreate: ({ editor }) => { diff --git a/yarn.lock b/yarn.lock index 1ec17702b..2e904b426 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15818,6 +15818,16 @@ __metadata: languageName: node 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": version: 2.10.4 resolution: "@tiptap/extension-history@npm:2.10.4" @@ -45813,6 +45823,7 @@ __metadata: "@tiptap/core": "npm:^2.10.4" "@tiptap/extension-document": "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-placeholder": "npm:^2.10.4" "@tiptap/extension-text": "npm:^2.10.4"