From d45d37cabf5350738bd02447db785e39c83f77f8 Mon Sep 17 00:00:00 2001 From: chenos Date: Sun, 13 Dec 2020 20:48:48 +0800 Subject: [PATCH] feat: add field renderer --- packages/app/src/components/views/Details.tsx | 6 +- .../app/src/components/views/Field/index.tsx | 134 ++++++++++++++++++ .../components/views/SortableTable/index.tsx | 6 +- packages/plugin-pages/src/actions/getView.ts | 8 +- 4 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 packages/app/src/components/views/Field/index.tsx diff --git a/packages/app/src/components/views/Details.tsx b/packages/app/src/components/views/Details.tsx index 20e77b3f48..a7e4967c10 100644 --- a/packages/app/src/components/views/Details.tsx +++ b/packages/app/src/components/views/Details.tsx @@ -4,6 +4,8 @@ import { Actions } from '@/components/actions'; import api from '@/api-client'; import { useRequest } from 'umi'; import { Spin } from '@nocobase/client'; +import Field from './Field'; +import get from 'lodash/get'; export function Details(props: any) { const { @@ -38,7 +40,9 @@ export function Details(props: any) { {fields.map((field: any) => { return ( - {JSON.stringify(data[field.name])} + + + ) })} diff --git a/packages/app/src/components/views/Field/index.tsx b/packages/app/src/components/views/Field/index.tsx new file mode 100644 index 0000000000..f5fa620c9d --- /dev/null +++ b/packages/app/src/components/views/Field/index.tsx @@ -0,0 +1,134 @@ + +import React, { useEffect, useState } from 'react'; +import moment from 'moment'; +import { Tag } from 'antd'; +import Icon from '@/components/icons'; + +const InterfaceTypes = new Map(); + +function registerFieldComponent(type, Component) { + InterfaceTypes.set(type, Component); +} + +function registerFieldComponents(components) { + Object.keys(components).forEach(key => { + registerFieldComponent(key, components[key]); + }); +} + +function getFieldComponent(type) { + if (InterfaceTypes.has(type)) { + return InterfaceTypes.get(type); + } + return InterfaceTypes.get('string'); +} + +export function StringField(props: any) { + const { value } = props; + return ( + <>{value} + ); +} + +export function TextareaField(props: any) { + const { value } = props; + return ( + <>{value} + ); +} + +export function BooleanField(props: any) { + const { value } = props; + return ( + <>{value ? '是' : '否'} + ); +} + +export function NumberField(props: any) { + const { schema: { precision }, value } = props; + return ( + <>{value} + ); +} + +export function PercentField(props: any) { + const { schema: { precision }, value } = props; + return ( + <>{value}% + ); +} + +export function DateTimeField(props: any) { + const { schema: { dateFormat, showTime, timeFormat }, value } = props; + const m = moment(value); + if (!m.isValid()) { + return null; + } + let format = dateFormat; + if (showTime) { + format += ` ${timeFormat}`; + } + return ( + <>{m.format(`${format}`)} + ); +} + +export function IconField(props) { + const { value } = props; + return ; +} + +function toFlat(items = []): Array { + let flat = []; + items.forEach(item => { + flat.push(item); + if (Array.isArray(item.children) && item.children.length) { + flat = flat.concat(toFlat(item.children)); + } + }); + return flat; +} + +export function DataSourceField(props: any) { + const { schema: { dataSource = [] }, value } = props; + const items = toFlat(dataSource); + console.log(items); + if (Array.isArray(value)) { + return value.map(val => { + const item = items.find(item => item.value === val); + return ( + + {item ? item.label : val} + + ) + }); + } + const item = items.find(item => item.value === value); + return ( + + {item ? item.label : value} + + ) +} + +registerFieldComponents({ + string: StringField, + textarea: TextareaField, + boolean: BooleanField, + select: DataSourceField, + multipleSelect: DataSourceField, + radio: DataSourceField, + checkboxes: DataSourceField, + number: NumberField, + percent: PercentField, + datetime: DateTimeField, + createdAt: DateTimeField, + updatedAt: DateTimeField, + icon: IconField, +}); + +export default function Field(props: any) { + const { schema = {} } = props; + const Component = getFieldComponent(schema.interface); + return ; +} diff --git a/packages/app/src/components/views/SortableTable/index.tsx b/packages/app/src/components/views/SortableTable/index.tsx index 358fe5f72b..07ebdcb0b1 100644 --- a/packages/app/src/components/views/SortableTable/index.tsx +++ b/packages/app/src/components/views/SortableTable/index.tsx @@ -6,6 +6,7 @@ import arrayMove from 'array-move'; import findIndex from 'lodash/findIndex'; import get from 'lodash/get'; import './style.less'; +import Field from '../Field'; export const SortableItem = sortableElement(props => ); export const SortableContainer = sortableContainer(props => ); @@ -55,10 +56,7 @@ export const components = ({data = {}, rowKey, mutate, onMoved}: Props) => { export function fields2columns(fields) { const columns: any[] = fields.map(field => { - const type = get(field, 'component.type'); - if (type === 'sort') { - field.render = () => ; - } + field.render = (value) => field.interface === 'sort' ? : ; return { ...field, ...(field.component||{}), diff --git a/packages/plugin-pages/src/actions/getView.ts b/packages/plugin-pages/src/actions/getView.ts index 75113a651a..24f6608841 100644 --- a/packages/plugin-pages/src/actions/getView.ts +++ b/packages/plugin-pages/src/actions/getView.ts @@ -12,7 +12,7 @@ const transforms = { arr.push({ ...field.get(), sorter: field.get('sortable'), - dataIndex: field.name, + dataIndex: field.name.split('.'), }); } return arr; @@ -72,6 +72,9 @@ const transforms = { set(prop, 'x-component-props.children', prop.title); delete prop.title; } + if (interfaceType === 'multipleSelect') { + set(prop, 'x-component-props.mode', 'multiple'); + } if (['radio', 'select', 'multipleSelect', 'checkboxes'].includes(interfaceType)) { prop.enum = get(field.options, 'dataSource', []); } @@ -159,6 +162,9 @@ export default async (ctx, next) => { }); view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name'])); } + if (view.get('template') === 'SimpleTable') { + view.setDataValue('rowViewName', 'form'); + } if (view.get('updateViewName')) { view.setDataValue('rowViewName', view.get('updateViewName')); }