2020-07-21 13:12:58 +08:00

182 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Component, Fragment } from 'react';
import { Icon, Button } from '@alifd/next';
import { SetterType, FieldConfig } from '@ali/lowcode-types';
import { createSettingFieldView } from '../settings/settings-pane';
import { PopupContext, PopupPipe } from '../popup';
import { SettingField } from '@ali/lowcode-designer';
import './style.less';
import { Title } from '@ali/lowcode-editor-core';
export default class ObjectSetter extends Component<{
field: SettingField;
descriptor?: string | ((rowField: SettingField) => string);
config: ObjectSetterConfig;
mode?: 'popup' | 'form';
// 1: in tablerow 2: in listrow 3: in column-cell
forceInline?: number;
}> {
render() {
const { mode, forceInline = 0, ...props } = this.props;
if (forceInline || mode === 'popup') {
if (forceInline > 2 || mode === 'popup') {
// popup
return <RowSetter {...props} primaryButton={forceInline ? false : true} />;
} else {
return <RowSetter columns={forceInline > 1 ? 2 : 4} {...props} />;
}
} else {
// form
return <FormSetter {...props} />;
}
}
}
interface ObjectSetterConfig {
items?: FieldConfig[];
extraSetter?: SetterType;
}
interface RowSetterProps {
field: SettingField;
descriptor?: string | ((rowField: SettingField) => string);
config: ObjectSetterConfig;
columns?: number;
primaryButton?: boolean;
}
class RowSetter extends Component<RowSetterProps> {
static contextType = PopupContext;
state: any = {
descriptor: '',
};
private items?: SettingField[];
constructor(props: RowSetterProps) {
super(props);
const { config, descriptor, field, columns } = props;
const items: SettingField[] = [];
if (columns && config?.items) {
const l = Math.min(config.items.length, columns);
for (let i = 0; i < l; i++) {
const conf = config.items[i];
if (conf.isRequired || conf.important || (conf.setter as any)?.isRequired) {
const item = field.createField({
...conf,
// in column-cell
forceInline: 3,
});
items.push(item);
}
}
}
if (items.length > 0) {
this.items = items;
}
let firstRun: boolean = true;
field.onEffect(() => {
let state: any = {};
if (descriptor) {
if (typeof descriptor === 'function') {
state.descriptor = descriptor(field);
} else {
state.descriptor = field.getPropValue(descriptor);
}
} else {
state.descriptor = field.title;
}
if (firstRun) {
firstRun = false;
this.state = state;
} else {
this.setState(state);
}
});
}
shouldComponentUpdate(_: any, nextState: any) {
if (this.state.decriptor !== nextState.decriptor) {
return true;
}
return false;
}
private pipe: any;
render() {
const items = this.items;
const { field, primaryButton, config } = this.props;
if (!this.pipe) {
this.pipe = (this.context as PopupPipe).create({ width: 320 });
}
const title = (
<Fragment>
<Title title={this.state.descriptor} />
</Fragment>
);
this.pipe.send(<FormSetter key={field.id} field={field} config={config} />, title);
if (items) {
return (
<div className="lc-setter-object-row">
<div
className="lc-setter-object-row-edit"
onClick={(e) => {
this.pipe.show((e as any).target, field.id);
}}
>
<Icon size="small" type="edit" />
</div>
<div className="lc-setter-object-row-body">{items.map((item) => createSettingFieldView(item, field))}</div>
</div>
);
}
return (
<Button
type={primaryButton === false ? 'normal' : 'primary'}
onClick={(e) => {
this.pipe.show((e as any).target, field.id);
}}
>
<Icon type="edit" />
{title}
</Button>
);
}
}
interface FormSetterProps {
field: SettingField;
config: ObjectSetterConfig;
}
class FormSetter extends Component<FormSetterProps> {
private items: SettingField[];
constructor(props: RowSetterProps) {
super(props);
const { config, field } = props;
this.items = (config?.items || []).map((conf) => field.createField(conf));
// TODO: extraConfig for custom fields
}
shouldComponentUpdate() {
return false;
}
render() {
const { field } = this.props;
return (
<div className="lc-setter-object lc-block-setter">
{this.items.map((item, index) => createSettingFieldView(item, field, index))}
</div>
);
}
}