mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-12 01:47:08 +00:00
refactor
This commit is contained in:
parent
222f3b2108
commit
96e5d065ce
@ -1,9 +1,9 @@
|
||||
import { CarouselConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo, PropsWithChildren } from 'react';
|
||||
import { Carousel } from 'zarm';
|
||||
import styles from './index.less';
|
||||
import { ICarouselConfig } from './schema';
|
||||
|
||||
interface CarouselTypes extends CarouselConfigType {
|
||||
interface CarouselTypes extends ICarouselConfig {
|
||||
isTpl: boolean;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,31 @@
|
||||
const Carousel = {
|
||||
import {
|
||||
IDataListConfigType,
|
||||
IRadioConfigType,
|
||||
ISwitchConfigType,
|
||||
TDataListDefaultType,
|
||||
TRadioDefaultType,
|
||||
TSwitchDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type CarouselDirectionKeyType = 'down' | 'left';
|
||||
|
||||
export type TCarouselEditData = Array<
|
||||
IRadioConfigType<CarouselDirectionKeyType> | ISwitchConfigType | IDataListConfigType
|
||||
>;
|
||||
export interface ICarouselConfig {
|
||||
direction: TRadioDefaultType<CarouselDirectionKeyType>;
|
||||
swipeable: TSwitchDefaultType;
|
||||
autoPlay: TSwitchDefaultType;
|
||||
imgList: TDataListDefaultType;
|
||||
tplImg: string;
|
||||
}
|
||||
|
||||
export interface ICarouselSchema {
|
||||
editData: TCarouselEditData;
|
||||
config: ICarouselConfig;
|
||||
}
|
||||
|
||||
const Carousel: ICarouselSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'direction',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { FooterConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
const Footer = memo((props: FooterConfigType) => {
|
||||
import { IFooterConfig } from './schema';
|
||||
const Footer = memo((props: IFooterConfig) => {
|
||||
const { bgColor, text, color, align, fontSize, height } = props;
|
||||
return (
|
||||
<footer
|
||||
|
||||
@ -1,4 +1,34 @@
|
||||
const Footer = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ISelectConfigType,
|
||||
ITextConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TSelectDefaultType,
|
||||
TTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TfooterSelectKeyType = 'left' | 'center' | 'right';
|
||||
|
||||
export type TFooterEditData = Array<
|
||||
IColorConfigType | INumberConfigType | ITextConfigType | ISelectConfigType<TfooterSelectKeyType>
|
||||
>;
|
||||
export interface IFooterConfig {
|
||||
bgColor: TColorDefaultType;
|
||||
text: TTextDefaultType;
|
||||
color: TColorDefaultType;
|
||||
align: TSelectDefaultType<TfooterSelectKeyType>;
|
||||
fontSize: TNumberDefaultType;
|
||||
height: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface IFooterSchema {
|
||||
editData: TFooterEditData;
|
||||
config: IFooterConfig;
|
||||
}
|
||||
|
||||
const Footer: IFooterSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'bgColor',
|
||||
|
||||
@ -1,9 +1,23 @@
|
||||
import { Input, Cell, DateSelect, Radio, Select } from 'zarm';
|
||||
import styles from './baseForm.less';
|
||||
import React from 'react';
|
||||
import {
|
||||
baseFormDateTpl,
|
||||
baseFormMyRadioTpl,
|
||||
baseFormMySelectTpl,
|
||||
baseFormNumberTpl,
|
||||
baseFormTextAreaTpl,
|
||||
baseFormTextTpl,
|
||||
baseFormUnionType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
// 维护表单控件, 提高form渲染性能
|
||||
const BaseForm = {
|
||||
Text: props => {
|
||||
|
||||
type TBaseForm = {
|
||||
[key in baseFormUnionType]: any;
|
||||
};
|
||||
|
||||
const BaseForm: TBaseForm = {
|
||||
Text: (props: baseFormTextTpl & { onChange: (v: string | undefined) => void }) => {
|
||||
const { label, placeholder, onChange } = props;
|
||||
return (
|
||||
<Cell title={label}>
|
||||
@ -11,7 +25,7 @@ const BaseForm = {
|
||||
</Cell>
|
||||
);
|
||||
},
|
||||
Textarea: props => {
|
||||
Textarea: (props: baseFormTextAreaTpl & { onChange: (v: string | undefined) => void }) => {
|
||||
const { label, placeholder, onChange } = props;
|
||||
return (
|
||||
<Cell title={label}>
|
||||
@ -26,7 +40,7 @@ const BaseForm = {
|
||||
</Cell>
|
||||
);
|
||||
},
|
||||
Number: props => {
|
||||
Number: (props: baseFormNumberTpl & { onChange: (v: string | undefined | number) => void }) => {
|
||||
const { label, placeholder, onChange } = props;
|
||||
return (
|
||||
<Cell title={label}>
|
||||
@ -34,7 +48,7 @@ const BaseForm = {
|
||||
</Cell>
|
||||
);
|
||||
},
|
||||
MyRadio: props => {
|
||||
MyRadio: (props: baseFormMyRadioTpl & { onChange: (v: string | undefined | number) => void }) => {
|
||||
const { label, options, onChange } = props;
|
||||
return (
|
||||
<div className={styles.radioWrap}>
|
||||
@ -53,7 +67,7 @@ const BaseForm = {
|
||||
</div>
|
||||
);
|
||||
},
|
||||
Date: props => {
|
||||
Date: (props: baseFormDateTpl & { onChange: (v: Date) => void }) => {
|
||||
const { label, placeholder, onChange } = props;
|
||||
return (
|
||||
<Cell title={label}>
|
||||
@ -67,7 +81,9 @@ const BaseForm = {
|
||||
</Cell>
|
||||
);
|
||||
},
|
||||
MySelect: props => {
|
||||
MySelect: (
|
||||
props: baseFormMySelectTpl & { onChange: ((v: Record<string, any>) => void) | undefined },
|
||||
) => {
|
||||
const { label, options, onChange } = props;
|
||||
return (
|
||||
<Cell title={label}>
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
import React, { memo, useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { Button } from 'zarm';
|
||||
import BaseForm from './BaseForm';
|
||||
import req from 'utils/req';
|
||||
import styles from './index.less';
|
||||
import { IFormConfig } from './schema';
|
||||
|
||||
function unParams(params = '?a=1&b=2&c=3') {
|
||||
let obj = {};
|
||||
params &&
|
||||
params.replace(/((\w*)=([\.a-z0-9A-Z]*)?)?/g, (m, a, b, c) => {
|
||||
if (b || c) obj[b] = c;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
const FormComponent = props => {
|
||||
const FormComponent = (props: IFormConfig) => {
|
||||
const { title, bgColor, fontSize, titColor, btnColor, btnTextColor, api, formControls } = props;
|
||||
const formData = {};
|
||||
const formData: Record<string, any> = {};
|
||||
const handleChange = useCallback(
|
||||
(item, v) => {
|
||||
if (item.options) {
|
||||
|
||||
@ -1,4 +1,34 @@
|
||||
const Form = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
IFormItemsConfigType,
|
||||
INumberConfigType,
|
||||
ITextConfigType,
|
||||
TColorDefaultType,
|
||||
TFormItemsDefaultType,
|
||||
TNumberDefaultType,
|
||||
TTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TFormEditData = Array<
|
||||
ITextConfigType | INumberConfigType | IColorConfigType | ITextConfigType | IFormItemsConfigType
|
||||
>;
|
||||
export interface IFormConfig {
|
||||
title: TTextDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
titColor: TColorDefaultType;
|
||||
bgColor: TColorDefaultType;
|
||||
btnColor: TColorDefaultType;
|
||||
btnTextColor: TColorDefaultType;
|
||||
api: TTextDefaultType;
|
||||
formControls: TFormItemsDefaultType;
|
||||
}
|
||||
|
||||
export interface IFormSchema {
|
||||
editData: TFormEditData;
|
||||
config: IFormConfig;
|
||||
}
|
||||
|
||||
const Form: IFormSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'title',
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
import React from 'react';
|
||||
import { HeaderConfigType } from '@/components/DynamicEngine/schema';
|
||||
import { IHeaderConfig } from './schema';
|
||||
|
||||
const Header = memo((props: HeaderConfigType) => {
|
||||
const Header = memo((props: IHeaderConfig) => {
|
||||
const { bgColor, logo, logoText, fontSize, color } = props;
|
||||
return (
|
||||
<header className={styles.header} style={{ backgroundColor: bgColor }}>
|
||||
|
||||
@ -1,4 +1,32 @@
|
||||
const Header = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ITextConfigType,
|
||||
IUploadConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TTextDefaultType,
|
||||
TUploadDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type THeaderEditData = Array<
|
||||
IColorConfigType | INumberConfigType | IUploadConfigType | ITextConfigType
|
||||
>;
|
||||
export interface IHeaderConfig {
|
||||
bgColor: TColorDefaultType;
|
||||
logo: TUploadDefaultType;
|
||||
logoText: TTextDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
color: TColorDefaultType;
|
||||
height: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface IHeaderSchema {
|
||||
editData: THeaderEditData;
|
||||
config: IHeaderConfig;
|
||||
}
|
||||
|
||||
const Header: IHeaderSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'bgColor',
|
||||
|
||||
@ -2,13 +2,11 @@ import React, { memo } from 'react';
|
||||
import * as Icon from '@ant-design/icons';
|
||||
import IconImg from 'assets/icon.png';
|
||||
import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon';
|
||||
import { IconConfigType } from '../../../DynamicEngine/schema';
|
||||
import { AntdIconType } from './icon';
|
||||
import { IIconConfig } from './schema';
|
||||
|
||||
interface IconType extends Omit<IconConfigType, 'spin' | 'color'> {
|
||||
interface IconType extends IIconConfig {
|
||||
isTpl?: boolean;
|
||||
spin?: IconConfigType['spin'];
|
||||
color?: IconConfigType['color'];
|
||||
}
|
||||
const XIcon = memo((props: IconType) => {
|
||||
const { color, size, type, spin, isTpl } = props;
|
||||
|
||||
@ -1,3 +1,29 @@
|
||||
import {
|
||||
ICardPickerConfigType,
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ISwitchConfigType,
|
||||
TCardPickerDefaultType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TSwitchDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TIconEditData = Array<
|
||||
IColorConfigType | INumberConfigType | ISwitchConfigType | ICardPickerConfigType<IconTypes>
|
||||
>;
|
||||
export interface IIconConfig {
|
||||
color: TColorDefaultType;
|
||||
size: TNumberDefaultType;
|
||||
spin: TSwitchDefaultType;
|
||||
type: TCardPickerDefaultType<IconTypes>;
|
||||
}
|
||||
|
||||
export interface IIconSchema {
|
||||
editData: TIconEditData;
|
||||
config: IIconConfig;
|
||||
}
|
||||
|
||||
export type IconTypes =
|
||||
| 'AccountBookTwoTone'
|
||||
| 'AlertTwoTone'
|
||||
@ -41,7 +67,7 @@ export type IconTypes =
|
||||
| 'SettingTwoTone'
|
||||
| 'RocketTwoTone';
|
||||
|
||||
const Icon = {
|
||||
const Icon: IIconSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'color',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ImageConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
const Image = memo((props: ImageConfigType) => {
|
||||
import { IImageConfig } from './schema';
|
||||
const Image = memo((props: IImageConfig) => {
|
||||
const { imgUrl, round = 0 } = props;
|
||||
return (
|
||||
<div style={{ borderRadius: round, width: '100%', textAlign: 'center', overflow: 'hidden' }}>
|
||||
|
||||
@ -1,4 +1,22 @@
|
||||
const Image = {
|
||||
import {
|
||||
INumberConfigType,
|
||||
IUploadConfigType,
|
||||
TNumberDefaultType,
|
||||
TUploadDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TImageEditData = Array<IUploadConfigType | INumberConfigType>;
|
||||
export interface IImageConfig {
|
||||
imgUrl: TUploadDefaultType;
|
||||
round: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface IImageSchema {
|
||||
editData: TImageEditData;
|
||||
config: IImageConfig;
|
||||
}
|
||||
|
||||
const Image: IImageSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'imgUrl',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ListConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
const List = memo((props: ListConfigType) => {
|
||||
import { IListConfig } from './schema';
|
||||
const List = memo((props: IListConfig) => {
|
||||
const { round, sourceData, imgSize, fontSize, color } = props;
|
||||
return (
|
||||
<div className={styles.list}>
|
||||
@ -18,7 +18,7 @@ const List = memo((props: ListConfigType) => {
|
||||
}
|
||||
alt={item.desc}
|
||||
style={{
|
||||
width: imgSize,
|
||||
width: parseFloat(imgSize),
|
||||
height: imgSize,
|
||||
objectFit: 'cover',
|
||||
borderRadius: round,
|
||||
|
||||
@ -1,4 +1,31 @@
|
||||
const List = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
IDataListConfigType,
|
||||
INumberConfigType,
|
||||
ISelectConfigType,
|
||||
TColorDefaultType,
|
||||
TDataListDefaultType,
|
||||
TNumberDefaultType,
|
||||
TSelectDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
export type TListSelectKeyType = '60' | '80' | '100' | '120' | '150';
|
||||
export type TListEditData = Array<
|
||||
IColorConfigType | IDataListConfigType | INumberConfigType | ISelectConfigType<TListSelectKeyType>
|
||||
>;
|
||||
export interface IListConfig {
|
||||
sourceData: TDataListDefaultType;
|
||||
round: TNumberDefaultType;
|
||||
imgSize: TSelectDefaultType<TListSelectKeyType>;
|
||||
fontSize: TNumberDefaultType;
|
||||
color: TColorDefaultType;
|
||||
}
|
||||
|
||||
export interface IListSchema {
|
||||
editData: TListEditData;
|
||||
config: IListConfig;
|
||||
}
|
||||
|
||||
const List: IListSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'sourceData',
|
||||
@ -16,23 +43,23 @@ const List = {
|
||||
type: 'Select',
|
||||
range: [
|
||||
{
|
||||
key: 60,
|
||||
key: '60',
|
||||
text: '60 x 60',
|
||||
},
|
||||
{
|
||||
key: 80,
|
||||
key: '80',
|
||||
text: '80 x 80',
|
||||
},
|
||||
{
|
||||
key: 100,
|
||||
key: '100',
|
||||
text: '100 x 100',
|
||||
},
|
||||
{
|
||||
key: 120,
|
||||
key: '120',
|
||||
text: '120 x 120',
|
||||
},
|
||||
{
|
||||
key: 150,
|
||||
key: '150',
|
||||
text: '150 x 150',
|
||||
},
|
||||
],
|
||||
@ -80,7 +107,7 @@ const List = {
|
||||
},
|
||||
],
|
||||
round: 0,
|
||||
imgSize: 80,
|
||||
imgSize: '80',
|
||||
fontSize: 16,
|
||||
color: 'rgba(153,153,153,1)',
|
||||
},
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { LongTextConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
const LongText = memo((props: LongTextConfigType) => {
|
||||
import { ILongTextConfig } from './schema';
|
||||
const LongText = memo((props: ILongTextConfig) => {
|
||||
const { text, fontSize, color, indent, lineHeight, textAlign } = props;
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -1,4 +1,36 @@
|
||||
const LongText = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ISelectConfigType,
|
||||
ITextAreaConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TSelectDefaultType,
|
||||
TTextAreaDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
export type TLongTextSelectKeyType = 'left' | 'center' | 'right';
|
||||
|
||||
export type TLongTextEditData = Array<
|
||||
| ITextAreaConfigType
|
||||
| IColorConfigType
|
||||
| INumberConfigType
|
||||
| ISelectConfigType<TLongTextSelectKeyType>
|
||||
>;
|
||||
export interface ILongTextConfig {
|
||||
text: TTextAreaDefaultType;
|
||||
color: TColorDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
indent: TNumberDefaultType;
|
||||
lineHeight: TNumberDefaultType;
|
||||
textAlign: TSelectDefaultType<TLongTextSelectKeyType>;
|
||||
}
|
||||
|
||||
export interface ILongTextSchema {
|
||||
editData: TLongTextEditData;
|
||||
config: ILongTextConfig;
|
||||
}
|
||||
|
||||
const LongText: ILongTextSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'text',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { NoticeBar } from 'zarm';
|
||||
import React, { memo } from 'react';
|
||||
import { NoticeConfigType } from '@/components/DynamicEngine/schema';
|
||||
const Notice = memo((props: NoticeConfigType) => {
|
||||
import { INoticeConfig } from './schema';
|
||||
const Notice = memo((props: INoticeConfig) => {
|
||||
const { text, speed, theme, isClose = false } = props;
|
||||
return (
|
||||
<NoticeBar theme={theme === 'default' ? undefined : theme} closable={isClose} speed={speed}>
|
||||
|
||||
@ -1,4 +1,31 @@
|
||||
const Notice = {
|
||||
import {
|
||||
INumberConfigType,
|
||||
ISelectConfigType,
|
||||
ISwitchConfigType,
|
||||
ITextConfigType,
|
||||
TNumberDefaultType,
|
||||
TSelectDefaultType,
|
||||
TSwitchDefaultType,
|
||||
TTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TNoticeSelectKeyType = 'default' | 'warning' | 'primary' | 'success' | 'danger';
|
||||
export type TNoticeEditData = Array<
|
||||
ITextConfigType | INumberConfigType | ISelectConfigType<TNoticeSelectKeyType> | ISwitchConfigType
|
||||
>;
|
||||
export interface INoticeConfig {
|
||||
text: TTextDefaultType;
|
||||
speed: TNumberDefaultType;
|
||||
theme: TSelectDefaultType<TNoticeSelectKeyType>;
|
||||
isClose: TSwitchDefaultType;
|
||||
}
|
||||
|
||||
export interface INoticeSchema {
|
||||
editData: TNoticeEditData;
|
||||
config: INoticeConfig;
|
||||
}
|
||||
|
||||
const Notice: INoticeSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'text',
|
||||
@ -45,7 +72,6 @@ const Notice = {
|
||||
],
|
||||
config: {
|
||||
text: '通知栏: 趣谈前端上线啦',
|
||||
link: '',
|
||||
speed: 50,
|
||||
theme: 'warning',
|
||||
isClose: false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { QRCodeConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import { IQrcodeConfig } from './schema';
|
||||
|
||||
const Qrcode = memo((props: QRCodeConfigType) => {
|
||||
const Qrcode = memo((props: IQrcodeConfig) => {
|
||||
const { qrcode, text, color, fontSize = 14 } = props;
|
||||
return (
|
||||
<div style={{ width: '240px', margin: '16px auto' }}>
|
||||
|
||||
@ -1,4 +1,30 @@
|
||||
const Qrcode = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ITextConfigType,
|
||||
IUploadConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TTextDefaultType,
|
||||
TUploadDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TQrcodeEditData = Array<
|
||||
IUploadConfigType | ITextConfigType | IColorConfigType | INumberConfigType
|
||||
>;
|
||||
export interface IQrcodeConfig {
|
||||
qrcode: TUploadDefaultType;
|
||||
text: TTextDefaultType;
|
||||
color: TColorDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface IQrcodeSchema {
|
||||
editData: TQrcodeEditData;
|
||||
config: IQrcodeConfig;
|
||||
}
|
||||
|
||||
const Qrcode: IQrcodeSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'qrcode',
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { TabConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { Tabs } from 'zarm';
|
||||
import styles from './index.less';
|
||||
import { ITabConfig } from './schema';
|
||||
|
||||
const { Panel } = Tabs;
|
||||
|
||||
const XTab = (props: TabConfigType) => {
|
||||
const XTab = (props: ITabConfig) => {
|
||||
const { tabs = ['分类一', '分类二'], activeColor, color, fontSize, sourceData } = props;
|
||||
|
||||
const tabWrapRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -1,4 +1,32 @@
|
||||
const Tab = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
IDataListConfigType,
|
||||
IMutiTextConfigType,
|
||||
INumberConfigType,
|
||||
TColorDefaultType,
|
||||
TDataListDefaultType,
|
||||
TMutiTextDefaultType,
|
||||
TNumberDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TTabEditData = Array<
|
||||
IMutiTextConfigType | IColorConfigType | INumberConfigType | IDataListConfigType
|
||||
>;
|
||||
export interface ITabConfig {
|
||||
tabs: TMutiTextDefaultType;
|
||||
color: TColorDefaultType;
|
||||
activeColor: TColorDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
imgSize: TNumberDefaultType;
|
||||
sourceData: TDataListDefaultType;
|
||||
}
|
||||
|
||||
export interface ITabSchema {
|
||||
editData: TTabEditData;
|
||||
config: ITabConfig;
|
||||
}
|
||||
|
||||
const Tab: ITabSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'tabs',
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { TextConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
import { ITextConfig } from './schema';
|
||||
|
||||
const Text = memo((props: TextConfigType) => {
|
||||
const Text = memo((props: ITextConfig) => {
|
||||
const { align, text, fontSize, color, lineHeight } = props;
|
||||
return (
|
||||
<div className={styles.textWrap} style={{ color, textAlign: align, fontSize, lineHeight }}>
|
||||
|
||||
@ -1,4 +1,31 @@
|
||||
const Text = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ISelectConfigType,
|
||||
ITextConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TSelectDefaultType,
|
||||
TTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TTextSelectKeyType = 'left' | 'right' | 'center';
|
||||
export type TTextEditData = Array<
|
||||
ITextConfigType | IColorConfigType | INumberConfigType | ISelectConfigType<TTextSelectKeyType>
|
||||
>;
|
||||
export interface ITextConfig {
|
||||
text: TTextDefaultType;
|
||||
color: TColorDefaultType;
|
||||
fontSize: TNumberDefaultType;
|
||||
align: TSelectDefaultType<TTextSelectKeyType>;
|
||||
lineHeight: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface ITextSchema {
|
||||
editData: TTextEditData;
|
||||
config: ITextConfig;
|
||||
}
|
||||
const Text: ITextSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'text',
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { VideoConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import { Player, BigPlayButton } from 'video-react';
|
||||
import './index.css';
|
||||
import { IVideoConfig } from './schema';
|
||||
|
||||
const VideoPlayer = memo((props: VideoConfigType) => {
|
||||
const VideoPlayer = memo((props: IVideoConfig) => {
|
||||
const { poster, url } = props;
|
||||
return (
|
||||
<div>
|
||||
|
||||
@ -1,4 +1,22 @@
|
||||
const Video = {
|
||||
import {
|
||||
ITextConfigType,
|
||||
IUploadConfigType,
|
||||
TTextDefaultType,
|
||||
TUploadDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TVideoEditData = Array<IUploadConfigType | ITextConfigType>;
|
||||
export interface IVideoConfig {
|
||||
poster: TUploadDefaultType;
|
||||
url: TTextDefaultType;
|
||||
}
|
||||
|
||||
export interface IVideoSchema {
|
||||
editData: TVideoEditData;
|
||||
config: IVideoConfig;
|
||||
}
|
||||
|
||||
const Video: IVideoSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'poster',
|
||||
|
||||
@ -1,25 +1,16 @@
|
||||
import { Chart } from '@antv/f2';
|
||||
import React, { memo, PropsWithChildren, useEffect, useRef } from 'react';
|
||||
import React, { memo, useEffect, useRef } from 'react';
|
||||
// import { uuid } from 'utils/tool';
|
||||
import ChartImg from '@/assets/chart.png';
|
||||
|
||||
import styles from './index.less';
|
||||
import { IChartConfig } from './schema';
|
||||
|
||||
type DataItem = {
|
||||
name: string;
|
||||
value: number;
|
||||
};
|
||||
|
||||
interface XChartProps {
|
||||
interface XChartProps extends IChartConfig {
|
||||
isTpl: boolean;
|
||||
title: string;
|
||||
color: string;
|
||||
size: number;
|
||||
paddingTop: number;
|
||||
data: Array<DataItem>;
|
||||
}
|
||||
|
||||
const XChart = (props: PropsWithChildren<XChartProps>) => {
|
||||
const XChart = (props: XChartProps) => {
|
||||
const { isTpl, data, color, size, paddingTop, title } = props;
|
||||
const chartRef = useRef(null);
|
||||
useEffect(() => {
|
||||
@ -44,7 +35,7 @@ const XChart = (props: PropsWithChildren<XChartProps>) => {
|
||||
// Step 4: 渲染图表
|
||||
chart.render();
|
||||
}
|
||||
}, []);
|
||||
}, [data, isTpl]);
|
||||
return (
|
||||
<div className={styles.chartWrap}>
|
||||
<div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>
|
||||
|
||||
@ -1,4 +1,31 @@
|
||||
const Chart = {
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ITableConfigType,
|
||||
ITextConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TTableDefaultType,
|
||||
TTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TChartEditData = Array<
|
||||
ITextConfigType | INumberConfigType | IColorConfigType | ITableConfigType
|
||||
>;
|
||||
export interface IChartConfig {
|
||||
title: TTextDefaultType;
|
||||
size: TNumberDefaultType;
|
||||
color: TColorDefaultType;
|
||||
paddingTop: TNumberDefaultType;
|
||||
data: TTableDefaultType;
|
||||
}
|
||||
|
||||
export interface IChartSchema {
|
||||
editData: TChartEditData;
|
||||
config: IChartConfig;
|
||||
}
|
||||
|
||||
const Chart: IChartSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'title',
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { XProgressConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import { Progress } from 'zarm';
|
||||
import styles from './index.less';
|
||||
import { IXProgressConfig } from './schema';
|
||||
|
||||
const XProgress = memo((props: XProgressConfigType) => {
|
||||
const XProgress = memo((props: IXProgressConfig) => {
|
||||
const { theme, size, shape, percent, strokeWidth } = props;
|
||||
return (
|
||||
<div className={styles.textWrap} style={{ textAlign: 'center' }}>
|
||||
|
||||
@ -1,4 +1,32 @@
|
||||
const XProgress = {
|
||||
import {
|
||||
INumberConfigType,
|
||||
IRadioConfigType,
|
||||
ISelectConfigType,
|
||||
TNumberDefaultType,
|
||||
TRadioDefaultType,
|
||||
TSelectDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
export type TXProgressSelectKeyType = 'success' | 'warning' | 'danger';
|
||||
export type TXProgressRadiotKeyType = 'circle' | 'line' | 'semi-circle';
|
||||
export type TXProgressEditData = Array<
|
||||
| ISelectConfigType<TXProgressSelectKeyType>
|
||||
| IRadioConfigType<TXProgressRadiotKeyType>
|
||||
| INumberConfigType
|
||||
>;
|
||||
export interface IXProgressConfig {
|
||||
theme: TSelectDefaultType<TXProgressSelectKeyType>;
|
||||
shape: TRadioDefaultType<TXProgressRadiotKeyType>;
|
||||
size: TNumberDefaultType;
|
||||
percent: TNumberDefaultType;
|
||||
strokeWidth: TNumberDefaultType;
|
||||
}
|
||||
|
||||
export interface IXProgressSchema {
|
||||
editData: TXProgressEditData;
|
||||
config: IXProgressConfig;
|
||||
}
|
||||
|
||||
const XProgress: IXProgressSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'theme',
|
||||
|
||||
@ -2,18 +2,17 @@ import { useState, useEffect, memo } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Icon from '../../BasicShop/BasicComponents/Icon';
|
||||
import styles from './index.less';
|
||||
import { IconTypes } from '../../DynamicEngine/schema';
|
||||
import React from 'react';
|
||||
import { IconTypes } from '@/components/BasicShop/BasicComponents/Icon/schema';
|
||||
import { ICardPickerConfigType } from '../FormEditor/types';
|
||||
|
||||
interface CardPickerType {
|
||||
type: IconTypes;
|
||||
icons: Array<IconTypes>;
|
||||
interface CardPickerType extends Omit<ICardPickerConfigType<IconTypes>, 'type' | 'key' | 'name'> {
|
||||
onChange?: (v: string) => void;
|
||||
type: IconTypes;
|
||||
}
|
||||
|
||||
export default memo((props: CardPickerType) => {
|
||||
const { type, icons, onChange } = props;
|
||||
console.log(type);
|
||||
const [selected, setSelected] = useState<IconTypes>(type);
|
||||
|
||||
const handlePicker = (v: IconTypes) => {
|
||||
@ -37,7 +36,7 @@ export default memo((props: CardPickerType) => {
|
||||
onClick={() => handlePicker(item)}
|
||||
key={i}
|
||||
>
|
||||
<Icon type={item} size={20} />
|
||||
<Icon type={item} size={20} color={'#4091f7'} spin={false} />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
import React, { memo, useEffect, FC } from 'react';
|
||||
import { Form, Select, Input, Modal } from 'antd';
|
||||
import Upload from '../Upload';
|
||||
import { BasicDataSource } from '../../DynamicEngine/schema';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
|
||||
import { TDataListDefaultTypeItem } from '../FormEditor/types';
|
||||
// import styles from './index.less';
|
||||
const normFile = (e: any) => {
|
||||
console.log('Upload event:', e);
|
||||
console.log('ffffffffff'); //待修改?
|
||||
if (Array.isArray(e)) {
|
||||
return e;
|
||||
}
|
||||
@ -24,7 +21,7 @@ const formItemLayout = {
|
||||
export type EditorModalProps = {
|
||||
visible: boolean;
|
||||
onCancel: ((e: React.MouseEvent<HTMLElement, MouseEvent>) => void) | undefined;
|
||||
item?: BasicDataSource;
|
||||
item?: TDataListDefaultTypeItem;
|
||||
onSave: Function;
|
||||
};
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import EditorModal from './editorModal';
|
||||
import { uuid } from '@/utils/tool';
|
||||
import styles from './index.less';
|
||||
import { BasicDataSource } from '../../DynamicEngine/schema';
|
||||
import { TDataListDefaultType, TDataListDefaultTypeItem } from '../FormEditor/types';
|
||||
|
||||
type ListItemProps = DndItemProps & {
|
||||
isDragging: boolean;
|
||||
@ -66,7 +66,7 @@ function ListItem(props: ListItemProps) {
|
||||
);
|
||||
}
|
||||
|
||||
type DndItemProps = BasicDataSource & {
|
||||
type DndItemProps = TDataListDefaultTypeItem & {
|
||||
onDel: Function;
|
||||
onEdit: Function;
|
||||
key: number;
|
||||
@ -127,8 +127,8 @@ const DndItem = DropTarget(
|
||||
)(DragSource(type, dragSpec, dragCollect)(ListItem));
|
||||
|
||||
export type DataListMemo = {
|
||||
onChange?: (v: BasicDataSource[]) => void;
|
||||
value?: BasicDataSource[];
|
||||
onChange?: (v: TDataListDefaultType) => void;
|
||||
value?: TDataListDefaultType;
|
||||
};
|
||||
|
||||
export type DataListType = DataListMemo & {
|
||||
@ -139,7 +139,7 @@ const List = function(props: DataListType) {
|
||||
const { onChange, value, connectDropTarget } = props;
|
||||
const [list, setList] = useState(value);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [curItem, setCurItem] = useState<BasicDataSource>();
|
||||
const [curItem, setCurItem] = useState<TDataListDefaultTypeItem>();
|
||||
|
||||
const handleDel = (id: string) => {
|
||||
if (value && onChange) {
|
||||
@ -172,13 +172,13 @@ const List = function(props: DataListType) {
|
||||
setVisible(false);
|
||||
}, []);
|
||||
|
||||
const handleEdit = useCallback((item: BasicDataSource) => {
|
||||
const handleEdit = useCallback((item: TDataListDefaultTypeItem) => {
|
||||
setVisible(true);
|
||||
setCurItem(item);
|
||||
}, []);
|
||||
|
||||
const handleSave = useCallback(
|
||||
(item: BasicDataSource) => {
|
||||
(item: TDataListDefaultTypeItem) => {
|
||||
setVisible(false);
|
||||
if (onChange) {
|
||||
onChange(list!.map(p => (p.id === item.id ? item : p)));
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { memo, useState, useEffect } from 'react';
|
||||
import React, { memo, useEffect } from 'react';
|
||||
import { Form, Select, InputNumber, Input, Switch, Radio, Button } from 'antd';
|
||||
import Upload from '../Upload';
|
||||
import DataList from '../DataList';
|
||||
@ -7,7 +7,6 @@ import Color from '../Color';
|
||||
import CardPicker from '../CardPicker';
|
||||
import Table from '../Table';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
import { BasicRangeType, IconSchema } from '../../DynamicEngine/schema';
|
||||
import FormItems from '../FormItems';
|
||||
// import styles from './index.less';
|
||||
const normFile = (e: any) => {
|
||||
@ -37,6 +36,7 @@ interface FormEditorProps {
|
||||
|
||||
const FormEditor = (props: FormEditorProps) => {
|
||||
const { config, defaultValue, onSave, onDel, uid } = props;
|
||||
console.log(defaultValue, config);
|
||||
const onFinish = (values: Store) => {
|
||||
onSave && onSave(values);
|
||||
};
|
||||
@ -51,7 +51,7 @@ const FormEditor = (props: FormEditorProps) => {
|
||||
return () => {
|
||||
form.resetFields();
|
||||
};
|
||||
}, [defaultValue]);
|
||||
}, [defaultValue, form]);
|
||||
return (
|
||||
<Form
|
||||
form={form}
|
||||
@ -96,7 +96,7 @@ const FormEditor = (props: FormEditorProps) => {
|
||||
{item.type === 'Select' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Select placeholder="请选择">
|
||||
{item.range.map((v: BasicRangeType<string>, i: number) => {
|
||||
{item.range.map((v: any, i: number) => {
|
||||
return (
|
||||
<Option value={v.key} key={i}>
|
||||
{v.text}
|
||||
@ -109,7 +109,7 @@ const FormEditor = (props: FormEditorProps) => {
|
||||
{item.type === 'Radio' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Radio.Group>
|
||||
{item.range.map((v: BasicRangeType<string>, i: number) => {
|
||||
{item.range.map((v: any, i: number) => {
|
||||
return (
|
||||
<Radio value={v.key} key={i}>
|
||||
{v.text}
|
||||
@ -136,10 +136,7 @@ const FormEditor = (props: FormEditorProps) => {
|
||||
)}
|
||||
{item.type === 'CardPicker' && (
|
||||
<Form.Item label={item.name} name={item.key} valuePropName="type">
|
||||
<CardPicker
|
||||
icons={item.icons}
|
||||
type={defaultValue['type'] as IconSchema['config']['type']}
|
||||
/>
|
||||
<CardPicker icons={item.icons} type={defaultValue['type']} />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Table' && (
|
||||
|
||||
@ -1,14 +1,199 @@
|
||||
export interface ItextAreaConfigType {
|
||||
////////////////////
|
||||
export interface IUploadConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Upload';
|
||||
isCrop?: boolean;
|
||||
cropRate?: number;
|
||||
}
|
||||
|
||||
export type TUploadDefaultType = Array<{
|
||||
uid: string;
|
||||
name: string;
|
||||
status: string;
|
||||
url: string;
|
||||
}>;
|
||||
/////////////////
|
||||
export interface ITextConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Text';
|
||||
}
|
||||
export type TTextDefaultType = string;
|
||||
////////////////////////
|
||||
export interface ITextAreaConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'TextArea';
|
||||
}
|
||||
export type TtextAreaDefaultType = string;
|
||||
|
||||
export interface InumberConfigType {
|
||||
export type TTextAreaDefaultType = string;
|
||||
////////////////////////////
|
||||
export interface INumberConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Number';
|
||||
range?: [number, number];
|
||||
step?: number;
|
||||
}
|
||||
|
||||
export type TNumberDefaultType = number;
|
||||
|
||||
///////////////////
|
||||
export interface IDataListConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'DataList';
|
||||
}
|
||||
|
||||
export type TDataListDefaultTypeItem = {
|
||||
id: string;
|
||||
title: string;
|
||||
desc: string;
|
||||
link: string;
|
||||
type?: number;
|
||||
imgUrl: TUploadDefaultType;
|
||||
};
|
||||
|
||||
export type TDataListDefaultType = Array<TDataListDefaultTypeItem>;
|
||||
|
||||
////////////////////
|
||||
export interface IColorConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Color';
|
||||
}
|
||||
|
||||
export type TColorDefaultType = string;
|
||||
|
||||
export interface IMutiTextConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'MutiText';
|
||||
}
|
||||
|
||||
export type TMutiTextDefaultType = Array<string>;
|
||||
|
||||
/////////////////////////////////
|
||||
export interface ISelectConfigType<KeyType> {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Select';
|
||||
range: Array<{
|
||||
key: KeyType;
|
||||
text: string;
|
||||
}>;
|
||||
}
|
||||
export type TSelectDefaultType<KeyType> = KeyType;
|
||||
|
||||
/////////////////////////
|
||||
export interface IRadioConfigType<KeyType> {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Radio';
|
||||
range: Array<{
|
||||
key: KeyType;
|
||||
text: string;
|
||||
}>;
|
||||
}
|
||||
export type TRadioDefaultType<KeyType> = KeyType;
|
||||
|
||||
///////////////
|
||||
|
||||
export interface ISwitchConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Switch';
|
||||
}
|
||||
export type TSwitchDefaultType = boolean;
|
||||
|
||||
/////////////////////////////
|
||||
export interface ICardPickerConfigType<T> {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'CardPicker';
|
||||
icons: Array<T>;
|
||||
}
|
||||
export type TCardPickerDefaultType<T> = T;
|
||||
|
||||
/////////////
|
||||
|
||||
export interface ITableConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'Table';
|
||||
}
|
||||
export type TTableDefaultType = Array<{
|
||||
name: string;
|
||||
value: number;
|
||||
}>;
|
||||
|
||||
//////////////////
|
||||
export interface IFormItemsConfigType {
|
||||
key: string;
|
||||
name: string;
|
||||
type: 'FormItems';
|
||||
}
|
||||
|
||||
//0---------baseform
|
||||
export type baseFormOptionsType = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type baseFormTextTpl = {
|
||||
id: string;
|
||||
type: 'Text';
|
||||
label: string;
|
||||
placeholder: string;
|
||||
};
|
||||
export type baseFormNumberTpl = {
|
||||
id: string;
|
||||
type: 'Number';
|
||||
label: string;
|
||||
placeholder: string;
|
||||
};
|
||||
|
||||
export type baseFormTextAreaTpl = {
|
||||
id: string;
|
||||
type: 'Textarea';
|
||||
label: string;
|
||||
placeholder: string;
|
||||
};
|
||||
|
||||
export type baseFormMyRadioTpl = {
|
||||
id: string;
|
||||
type: 'MyRadio';
|
||||
label: string;
|
||||
options: baseFormOptionsType[];
|
||||
};
|
||||
|
||||
export type baseFormMySelectTpl = {
|
||||
id: string;
|
||||
type: 'MySelect';
|
||||
label: string;
|
||||
options: baseFormOptionsType[];
|
||||
};
|
||||
|
||||
export type baseFormDateTpl = {
|
||||
id: string;
|
||||
type: 'Date';
|
||||
label: string;
|
||||
placeholder: string;
|
||||
};
|
||||
|
||||
export type baseFormUnion =
|
||||
| baseFormTextTpl
|
||||
| baseFormNumberTpl
|
||||
| baseFormTextAreaTpl
|
||||
| baseFormMyRadioTpl
|
||||
| baseFormMySelectTpl
|
||||
| baseFormDateTpl;
|
||||
export type baseFormUnionType =
|
||||
| baseFormTextTpl['type']
|
||||
| baseFormNumberTpl['type']
|
||||
| baseFormTextAreaTpl['type']
|
||||
| baseFormMyRadioTpl['type']
|
||||
| baseFormMySelectTpl['type']
|
||||
| baseFormDateTpl['type'];
|
||||
|
||||
export type TFormItemsDefaultType = Array<baseFormUnion>;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import React, { memo, useEffect } from 'react';
|
||||
import React, { FC, memo, useEffect } from 'react';
|
||||
import { Form, Select, Input, Modal } from 'antd';
|
||||
import { baseFormOptionsType, baseFormUnion } from '../FormEditor/types';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
@ -8,10 +10,17 @@ const formItemLayout = {
|
||||
wrapperCol: { span: 14 },
|
||||
};
|
||||
|
||||
const EditorModal = props => {
|
||||
interface EditorModalProps {
|
||||
item: any;
|
||||
onSave: (data: any) => void;
|
||||
visible: boolean;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const EditorModal: FC<EditorModalProps> = props => {
|
||||
const { item, onSave, visible, onCancel } = props;
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
onSave && onSave(values);
|
||||
};
|
||||
|
||||
@ -19,7 +28,6 @@ const EditorModal = props => {
|
||||
form
|
||||
.validateFields()
|
||||
.then(values => {
|
||||
console.log(values);
|
||||
values.id = item.id;
|
||||
onSave && onSave(values);
|
||||
})
|
||||
@ -34,70 +42,72 @@ const EditorModal = props => {
|
||||
return () => {
|
||||
form.resetFields();
|
||||
};
|
||||
}, [item]);
|
||||
}, [form, item]);
|
||||
|
||||
return (
|
||||
!!item && (
|
||||
<Modal
|
||||
title="编辑表单组件"
|
||||
visible={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={onCancel}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
name={`formItem_editor_modal`}
|
||||
{...formItemLayout}
|
||||
onFinish={onFinish}
|
||||
initialValues={item}
|
||||
<>
|
||||
{!!item && (
|
||||
<Modal
|
||||
title="编辑表单组件"
|
||||
visible={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={onCancel}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
{
|
||||
<Form.Item label="类型" name="type" hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
}
|
||||
{!!item.label && (
|
||||
<Form.Item
|
||||
label="字段名"
|
||||
name="label"
|
||||
rules={[{ required: true, message: '请输入字段名!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
{!!item.placeholder && (
|
||||
<Form.Item label="提示文本" name="placeholder">
|
||||
<Input placeholder="请输入提示文本" />
|
||||
</Form.Item>
|
||||
)}
|
||||
{!!item.options && (
|
||||
<Form.Item
|
||||
label="选项源"
|
||||
name="options"
|
||||
rules={[{ required: true, message: '选项不能为空!' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请输入"
|
||||
mode="tags"
|
||||
labelInValue
|
||||
maxTagCount={39}
|
||||
maxTagTextLength={16}
|
||||
<Form
|
||||
form={form}
|
||||
name={`formItem_editor_modal`}
|
||||
{...formItemLayout}
|
||||
onFinish={onFinish}
|
||||
initialValues={item}
|
||||
>
|
||||
{
|
||||
<Form.Item label="类型" name="type" hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
}
|
||||
{!!item.label && (
|
||||
<Form.Item
|
||||
label="字段名"
|
||||
name="label"
|
||||
rules={[{ required: true, message: '请输入字段名!' }]}
|
||||
>
|
||||
{item.options.map((v, i) => {
|
||||
return (
|
||||
<Option value={v.value} key={i}>
|
||||
{v.label}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
)
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
{!!item.placeholder && (
|
||||
<Form.Item label="提示文本" name="placeholder">
|
||||
<Input placeholder="请输入提示文本" />
|
||||
</Form.Item>
|
||||
)}
|
||||
{!!item.options && (
|
||||
<Form.Item
|
||||
label="选项源"
|
||||
name="options"
|
||||
rules={[{ required: true, message: '选项不能为空!' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请输入"
|
||||
mode="tags"
|
||||
labelInValue
|
||||
maxTagCount={39}
|
||||
maxTagTextLength={16}
|
||||
>
|
||||
{item.options.map((v: baseFormOptionsType, i: number) => {
|
||||
return (
|
||||
<Option value={v.value} key={i}>
|
||||
{v.label}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import React, { memo, useState, useEffect } from 'react';
|
||||
import React, { memo, useState } from 'react';
|
||||
import BaseForm from '../../BasicShop/BasicComponents/Form/BaseForm';
|
||||
import EditorModal from './EditorModal';
|
||||
|
||||
import { EditOutlined, MinusCircleOutlined } from '@ant-design/icons';
|
||||
import styles from './formItems.less';
|
||||
import { baseFormUnion, TFormItemsDefaultType } from '../FormEditor/types';
|
||||
|
||||
// import { Popconfirm } from 'antd';
|
||||
|
||||
import styles from './formItems.less';
|
||||
|
||||
const formTpl = [
|
||||
const formTpl: TFormItemsDefaultType = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'Text',
|
||||
@ -50,29 +49,35 @@ const formTpl = [
|
||||
id: '6',
|
||||
type: 'Date',
|
||||
label: '日期框',
|
||||
placeholder: '',
|
||||
},
|
||||
];
|
||||
|
||||
const FormItems = props => {
|
||||
const { formList, onChange } = props;
|
||||
console.log(props);
|
||||
const [formData, setFormData] = useState(formList || []);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [curItem, setCurItem] = useState();
|
||||
interface FormItemsProps {
|
||||
formList?: TFormItemsDefaultType;
|
||||
onChange?: (v: TFormItemsDefaultType) => void;
|
||||
data: any;
|
||||
}
|
||||
|
||||
const handleAddItem = item => {
|
||||
const FormItems = (props: FormItemsProps) => {
|
||||
const { formList, onChange } = props;
|
||||
const [formData, setFormData] = useState<TFormItemsDefaultType>(formList || []);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [curItem, setCurItem] = useState<baseFormUnion>();
|
||||
|
||||
const handleAddItem = (item: baseFormUnion) => {
|
||||
let tpl = formTpl.find(v => v.type === item.type);
|
||||
let newData = [...formData, tpl];
|
||||
let newData = [...formData, tpl!];
|
||||
setFormData(newData);
|
||||
onChange && onChange(newData);
|
||||
};
|
||||
|
||||
const handleEditItem = item => {
|
||||
const handleEditItem = (item: baseFormUnion) => {
|
||||
setVisible(true);
|
||||
setCurItem(item);
|
||||
};
|
||||
|
||||
const handleDelItem = item => {
|
||||
const handleDelItem = (item: baseFormUnion) => {
|
||||
let newData = formData.filter(v => v.type !== item.type);
|
||||
setFormData(newData);
|
||||
onChange && onChange(newData);
|
||||
@ -82,7 +87,7 @@ const FormItems = props => {
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
const handleSaveItem = data => {
|
||||
const handleSaveItem = (data: baseFormUnion) => {
|
||||
let newData = formData.map(v => (v.type === data.type ? data : v));
|
||||
setFormData(newData);
|
||||
onChange && onChange(newData);
|
||||
@ -91,7 +96,7 @@ const FormItems = props => {
|
||||
return (
|
||||
<div className={styles.formItemWrap}>
|
||||
<div className={styles.editForm}>
|
||||
{formData.map((item, i) => {
|
||||
{formData.map((item: baseFormUnion, i: number) => {
|
||||
let FormItem = BaseForm[item.type];
|
||||
return (
|
||||
<div className={styles.formItem} key={i}>
|
||||
|
||||
@ -2,11 +2,11 @@ import React, { memo, useState, useEffect } from 'react';
|
||||
import { Input, Button, Popconfirm } from 'antd';
|
||||
import { MinusCircleOutlined } from '@ant-design/icons';
|
||||
import styles from './index.less';
|
||||
import { TabConfigType } from '../../DynamicEngine/schema';
|
||||
import { TMutiTextDefaultType } from '../FormEditor/types';
|
||||
|
||||
type MultiTextProps = {
|
||||
onChange?: (v: TabConfigType['tabs']) => void;
|
||||
value?: TabConfigType['tabs'];
|
||||
onChange?: (v: TMutiTextDefaultType) => void;
|
||||
value?: TMutiTextDefaultType;
|
||||
};
|
||||
|
||||
export default memo(function MutiText(props: MultiTextProps) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user