Skip to content

Commit

Permalink
feat(form): add inline flag
Browse files Browse the repository at this point in the history
* feat(form): add isline flag

* fix(form): remove bugs in inline form

* test(form): validate inline form and yaml

* test(form): split into multiple tests
  • Loading branch information
ingeridhellen committed Aug 2, 2023
1 parent fd20d70 commit e85ecb0
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 72 deletions.
105 changes: 65 additions & 40 deletions e2e/tests/plugin-form-Nested.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { expect, test } from '@playwright/test'
import { Page, expect, test } from '@playwright/test'

test('Nested Form', async ({ page }) => {
//Open form
test.describe.configure({ mode: 'serial' })

let page: Page

test.beforeAll(async ({ browser }) => {
page = await browser.newPage()
await page.goto('http://localhost:3000/')
await navigate()
})

test.afterAll(async () => {
await page.close()
})

const navigate = async () => {
await page.getByText('plugins', { exact: true }).click()
await page.getByText('form').click()
await page.getByText('nested', { exact: true }).click()
await page.getByText('DemoDataSource/$Nested').click()
}

//Change owner
test('Change owner', async () => {
await expect(page.getByText('Owner', { exact: true })).toBeVisible
await page
.getByText('OwnerOpen')
Expand All @@ -22,8 +35,9 @@ test('Nested Form', async ({ page }) => {
await expect(page.getByLabel('Name')).toHaveValue('Jacob')
await expect(page.getByLabel('Phone Number (optional)')).toHaveValue('1234')
await page.getByRole('tab').nth(2).click()
})

//Hiring a CEO
test('Hiring a CEO', async () => {
await page
.getByText('CEO (optional)Add')
.getByRole('button', { name: 'Add' })
Expand Down Expand Up @@ -52,52 +66,64 @@ test('Nested Form', async ({ page }) => {
await expect(
page.getByText('CEO (optional)Add').getByRole('button', { name: 'Add' })
).toBeVisible()
})

test('View accountant yaml', async () => {
await expect(
page.getByTestId('accountant').getByRole('button', { name: 'Copy as YAML' })
).toBeVisible()
await expect(
page.getByTestId('accountant').getByRole('button', { name: 'Copy as JSON' })
).toBeVisible()
await expect(page.getByTestId('accountant').getByRole('code')).toBeVisible()
})

//Replacing accountant
test('Adding a trainee', async () => {
await page
.getByText('AccountantOpen')
.getByRole('button', { name: 'Open' })
.getByText('Trainee (optional)Add')
.getByRole('button', { name: 'Add' })
.click()
await page.getByLabel('Name').fill('Richie')
await page.getByLabel('Phone Number (optional)').fill('11223344')
await page.getByRole('button', { name: 'Submit' }).click()
await page.getByText('self').first().click()
await page.getByRole('tab').nth(2).click()
await page.getByTestId('trainee').getByLabel('Name').fill('Peter Pan')
await page
.getByText('AccountantOpen')
.getByRole('button', { name: 'Open' })
.click()
await expect(page.getByLabel('Name')).toHaveValue('Richie')
await expect(page.getByLabel('Phone Number (optional)')).toHaveValue(
'11223344'
.getByTestId('trainee')
.getByLabel('Phone Number (optional)')
.fill('123')
await page.getByRole('button', { name: 'Submit' }).click()
await page.reload()
await navigate()
await expect(page.getByTestId('trainee').getByLabel('Name')).toHaveValue(
'Peter Pan'
)
await page.getByRole('tab').nth(2).click()
await expect(
page.getByTestId('trainee').getByLabel('Phone Number (optional)')
).toHaveValue('123')
})

//New car
test('New car', async () => {
await page.getByText('CarsOpen').getByRole('button', { name: 'Open' }).click()
await expect.soft(page.getByText('1 - 2 of 2')).toBeVisible()
await page.getByRole('button', { name: 'Append Add Item' }).click()
await expect.soft(page.getByText('1 - 3 of 3')).toBeVisible()
await page.getByRole('button', { name: 'Save' }).click()
await page.getByRole('button', { name: 'Open item' }).last().click()
await page.getByLabel('Name').fill('McLaren')
await page.getByLabel('Plate Number').fill('3000')
await page.getByRole('button', { name: 'Submit' }).click()
const lastTabPanel = page.getByRole('tabpanel').last()
await expect(lastTabPanel).toBeVisible()
await lastTabPanel.getByLabel('Name').fill('McLaren')
await lastTabPanel.getByLabel('Plate Number').fill('3000')
await lastTabPanel.getByRole('button', { name: 'Submit' }).click()
await page.reload()
await page.getByText('plugins', { exact: true }).click()
await page.getByText('form').click()
await page.getByText('nested').click()
await page.getByText('DemoDataSource/$Nested').click()
await navigate()
await page.getByText('CarsOpen').getByRole('button', { name: 'Open' }).click()
// await expect(page.getByText('McLaren')).toBeVisible() Does not work because two instances are stored when submitting form... Known bug.
await page.getByRole('button', { name: 'Open item' }).last().click()
await expect(page.getByRole('tab', { name: 'McLaren' })).toBeVisible()
await expect(page.getByLabel('Name')).toHaveValue('McLaren')
await expect(page.getByLabel('Plate Number')).toHaveValue('3000')
await expect(lastTabPanel.getByLabel('Name')).toHaveValue('McLaren')
await expect(lastTabPanel.getByLabel('Plate Number')).toHaveValue('3000')
await page.getByRole('tab').last().click()
await page.getByRole('tab').last().click()
})

//New customer
test('New customer', async () => {
await page
.getByText('CustomersOpen')
.getByRole('button', { name: 'Open' })
Expand All @@ -107,23 +133,22 @@ test('Nested Form', async ({ page }) => {
await expect.soft(page.getByText('1 - 3 of 3')).toBeVisible()
await page.getByRole('button', { name: 'Save' }).click()
await page.getByRole('button', { name: 'Open item' }).last().click()
await page.getByLabel('Name').fill('Lewis')
await page.getByLabel('Phone number (optional)').fill('12345678')
await page.getByRole('button', { name: 'Submit' }).click()
const lastTabPanel = page.getByRole('tabpanel').last()
await expect(lastTabPanel).toBeVisible()
await lastTabPanel.getByLabel('Name').fill('Lewis')
await lastTabPanel.getByLabel('Phone number (optional)').fill('12345678')
await lastTabPanel.getByRole('button', { name: 'Submit' }).click()
await page.reload()
await page.getByText('plugins', { exact: true }).click()
await page.getByText('form').click()
await page.getByText('nested').click()
await page.getByText('DemoDataSource/$Nested').click()
await navigate()
await page
.getByText('CustomersOpen')
.getByRole('button', { name: 'Open' })
.click()
// await expect(page.getByText('Lewis')).toBeVisible() Does not work because two instances are stored when submitting form... Known bug.
await page.getByRole('button', { name: 'Open item' }).last().click()
await expect(page.getByRole('tab', { name: 'Lewis' })).toBeVisible()
await expect(page.getByLabel('Name')).toHaveValue('Lewis')
await expect(page.getByLabel('Phone number (optional)')).toHaveValue(
await expect(lastTabPanel.getByLabel('Name')).toHaveValue('Lewis')
await expect(lastTabPanel.getByLabel('Phone number (optional)')).toHaveValue(
'12345678'
)
await page.getByRole('tab').last().click()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
"attributeType": "./Person",
"label": "Accountant"
},
{
"name": "trainee",
"type": "CORE:BlueprintAttribute",
"attributeType": "./Person",
"label": "Trainee",
"optional": true
},
{
"name": "bestCustomer",
"type": "CORE:BlueprintAttribute",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,23 @@
"type": "PLUGINS:dm-core-plugins/form/FormInput",
"attributes": [
{
"type": "PLUGINS:dm-core-plugins/form/fields/StringField",
"name": "type",
"widget": "TypeWidget"
"type": "PLUGINS:dm-core-plugins/form/fields/ObjectField",
"name": "trainee",
"isInline": true,
"uiRecipe": "defaultForm"
},
{
"type": "PLUGINS:dm-core-plugins/form/fields/ObjectField",
"name": "owner",
"name": "accountant",
"isInline": true,
"uiRecipe": "defaultYaml"
}
],
"fields": [
"owner",
"ceo",
"accountant",
"trainee",
"bestCustomer",
"cars",
"customers"
Expand Down
8 changes: 8 additions & 0 deletions packages/dm-core-plugins/blueprints/form/fields/Field.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
"type": "dmss://system/SIMOS/BlueprintAttribute",
"optional": false,
"attributeType": "string"
},
{
"name": "isInline",
"description": "If true, the attribute will be shown inline. If false, it will be opened in a new tab if possible",
"type": "dmss://system/SIMOS/BlueprintAttribute",
"optional": true,
"default": false,
"attributeType": "boolean"
}
]
}
53 changes: 27 additions & 26 deletions packages/dm-core-plugins/src/form/fields/ObjectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export const ContainedAttribute = (props: TContentProps): JSX.Element => {
namePath,
displayLabel = '',
optional = false,
uiAttribute,
uiRecipe,
blueprint,
} = props
Expand All @@ -149,7 +150,7 @@ export const ContainedAttribute = (props: TContentProps): JSX.Element => {
const attributePath = idReference.split('.', 2).slice(1)

return (
<div>
<div data-testid={`${namePath}`}>
<Stack spacing={0.25} alignItems="flex-start">
<Typography bold={true}>{displayLabel}</Typography>
{optional &&
Expand All @@ -174,36 +175,35 @@ export const ContainedAttribute = (props: TContentProps): JSX.Element => {
onAdd={() => setIsDefined(true)}
/>
))}
{hasOpen && isDefined && (
<OpenObjectButton
viewId={namePath}
idReference={idReference}
namePath={
attributePath && attributePath.length > 1
? `${attributePath[1]}.${namePath}`
: namePath
}
/>
)}
{!hasOpen && isDefined && (
<>
{uiRecipe && uiRecipe.plugin !== 'form' && (
<EntityView
idReference={`${idReference}.${namePath}`}
type={type}
onOpen={onOpen}
/>
)}
{(uiRecipe === undefined ||
(uiRecipe && uiRecipe.plugin === 'form')) && (
{isDefined &&
(hasOpen && !uiAttribute?.isInline ? (
<OpenObjectButton
viewId={namePath}
idReference={idReference}
namePath={
attributePath && attributePath.length > 1
? `${attributePath[1]}.${namePath}`
: namePath
}
/>
) : uiRecipe &&
uiRecipe.plugin !==
'@development-framework/dm-core-plugins/form' ? (
<EntityView
recipeName={uiRecipe.name}
idReference={`${idReference}.${namePath}`}
type={type}
onOpen={onOpen}
/>
) : (
<div style={{ borderLeft: '1px solid black', paddingLeft: '1rem' }}>
<AttributeList
namePath={namePath}
config={uiRecipe?.config}
blueprint={blueprint}
/>
)}
</>
)}
</div>
))}
</Stack>
</div>
)
Expand Down Expand Up @@ -328,6 +328,7 @@ export const ObjectTypeSelector = (props: TObjectFieldProps): JSX.Element => {
optional={optional}
blueprint={blueprint}
uiRecipe={uiRecipe}
uiAttribute={uiAttribute}
/>
)
}
2 changes: 2 additions & 0 deletions packages/dm-core-plugins/src/form/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type TContentProps = {
optional: boolean
blueprint: TBlueprint | undefined
uiRecipe: TUiRecipeForm | undefined
uiAttribute: TAttributeConfig | undefined
}

export type TAttributeFieldProps = {
Expand Down Expand Up @@ -64,6 +65,7 @@ export type TBooleanFieldProps = {
type TAttributeBasis = {
name: string
type: string
isInline?: boolean
}
type TAttributeString = TAttributeBasis & { widget: string; format: string }
type TAttributeArray = TAttributeBasis & {
Expand Down
5 changes: 3 additions & 2 deletions packages/dm-core-plugins/src/view_selector/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react'
import styled from 'styled-components'
import {
TGenericObject,
TViewConfig,
ViewCreator,
} from '@development-framework/dm-core'
import * as React from 'react'
import styled from 'styled-components'
import { TItemData } from './types'

const HidableWrapper = styled.div<any>`
Expand All @@ -28,6 +28,7 @@ export const Content = (props: {
<HidableWrapper
key={config.viewId}
hidden={config.viewId !== selectedView}
role="tabpanel"
>
<ViewCreator
idReference={config.rootEntityId}
Expand Down

0 comments on commit e85ecb0

Please sign in to comment.