feat:修复source变化后视图不更新,调整部分文案

This commit is contained in:
fujianchao 2024-10-24 20:47:24 +08:00 committed by lmaomaoz
parent 05e6aa2d09
commit 024efd3a17
4 changed files with 75 additions and 66 deletions

View File

@ -42,10 +42,6 @@ export class TimelinePlugin extends BasePlugin {
title: '基本',
body: [
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
getSchemaTpl('formItemName', {
required: true
}),
getSchemaTpl('label'),
{
label: '排序',
name: 'reverse',
@ -95,7 +91,7 @@ export class TimelinePlugin extends BasePlugin {
{
type: 'ae-switch-more',
mode: 'normal',
label: '自定义标题显示模板',
label: '自定义标题模板',
bulk: false,
name: 'itemTitleSchema',
formType: 'extend',
@ -107,7 +103,7 @@ export class TimelinePlugin extends BasePlugin {
size: 'sm',
block: true,
onClick: this.editDetail.bind(this, context),
label: '配置标题显示模板'
label: '配置示模板'
}
]
},
@ -121,7 +117,7 @@ export class TimelinePlugin extends BasePlugin {
if (value === true) {
return {
type: 'tpl',
tpl: '请编辑标题内容'
tpl: this.scaffold.label
};
}
return value ? value : undefined;
@ -166,12 +162,12 @@ export class TimelinePlugin extends BasePlugin {
const value = store.getValueOf(id);
const defaultItemSchema = {
type: 'tpl',
tpl: '请编辑标题内容'
tpl: this.scaffold.label
};
node &&
value &&
this.manager.openSubEditor({
title: '配置标题显示模',
title: '配置标题显示模',
value: schemaToArray(value.itemTitleSchema ?? defaultItemSchema),
slot: {
type: 'container',
@ -180,8 +176,7 @@ export class TimelinePlugin extends BasePlugin {
onChange: (newValue: any) => {
newValue = {...value, itemTitleSchema: schemaArrayFormat(newValue)};
manager.panelChangeValue(newValue, diff(value, newValue));
},
data: schema
}
});
}
}

View File

@ -10,6 +10,7 @@ import {render as amisRender, FormItem, Icon} from 'amis';
import {getI18nEnabled} from 'amis-editor-core';
import {autobind} from 'amis-editor-core';
import {getSchemaTpl} from 'amis-editor-core';
import {isExpression} from 'amis-core';
import type {FormControlProps} from 'amis-core';
import type {SchemaApi} from 'amis';
@ -27,9 +28,10 @@ export interface TimelineItemProps extends FormControlProps {
className?: string;
}
export type SourceType = 'custom' | 'api' | 'variable';
export interface TimelineItemState {
items: Array<Partial<TimelineItem>>;
source: 'custom' | 'api' | 'variable';
source: SourceType;
api: SchemaApi;
}
@ -43,54 +45,44 @@ export default class TimelineItemControl extends React.Component<
constructor(props: TimelineItemProps) {
super(props);
const {source} = props.data || {};
this.state = {
items: props.value,
api: props.data.source,
source: props.data.source
? typeof props.data.source === 'string' &&
props.data.source.match(/^\$\{.*\}$/)
? 'variable'
: 'api'
: 'custom'
api: source,
source: source ? (isExpression(source) ? 'variable' : 'api') : 'custom'
};
}
/**
*
*/
@autobind
handleSourceChange(source: 'custom' | 'api' | 'variable') {
this.setState({source: source}, this.onChange);
handleSourceChange(source: SourceType) {
//取消无效切换
if (source === this.state.source) {
return;
}
this.setState({source: source, api: '', items: []}, this.onChange);
}
@autobind
handleAPIChange(source: SchemaApi) {
this.setState({api: source}, this.onChange);
}
onChange() {
const {source} = this.state;
const {source, items, api} = this.state;
const {onBulkChange} = this.props;
const data: Partial<TimelineItemProps> = {
source: undefined,
items: undefined
};
if (source === 'custom') {
const {items} = this.state;
data.items = items.map(item => ({...item}));
}
if (source === 'api') {
const {items, api} = this.state;
data.items = items.map(item => ({...item}));
data.source = api;
}
if (source === 'variable') {
const {items, api} = this.state;
data.items = items.map(item => ({...item}));
if (source === 'api' || source === 'variable') {
data.source = api;
}
onBulkChange && onBulkChange(data);
return;
}
@autobind
@ -212,7 +204,7 @@ export default class TimelineItemControl extends React.Component<
body: [
{
type: 'tpl',
tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每行可通过空格来分别设置time和title,例:"2022-06-23 期末补考"'
tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每个数据单独一行时间与标题用空格分隔“2024-01-01 提交申请”'
}
],
showIcon: true,
@ -252,7 +244,7 @@ export default class TimelineItemControl extends React.Component<
return {
type: 'action',
actionType: 'dialog',
label: '添加项',
label: '添加项',
active: true,
dialog: {
title: '节点配置',
@ -530,10 +522,6 @@ export default class TimelineItemControl extends React.Component<
renderApiPanel() {
const {render} = this.props;
const {source, api} = this.state;
if (source !== 'api') {
return null;
}
return render(
'api',
getSchemaTpl('apiControl', {
@ -542,7 +530,8 @@ export default class TimelineItemControl extends React.Component<
className: 'ae-ExtendMore',
visibleOn: 'this.autoComplete !== false',
value: api,
onChange: this.handleAPIChange
onChange: this.handleAPIChange,
sourceType: source
})
);
}
@ -576,7 +565,7 @@ export default class TimelineItemControl extends React.Component<
</div>
</div>
) : null}
{source === 'api' ? this.renderApiPanel() : null}
{source === 'variable'
? render(
'variable',
@ -589,7 +578,6 @@ export default class TimelineItemControl extends React.Component<
}
)
: null}
{this.renderApiPanel()}
</div>
);
}

View File

@ -171,8 +171,6 @@
.#{$ns}Timeline-horizontal {
display: flex;
flex-flow: row;
margin-left: 50%;
transform: translateX(-50%);
.#{$ns}TimelineItem {
display: flex;

View File

@ -243,16 +243,20 @@ export function withRemoteConfig<P = any>(
this.props.env || (this.context as RendererEnv);
const {store, data} = this.props;
const source = (this.props as any)[config.sourceField || 'source'];
if (isPureVariable(source)) {
//监听上下文变量变化
this.toDispose.push(
reaction(
() =>
resolveVariableAndFilter(
() => {
const source = (this.props as any)[
config.sourceField || 'source'
];
return resolveVariableAndFilter(
source as string,
store.data,
'| raw'
),
);
},
() => this.syncConfig(),
// 当nav配置source: "${amisStore.app.portalNavs}"时切换页面就会触发source更新
// 因此这里增加这个配置 数据源完全不相等情况下再执行loadConfig
@ -262,28 +266,52 @@ export function withRemoteConfig<P = any>(
);
} else if (env && isEffectiveApi(source, data)) {
this.loadConfig();
(source as ApiObject).autoRefresh !== false &&
this.toDispose.push(
reaction(
() => {
const api = normalizeApi(source as string);
return api.trackExpression
? tokenize(api.trackExpression, store.data)
: buildApi(api, store.data, {
ignoreData: true
}).url;
},
() => this.loadConfig()
)
);
}
}
componentDidUpdate(prevProps: any) {
const props = this.props;
//监听source变化
const env: RendererEnv =
this.props.env || (this.context as RendererEnv);
const {store, data} = this.props;
let source = (this.props as any)[config.sourceField || 'source'];
const prevSource = prevProps.source;
const prevApi = normalizeApi(prevSource as string);
const api = normalizeApi(source as string);
//如果没对上下文变量进行监听,则进行监听
if (isPureVariable(source) && !this.toDispose.length) {
//比较上下文变量是否变化
resolveVariableAndFilter(
prevSource as string,
store.data,
'| raw'
) !==
resolveVariableAndFilter(
source as string,
store.data,
'| raw'
) && this.syncConfig();
} else if (env && isEffectiveApi(source, data)) {
//比较api是否变化
(source as ApiObject).autoRefresh !== false &&
(api.trackExpression
? tokenize(api.trackExpression, store.data)
: buildApi(api, store.data, {
ignoreData: true
}).url) !==
(prevApi.trackExpression
? tokenize(prevApi.trackExpression, store.data)
: buildApi(prevApi, store.data, {
ignoreData: true
}).url) &&
this.loadConfig();
} else if (!source) {
//如果source为空则清空配置
this.setConfig(undefined);
}
if (props.data !== prevProps.data) {
props.store.setData(props.data);
if (data !== prevProps.data) {
store.setData(data);
}
}