Skip to content

Commit

Permalink
feat: unify flatten unflatten logic
Browse files Browse the repository at this point in the history
fixes #352
  • Loading branch information
wojtek-krysiak committed Aug 26, 2020
2 parents f271570 + 12395a5 commit b8435de
Show file tree
Hide file tree
Showing 27 changed files with 293 additions and 424 deletions.
1 change: 1 addition & 0 deletions example-app/bin/setup-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const setupDb = async () => {

await Tool.create([...new Array(100)].map((el, index) => ({
name: `tool ${index}`,
description: null,
})))
}

Expand Down
11 changes: 11 additions & 0 deletions example-app/cypress/integration/tools/create-tool.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,22 @@ context('resources/Tool/actions/new', () => {
})

it('creates new tool by hitting enter instead of clicking submit', () => {
cy.server()
cy.route({ method: 'POST', url: 'admin/api/resources/Tool/actions/new' })
.as('apiNew')

const name = 'My Name'
cy.get('[data-testid="property-edit-name"]').type(`${name}{enter}`)

cy.wait('@apiNew').then((xhr) => {
const { record } = xhr.response.body
expect(record.params.description).to.be.undefined
expect(record.params.name).to.eq(name)
})

cy.location('pathname').should('eq', '/admin/resources/Tool')

// Remove the created record, because it brakes the pagination test otherwise.
cy.get('td[data-property-name="name"]').contains(name).parents('tr')
.find('[data-testid="actions-dropdown"]')
.trigger('mouseover')
Expand Down
28 changes: 28 additions & 0 deletions example-app/cypress/integration/tools/edit-tool.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// <reference types="cypress" />
/// <reference types="../../support" />

context('resources/Tool/actions/edit', () => {
before(() => {
cy.login()
})

beforeEach(() => {
Cypress.Cookies.preserveOnce(Cypress.env('COOKIE_NAME'))
cy.visit('resources/Tool')
})

it('leaves null value in description when it was not alter', () => {
cy.get('[data-testid="property-list-name"]').last().click()
cy.get('[data-testid="action-edit"]').click()

cy.server()
cy.route({ method: 'POST', url: 'admin/api/resources/Tool/records/*/edit' })
.as('apiEdit')
cy.get('button[type="submit"]').click()

cy.wait('@apiEdit').then((xhr) => {
const { record } = xhr.response.body
expect(record.params.description).to.eq(null)
})
})
})
2 changes: 2 additions & 0 deletions example-app/src/admin.options.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const AdminTaggable = require('./taggables/taggable.admin')
const AdminProfession = require('./professions/profession.admin')
const AdminTool = require('./tools/tool.admin')
const AdminPage = require('./pages/page.admin')
const AdminNested = require('./nested/nested.admin')

AdminBro.bundle('./components/sidebar-footer', 'SidebarFooter')
AdminBro.bundle('./components/no-records', 'NoRecords')
Expand All @@ -27,6 +28,7 @@ const options = {
AdminTool,
AdminTaggable,
AdminPage,
AdminNested,
],
version: {
admin: true,
Expand Down
11 changes: 11 additions & 0 deletions example-app/src/nested/nested.admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { Nested } = require('./nested.entity')

/** @type {import('admin-bro').ResourceOptions} */
const options = {

}

module.exports = {
options,
resource: Nested,
}
26 changes: 26 additions & 0 deletions example-app/src/nested/nested.entity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const mongoose = require('mongoose')

const InnerElement = new mongoose.Schema({
name: {
type: String,
required: true,
},
})

const TopArrayElement = new mongoose.Schema({
innerObjects: {
type: [InnerElement],
required: true,
},
})

const NestedSchema = new mongoose.Schema({
name: {
type: String,
},
topObjects: [TopArrayElement],
})

const Nested = mongoose.model('Nested', NestedSchema)

module.exports = { ToolSchema: NestedSchema, Nested }
6 changes: 0 additions & 6 deletions src/backend/utils/request-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ describe('RequestParser', function () {
return newProperty
},
} as BaseResource

it('converts empty string to an empty array', function () {
const request = { ...baseRequest, payload: { arrayed: '' } }

expect(requestParser(request, resource).payload?.arrayed).to.deep.eq([])
})
})

describe('boolean values', function () {
Expand Down
15 changes: 9 additions & 6 deletions src/backend/utils/request-parser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ActionRequest } from '../actions/action.interface'
import BaseResource from '../adapters/base-resource'
import { FORM_VALUE_NULL, FORM_VALUE_EMPTY_OBJECT, FORM_VALUE_EMPTY_ARRAY } from '../../frontend/hooks/use-record/record-to-form-data'

/**
* Takes the original ActionRequest and convert string values to a corresponding
* types.
* types. It
*
* @param {ActionRequest} originalRequest
* @param {BaseResource} resource
Expand All @@ -14,27 +15,29 @@ import BaseResource from '../adapters/base-resource'
const RequestParser = (originalRequest: ActionRequest, resource: BaseResource): ActionRequest => {
const { payload: originalPayload } = originalRequest

const payload = Object.entries(originalPayload || {}).reduce((memo, [path, value]) => {
const payload = Object.entries(originalPayload || {}).reduce((memo, [path, formValue]) => {
const property = resource.property(path)

let value = formValue
if (formValue === FORM_VALUE_NULL) { value = null }
if (formValue === FORM_VALUE_EMPTY_OBJECT) { value = {} }
if (formValue === FORM_VALUE_EMPTY_ARRAY) { value = [] }

if (property) {
if (property.type() === 'boolean') {
if (value === 'true') { return { ...memo, [path]: true } }
if (value === 'false') { return { ...memo, [path]: false } }
if (value === '') { return { ...memo, [path]: false } }
}
if (['date', 'datetime'].includes(property.type())) {
if (value === '') { return { ...memo, [path]: null } }
if (value === '' || value === null) { return { ...memo, [path]: null } }
}
if (property.type() === 'string') {
const availableValues = property.availableValues()
if (availableValues && !availableValues.includes(value) && value === '') {
return { ...memo, [path]: null }
}
}
if (property.isArray() && value === '') {
return { ...memo, [path]: [] }
}
}

return {
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/components/actions/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DrawerContent, Box, DrawerFooter, Button, Icon } from '@admin-bro/desig
import PropertyType from '../property-type'
import { ActionProps } from './action.props'
import ActionHeader from '../app/action-header'
import useRecord from '../../hooks/use-record'
import useRecord from '../../hooks/use-record/use-record'
import RecordJSON from '../../../backend/decorators/record-json.interface'
import { appendForceRefresh } from './utils/append-force-refresh'
import { useTranslation } from '../../hooks/use-translation'
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/components/actions/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PropertyType from '../property-type'
import { ActionProps } from './action.props'
import ActionHeader from '../app/action-header'
import RecordJSON from '../../../backend/decorators/record-json.interface'
import useRecord from '../../hooks/use-record'
import useRecord from '../../hooks/use-record/use-record'
import { appendForceRefresh } from './utils/append-force-refresh'
import { useTranslation } from '../../hooks/use-translation'

Expand Down
27 changes: 0 additions & 27 deletions src/frontend/components/actions/record-to-form-data.spec.ts

This file was deleted.

32 changes: 0 additions & 32 deletions src/frontend/components/actions/record-to-form-data.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import RecordJSON from '../../../../backend/decorators/record-json.interface'
import ViewHelpers from '../../../../backend/utils/view-helpers'
import { display } from './records-table-header'
import { ActionResponse, RecordActionResponse } from '../../../../backend/actions/action.interface'
import mergeRecordResponse from '../../../utils/merge-record-response'
import mergeRecordResponse from '../../../hooks/use-record/merge-record-response'

type Props = {
resource: ResourceJSON;
Expand Down
99 changes: 0 additions & 99 deletions src/frontend/components/app/sidebar/sidebar.spec.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/frontend/components/property-type/reference/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Edit: FC<CombinedProps> = (props) => {
if (selected) {
onChange(property.name, selected.value, selected.record)
} else {
onChange(property.name, '')
onChange(property.name, null)
}
}

Expand Down Expand Up @@ -87,6 +87,7 @@ const Edit: FC<CombinedProps> = (props) => {
defaultOptions
loadOptions={loadOptions}
onChange={handleChange}
isClearable
isDisabled={property.isDisabled}
isLoading={loadingRecord}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/components/routes/record-action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ActionHeader } from '../app'
import { useNotice, useTranslation } from '../../hooks'
import DrawerPortal from '../app/drawer-portal'
import { ActionResponse, RecordActionResponse } from '../../../backend/actions/action.interface'
import mergeRecordResponse from '../../utils/merge-record-response'
import mergeRecordResponse from '../../hooks/use-record/merge-record-response'

const api = new ApiClient()

Expand Down

0 comments on commit b8435de

Please sign in to comment.