-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add editing mode to task cards
Allow editing of layoutset name and datamodelbinding on task/layout cards commit-id:4f2b585e
- Loading branch information
Showing
6 changed files
with
361 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
frontend/packages/ux-editor/src/components/TaskNavigation/TaskCardEditing.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.card { | ||
width: 300px; | ||
min-height: 250px; | ||
} | ||
|
||
.cardContent { | ||
padding: var(--fds-spacing-2); | ||
} | ||
|
||
.btnGroup { | ||
display: flex; | ||
gap: var(--fds-spacing-2); | ||
} |
157 changes: 157 additions & 0 deletions
157
frontend/packages/ux-editor/src/components/TaskNavigation/TaskCardEditing.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import React from 'react'; | ||
import type { LayoutSetModel } from 'app-shared/types/api/dto/LayoutSetModel'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { screen } from '@testing-library/react'; | ||
import { renderWithProviders } from '../../testing/mocks'; | ||
import { TaskCardEditing, type TaskCardEditingProps } from './TaskCardEditing'; | ||
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; | ||
import { QueryKey } from 'app-shared/types/QueryKey'; | ||
import { app, org } from '@studio/testing/testids'; | ||
|
||
const updateProcessDataTypesMutation = jest.fn().mockImplementation((params, options) => { | ||
options.onSettled(); | ||
}); | ||
const updateLayoutSetIdMutation = jest.fn().mockImplementation((params, options) => { | ||
options.onSettled(); | ||
}); | ||
jest.mock('app-development/hooks/mutations/useUpdateProcessDataTypesMutation', () => ({ | ||
useUpdateProcessDataTypesMutation: () => ({ mutate: updateProcessDataTypesMutation }), | ||
})); | ||
jest.mock('app-development/hooks/mutations/useUpdateLayoutSetIdMutation', () => ({ | ||
useUpdateLayoutSetIdMutation: () => ({ mutate: updateLayoutSetIdMutation }), | ||
})); | ||
|
||
const datamodels = ['datamodell123', 'unuseddatamodel']; | ||
const subformLayoutSet: LayoutSetModel = { | ||
id: 'test', | ||
dataType: datamodels[0], | ||
type: 'subform', | ||
task: null, | ||
}; | ||
|
||
const customReceiptLayoutSet: LayoutSetModel = { | ||
id: 'test', | ||
dataType: datamodels[0], | ||
type: '', | ||
task: { id: 'CustomReceipt', type: 'CustomReceipt' }, | ||
}; | ||
|
||
describe('taskCard', () => { | ||
let confirmSpy: jest.SpyInstance; | ||
beforeAll(() => { | ||
confirmSpy = jest.spyOn(window, 'confirm'); | ||
confirmSpy.mockImplementation(jest.fn(() => true)); | ||
}); | ||
|
||
afterAll(() => { | ||
confirmSpy.mockRestore(); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should render with disabled save button without changes', () => { | ||
render(); | ||
expect(screen.getByRole('button', { name: /general.save/ })).toBeDisabled(); | ||
}); | ||
|
||
it('should show alert when changing data model', async () => { | ||
const user = userEvent.setup(); | ||
const onClose = jest.fn(); | ||
render({ onClose, layoutSetModel: customReceiptLayoutSet }); | ||
|
||
await user.selectOptions(dataModelBindingCombobox(), datamodels[1]); | ||
expect(confirmSpy.getMockImplementation()).toHaveBeenCalledTimes(0); | ||
await user.click(screen.getByRole('button', { name: /general.save/ })); | ||
|
||
expect(onClose).toHaveBeenCalledTimes(1); | ||
expect(confirmSpy.getMockImplementation()).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should not show alert when not changing data model', async () => { | ||
const user = userEvent.setup(); | ||
const onClose = jest.fn(); | ||
render({ onClose, layoutSetModel: customReceiptLayoutSet }); | ||
|
||
await user.type(layoutSetNameTextbox(), 'test'); | ||
await user.click(screen.getByRole('button', { name: /general.save/ })); | ||
}); | ||
|
||
it('should call onClose when clicking close button', async () => { | ||
const user = userEvent.setup(); | ||
const onClose = jest.fn(); | ||
render({ onClose }); | ||
|
||
await user.click(screen.getByRole('button', { name: /general.close/ })); | ||
|
||
expect(onClose).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should call updateLayoutSetidMutation when layout set id is changed', async () => { | ||
const user = userEvent.setup(); | ||
const onClose = jest.fn(); | ||
render({ onClose, layoutSetModel: subformLayoutSet }); | ||
|
||
await user.clear(layoutSetNameTextbox()); | ||
const newLayoutSetId = 'CoolLayoutName'; | ||
await user.type(layoutSetNameTextbox(), newLayoutSetId); | ||
await user.click(screen.getByRole('button', { name: /general.save/ })); | ||
|
||
expect(updateLayoutSetIdMutation).toHaveBeenCalledTimes(1); | ||
expect(updateLayoutSetIdMutation).toHaveBeenCalledWith( | ||
{ | ||
layoutSetIdToUpdate: subformLayoutSet.id, | ||
newLayoutSetId: newLayoutSetId, | ||
}, | ||
expect.anything(), | ||
); | ||
expect(onClose).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should call updateProcessDataTypesMutation when datamodel id is changed', async () => { | ||
const user = userEvent.setup(); | ||
const onClose = jest.fn(); | ||
render({ onClose, layoutSetModel: customReceiptLayoutSet }); | ||
|
||
await user.selectOptions(dataModelBindingCombobox(), datamodels[1]); | ||
await user.click(screen.getByRole('button', { name: /general.save/ })); | ||
|
||
expect(updateProcessDataTypesMutation).toHaveBeenCalledTimes(1); | ||
expect(updateProcessDataTypesMutation).toHaveBeenCalledWith( | ||
{ | ||
connectedTaskId: customReceiptLayoutSet.task?.id, | ||
newDataTypes: [datamodels[1]], | ||
}, | ||
expect.anything(), | ||
); | ||
expect(onClose).toHaveBeenCalledTimes(1); | ||
expect(confirmSpy.getMockImplementation()).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should show validation error when inputting invalid id', async () => { | ||
const user = userEvent.setup(); | ||
const invalidLayoutName = ' test4! &'; | ||
render(); | ||
|
||
await user.type(layoutSetNameTextbox(), invalidLayoutName); | ||
|
||
expect(layoutSetNameTextbox()).toBeInvalid(); | ||
expect(screen.getByRole('button', { name: /general.save/ })).toBeDisabled(); | ||
}); | ||
}); | ||
|
||
const render = (props?: Partial<TaskCardEditingProps>) => { | ||
const queryClient = createQueryClientMock(); | ||
queryClient.setQueryData([QueryKey.AppMetadataModelIds, org, app, true], datamodels); | ||
renderWithProviders( | ||
<TaskCardEditing layoutSetModel={subformLayoutSet} onClose={jest.fn()} {...props} />, | ||
{ queryClient }, | ||
); | ||
}; | ||
|
||
const layoutSetNameTextbox = (): Element => | ||
screen.getByRole('textbox', { name: /ux_editor.component_properties.layoutSet/ }); | ||
|
||
const dataModelBindingCombobox = (): Element => | ||
screen.getByRole('combobox', { name: /ux_editor.modal_properties_data_model_binding/ }); |
Oops, something went wrong.