From 83b8e368ed610c79c9c01a0846fffe2b535b9fcd Mon Sep 17 00:00:00 2001 From: asimonok Date: Fri, 1 Mar 2024 09:13:41 +0300 Subject: [PATCH 1/3] Allow to disable columns in confirmation modal --- src/components/FormPanel/FormPanel.test.tsx | 107 +++++++++++++++++++- src/components/FormPanel/FormPanel.tsx | 95 ++++++++++------- src/constants/confirm-modal.ts | 19 ++++ src/constants/default.ts | 2 + src/constants/index.ts | 1 + src/module.ts | 19 +++- src/types/modal.ts | 16 +++ 7 files changed, 218 insertions(+), 41 deletions(-) create mode 100644 src/constants/confirm-modal.ts diff --git a/src/components/FormPanel/FormPanel.test.tsx b/src/components/FormPanel/FormPanel.test.tsx index dae34386..35b6fe16 100644 --- a/src/components/FormPanel/FormPanel.test.tsx +++ b/src/components/FormPanel/FormPanel.test.tsx @@ -17,7 +17,15 @@ import { TEST_IDS, } from '../../constants'; import { useDatasourceRequest } from '../../hooks'; -import { ButtonOrientation, ButtonVariant, FormElement, LocalFormElement, UpdateEnabledMode } from '../../types'; +import { + ButtonOrientation, + ButtonVariant, + FormElement, + LocalFormElement, + ModalColumnName, + PanelOptions, + UpdateEnabledMode, +} from '../../types'; import { getFormElementsSelectors, getPanelSelectors, toLocalFormElement } from '../../utils'; import { FormElements } from '../FormElements'; import { FormPanel } from './FormPanel'; @@ -1968,7 +1976,7 @@ describe('Panel', () => { }); describe('Confirm changes', () => { - const prepareComponent = async () => { + const prepareComponent = async (options?: Partial) => { let triggerChangeElement: (element: LocalFormElement) => void = jest.fn(); jest.mocked(FormElements).mockImplementation(({ onChangeElement }) => { triggerChangeElement = onChangeElement; @@ -2002,7 +2010,11 @@ describe('Panel', () => { await act(async () => render( getComponent({ - options: { elements: [elementWithInitialValue, elementWithoutInitialValue], update: { confirm: true } }, + options: { + elements: [elementWithInitialValue, elementWithoutInitialValue], + update: { confirm: true }, + ...options, + }, }) ) ); @@ -2108,6 +2120,95 @@ describe('Panel', () => { ); expect(updatedFieldSelectors.confirmModalFieldValue()).toHaveTextContent('111'); }); + + it('Should show only included columns', async () => { + const { triggerChangeElement, elementWithInitialValue } = await prepareComponent({ + confirmModal: { + columns: { + include: [ModalColumnName.NEW_VALUE], + }, + } as any, + }); + + /** + * Trigger field change + */ + await act(async () => + triggerChangeElement({ + ...elementWithInitialValue, + value: '111', + }) + ); + + /** + * Check if submit button is enabled + */ + expect(selectors.buttonSubmit()).not.toBeDisabled(); + + /** + * Open confirm modal + */ + await act(async () => fireEvent.click(selectors.buttonSubmit())); + + /** + * Check confirm modal presence + */ + expect(selectors.confirmModalContent()).toBeInTheDocument(); + + /** + * Check updated field presence in confirm modal + */ + const updatedField = selectors.confirmModalField(false, elementWithInitialValue.id); + expect(updatedField).toBeInTheDocument(); + + /** + * Check if only included columns are shown + */ + const updatedFieldSelectors = getPanelSelectors(within(updatedField)); + expect(updatedFieldSelectors.confirmModalFieldTitle(true)).not.toBeInTheDocument(); + expect(updatedFieldSelectors.confirmModalFieldPreviousValue(true)).not.toBeInTheDocument(); + expect(updatedFieldSelectors.confirmModalFieldValue()).toBeInTheDocument(); + }); + + it('Should not show table if no included columns', async () => { + const { triggerChangeElement, elementWithInitialValue } = await prepareComponent({ + confirmModal: { + columns: { + include: [], + }, + } as any, + }); + + /** + * Trigger field change + */ + await act(async () => + triggerChangeElement({ + ...elementWithInitialValue, + value: '111', + }) + ); + + /** + * Check if submit button is enabled + */ + expect(selectors.buttonSubmit()).not.toBeDisabled(); + + /** + * Open confirm modal + */ + await act(async () => fireEvent.click(selectors.buttonSubmit())); + + /** + * Check confirm modal presence + */ + expect(selectors.confirmModalContent()).toBeInTheDocument(); + + /** + * Check no columns are show + */ + expect(selectors.confirmModalField(true, elementWithInitialValue.id)).not.toBeInTheDocument(); + }); }); describe('Save default values', () => { diff --git a/src/components/FormPanel/FormPanel.tsx b/src/components/FormPanel/FormPanel.tsx index 9238b1a0..56e932f7 100644 --- a/src/components/FormPanel/FormPanel.tsx +++ b/src/components/FormPanel/FormPanel.tsx @@ -43,7 +43,14 @@ import { TEST_IDS, } from '../../constants'; import { useDatasourceRequest, useFormElements, useMutableState } from '../../hooks'; -import { ButtonVariant, FormElement, LocalFormElement, PanelOptions, UpdateEnabledMode } from '../../types'; +import { + ButtonVariant, + FormElement, + LocalFormElement, + ModalColumnName, + PanelOptions, + UpdateEnabledMode, +} from '../../types'; import { convertToElementValue, fileToBase64, @@ -1066,19 +1073,25 @@ export const FormPanel: React.FC = ({ body={

{options.confirmModal.body}

- {options.layout.variant !== LayoutVariant.NONE && ( + {options.layout.variant !== LayoutVariant.NONE && options.confirmModal.columns.include.length > 0 && ( - - - + {options.confirmModal.columns.include.includes(ModalColumnName.NAME) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.OLD_VALUE) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.NEW_VALUE) && ( + + )} @@ -1104,18 +1117,24 @@ export const FormPanel: React.FC = ({ key={element.id} data-testid={TEST_IDS.panel.confirmModalField(element.id)} > - - - + {options.confirmModal.columns.include.includes(ModalColumnName.NAME) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.OLD_VALUE) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.NEW_VALUE) && ( + + )} ); } @@ -1134,18 +1153,24 @@ export const FormPanel: React.FC = ({ key={element.id} data-testid={TEST_IDS.panel.confirmModalField(element.id)} > - - - + {options.confirmModal.columns.include.includes(ModalColumnName.NAME) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.OLD_VALUE) && ( + + )} + {options.confirmModal.columns.include.includes(ModalColumnName.NEW_VALUE) && ( + + )} ); })} diff --git a/src/constants/confirm-modal.ts b/src/constants/confirm-modal.ts new file mode 100644 index 00000000..ef83a08d --- /dev/null +++ b/src/constants/confirm-modal.ts @@ -0,0 +1,19 @@ +import { ModalColumnName } from '../types'; + +/** + * Confirm Modal Columns Include Options + */ +export const CONFIRM_MODAL_COLUMNS_INCLUDE_OPTIONS = [ + { + value: ModalColumnName.NAME, + label: 'Name', + }, + { + value: ModalColumnName.OLD_VALUE, + label: 'Old Value', + }, + { + value: ModalColumnName.NEW_VALUE, + label: 'New Value', + }, +]; diff --git a/src/constants/default.ts b/src/constants/default.ts index 5f63b2bd..5b2230a3 100644 --- a/src/constants/default.ts +++ b/src/constants/default.ts @@ -4,6 +4,7 @@ import { CodeLanguage, CodeOptions, FormElement, + ModalColumnName, ModalOptions, NumberOptions, SelectOptions, @@ -187,6 +188,7 @@ export const CONFIRM_MODAL_DEFAULT: ModalOptions = { title: 'Confirm update request', body: 'Please confirm to update changed values', columns: { + include: [ModalColumnName.NAME, ModalColumnName.OLD_VALUE, ModalColumnName.NEW_VALUE], name: 'Label', oldValue: 'Old Value', newValue: 'New Value', diff --git a/src/constants/index.ts b/src/constants/index.ts index fd2333bf..b73bec58 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,5 +1,6 @@ export * from './button'; export * from './code-editor'; +export * from './confirm-modal'; export * from './data'; export * from './default'; export * from './form-element'; diff --git a/src/module.ts b/src/module.ts index 23874d4a..42cb45a0 100644 --- a/src/module.ts +++ b/src/module.ts @@ -15,6 +15,7 @@ import { BUTTON_SIZE_OPTIONS, BUTTON_VARIANT_HIDDEN_OPTIONS, BUTTON_VARIANT_OPTIONS, + CONFIRM_MODAL_COLUMNS_INCLUDE_OPTIONS, CONFIRM_MODAL_DEFAULT, CONTENT_TYPE_OPTIONS, ContentType, @@ -47,6 +48,7 @@ import { ButtonSize, ButtonVariant, CodeEditorType, + ModalColumnName, PanelOptions, RequestOptions, UpdateEnabledMode, @@ -435,26 +437,37 @@ export const plugin = new PanelPlugin(FormPanel) defaultValue: CONFIRM_MODAL_DEFAULT.body, showIf: (config) => config.update.confirm, }) + .addMultiSelect({ + path: 'confirmModal.columns.include', + name: 'Include columns', + category: ['Update Confirmation Window'], + defaultValue: CONFIRM_MODAL_DEFAULT.columns.include as unknown, + showIf: (config) => config.update.confirm, + settings: { + options: CONFIRM_MODAL_COLUMNS_INCLUDE_OPTIONS, + }, + }) .addTextInput({ path: 'confirmModal.columns.name', name: 'Label column', category: ['Update Confirmation Window'], defaultValue: CONFIRM_MODAL_DEFAULT.columns.name, - showIf: (config) => config.update.confirm, + showIf: (config) => config.update.confirm && config.confirmModal.columns.include.includes(ModalColumnName.NAME), }) .addTextInput({ path: 'confirmModal.columns.oldValue', name: 'Old value column', category: ['Update Confirmation Window'], defaultValue: CONFIRM_MODAL_DEFAULT.columns.oldValue, - showIf: (config) => config.update.confirm, + showIf: (config) => + config.update.confirm && config.confirmModal.columns.include.includes(ModalColumnName.OLD_VALUE), }) .addTextInput({ path: 'confirmModal.columns.newValue', name: 'New value column', category: ['Update Confirmation Window'], defaultValue: CONFIRM_MODAL_DEFAULT.columns.newValue, - showIf: (config) => config.update.confirm, + showIf: (config) => config.update.confirm && config.confirmModal.columns.include.includes(ModalColumnName.NAME), }) .addTextInput({ path: 'confirmModal.confirm', diff --git a/src/types/modal.ts b/src/types/modal.ts index 951b473e..cefe36e1 100644 --- a/src/types/modal.ts +++ b/src/types/modal.ts @@ -1,3 +1,12 @@ +/** + * Modal Column Name + */ +export enum ModalColumnName { + NAME = 'name', + OLD_VALUE = 'oldValue', + NEW_VALUE = 'newValue', +} + /** * Modal Options */ @@ -20,6 +29,13 @@ export interface ModalOptions { * Columns */ columns: { + /** + * Include + * + * @type {ModalColumnName[]} + */ + include: ModalColumnName[]; + /** * Name * From 870ed3412ee1413b57b194a6595208cb3310499c Mon Sep 17 00:00:00 2001 From: asimonok Date: Fri, 1 Mar 2024 09:19:20 +0300 Subject: [PATCH 2/3] Fix tests --- src/module.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/module.test.ts b/src/module.test.ts index 833084b7..e33fa8cb 100644 --- a/src/module.test.ts +++ b/src/module.test.ts @@ -18,6 +18,7 @@ describe('plugin', () => { addSelect: jest.fn().mockImplementation(() => builder), addSliderInput: jest.fn().mockImplementation(() => builder), addTextInput: jest.fn().mockImplementation(() => builder), + addMultiSelect: jest.fn().mockImplementation(() => builder), }; it('Should be instance of PanelPlugin', () => { From fa99001a06c3af8e295cab09475adc5c07b6f795 Mon Sep 17 00:00:00 2001 From: Mikhail Volkov Date: Fri, 8 Mar 2024 00:25:41 -0500 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66aa7857..b623f925 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Add files upload examples and fix form data header (#357) - Add code parameters with builder and add initial request to element value changed code (#358) +- Allow to disable columns in confirmation modal (#360) ## 3.6.0 (2023-01-10)
- {options.confirmModal.columns.name} - - {options.confirmModal.columns.oldValue} - - {options.confirmModal.columns.newValue} - + {options.confirmModal.columns.name} + + {options.confirmModal.columns.oldValue} + + {options.confirmModal.columns.newValue} +
- {element.title || element.tooltip} - - ********* - - ********* - + {element.title || element.tooltip} + + ********* + + ********* +
- {element.title || element.tooltip} - - {initial[element.id] === undefined ? '' : String(initial[element.id])} - - {currentValue === undefined ? '' : String(currentValue)} - + {element.title || element.tooltip} + + {initial[element.id] === undefined ? '' : String(initial[element.id])} + + {currentValue === undefined ? '' : String(currentValue)} +