Skip to content

Commit

Permalink
Allow Display in Details
Browse files Browse the repository at this point in the history
  • Loading branch information
hramezani committed May 30, 2024
1 parent 61d9b0c commit 8a37a71
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
23 changes: 18 additions & 5 deletions src/npm-fastui/src/components/details.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FC } from 'react'

import type { Details } from '../models'
import type { Details, Display, DisplayMode } from '../models'

import { asTitle } from '../tools'
import { useClassName } from '../hooks/className'
Expand All @@ -15,13 +15,26 @@ export const DetailsComp: FC<Details> = (props) => (
</dl>
)

const FieldDetail: FC<{ props: Details; fieldDisplay: DisplayLookupProps }> = ({ props, fieldDisplay }) => {
const { field, title, onClick, ...rest } = fieldDisplay
const value = props.data[field]
const FieldDetail: FC<{ props: Details; fieldDisplay: DisplayLookupProps | Display }> = ({ props, fieldDisplay }) => {
const onClick = fieldDisplay.onClick
let title = fieldDisplay.title
const rest: { mode?: DisplayMode; tableWidthPercent?: number } = { mode: fieldDisplay.mode }
let value: any

if ('type' in fieldDisplay && fieldDisplay.type === 'Display') {
// fieldDisplay is Display
value = fieldDisplay.value
} else if ('field' in fieldDisplay) {
// fieldDisplay is DisplayLookupProps
const field = fieldDisplay.field
title = title ?? asTitle(field)
value = props.data[field]
rest.tableWidthPercent = fieldDisplay.tableWidthPercent
}
const renderedOnClick = renderEvent(onClick, props.data)
return (
<>
<dt className={useClassName(props, { el: 'dt' })}>{title ?? asTitle(field)}</dt>
<dt className={useClassName(props, { el: 'dt' })}>{title}</dt>
<dd className={useClassName(props, { el: 'dd' })}>
<DisplayComp type="Display" onClick={renderedOnClick} value={value !== undefined ? value : null} {...rest} />
</dd>
Expand Down
2 changes: 1 addition & 1 deletion src/npm-fastui/src/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ export interface Display {
*/
export interface Details {
data: DataModel
fields: DisplayLookup[]
fields: (DisplayLookup | Display)[]
className?: ClassName
type: 'Details'
}
Expand Down
11 changes: 7 additions & 4 deletions src/python-fastui/fastui/components/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Details(BaseModel, extra='forbid'):
data: pydantic.SerializeAsAny[_types.DataModel]
"""Data model to display."""

fields: _t.Union[_t.List[DisplayLookup], None] = None
fields: _t.Union[_t.List[_t.Union[DisplayLookup, Display]], None] = None
"""Fields to display."""

class_name: _class_name.ClassNameField = None
Expand All @@ -86,9 +86,12 @@ def _fill_fields(self) -> _te.Self:
else:
# add pydantic titles to fields that don't have them
for field in (c for c in self.fields if c.title is None):
pydantic_field = self.data.model_fields.get(field.field)
if pydantic_field and pydantic_field.title:
field.title = pydantic_field.title
if isinstance(field, DisplayLookup):
pydantic_field = self.data.model_fields.get(field.field)
if pydantic_field and pydantic_field.title:
field.title = pydantic_field.title
elif isinstance(field, Display):
field.title = field.title
return self

@classmethod
Expand Down
22 changes: 22 additions & 0 deletions src/python-fastui/tests/test_tables_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,25 @@ def test_display_fields():
'fields': [{'title': 'ID', 'field': 'id'}, {'title': 'Name', 'field': 'name'}],
'type': 'Details',
}


def test_details_with_display_lookup_and_display():
d = components.Details(
data=users[0],
fields=[
display.DisplayLookup(field='id', title='ID'),
display.DisplayLookup(field='name'),
display.Display(value='display value', title='Display Title'),
],
)

# insert_assert(d.model_dump(by_alias=True, exclude_none=True))
assert d.model_dump(by_alias=True, exclude_none=True) == {
'data': {'id': 1, 'name': 'john', 'representation': '1: john'},
'fields': [
{'title': 'ID', 'field': 'id'},
{'title': 'Name', 'field': 'name'},
{'title': 'Display Title', 'value': 'display value', 'type': 'Display'},
],
'type': 'Details',
}

0 comments on commit 8a37a71

Please sign in to comment.