feat: 编辑器只读模式下编辑后还原数据 (#10968)

Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com>
This commit is contained in:
qkiroc 2024-09-26 17:14:46 +08:00 committed by GitHub
parent fabab5a2c7
commit e41119784d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 24 deletions

View File

@ -378,7 +378,7 @@ export interface FormProps
onSubmit?: (values: object, action: any) => any;
onChange?: (values: object, diff: object, props: any) => any;
onFailed?: (reason: string, errors: any) => any;
onFinished: (values: object, action: any) => any;
onFinished: (values: object, action: ActionObject, store: IFormStore) => any;
onValidate: (values: object, form: any) => any;
onValidChange?: (valid: boolean, props: any) => void; // 表单数据合法性变更
messages: {
@ -1450,7 +1450,7 @@ export default class Form extends React.Component<FormProps, object> {
return store.data;
}
if (onFinished && onFinished(values, action) === false) {
if (onFinished && onFinished(values, action, store) === false) {
return values;
}

View File

@ -741,6 +741,10 @@ export const FormStore = ServiceStore.named('FormStore')
items.forEach(item => item.reset());
}
function setPristine(data: object) {
self.pristine = data;
}
function reset(cb?: (data: any) => void, resetData: boolean = true) {
if (resetData) {
self.data = self.pristine;
@ -826,6 +830,7 @@ export const FormStore = ServiceStore.named('FormStore')
getLocalPersistData,
setLocalPersistData,
clearLocalPersistData,
setPristine,
setPersistData,
clear,
updateSavedData,

View File

@ -67,27 +67,13 @@ export class RightPanels extends React.Component<
handlePanelChangeValue(
...arg: Parameters<typeof this.props.manager.panelChangeValue>
) {
const {manager, readonly} = this.props;
const {manager} = this.props;
if (readonly) {
const diff = arg[1];
if (
!diff?.find((item: any) =>
item.path.find(
(p: string) => !p.startsWith('__') && p !== 'pullRefresh'
)
)
) {
return;
}
toast.error('不支持编辑');
} else {
manager.panelChangeValue(...arg);
}
}
render() {
const {store, manager, theme} = this.props;
const {store, manager, theme, readonly} = this.props;
const {isOpenStatus, isFixedStatus} = this.state;
const panels = store.getPanels();
const id = store.activeId;
@ -104,7 +90,8 @@ export class RightPanels extends React.Component<
onChange: this.handlePanelChangeValue,
store: store,
manager: manager,
popOverContainer: this.getPopOverContainer
popOverContainer: this.getPopOverContainer,
readonly
})
) : panel.component ? (
<panel.component
@ -118,6 +105,7 @@ export class RightPanels extends React.Component<
store={store}
manager={manager}
popOverContainer={this.getPopOverContainer}
readonly={readonly}
/>
) : null;
};

View File

@ -2,7 +2,13 @@ import React from 'react';
import {EditorNodeType} from '../../store/node';
import {EditorManager} from '../../manager';
import {diff, getThemeConfig} from '../../util';
import {createObjectFromChain, extractObjectChain, render} from 'amis';
import {
createObjectFromChain,
extractObjectChain,
IFormStore,
render,
toast
} from 'amis';
import omit from 'lodash/omit';
import cx from 'classnames';
@ -22,7 +28,8 @@ export function SchemaFrom({
justify,
ctx,
pipeIn,
pipeOut
pipeOut,
readonly
}: {
propKey?: string;
env: any;
@ -48,6 +55,7 @@ export function SchemaFrom({
ctx?: any;
pipeIn?: (value: any) => any;
pipeOut?: (value: any, oldValue: any) => any;
readonly?: boolean;
}) {
const schema = React.useMemo(() => {
let containerKey = 'body';
@ -129,6 +137,8 @@ export function SchemaFrom({
[]
);
const [init, setInit] = React.useState(true);
const data = React.useMemo(() => {
value = value || {};
const finalValue = pipeIn ? pipeIn(value) : value;
@ -143,13 +153,21 @@ export function SchemaFrom({
return render(
schema,
{
onFinished: async (newValue: any) => {
onFinished: async (newValue: any, action: any, store: IFormStore) => {
newValue = pipeOut ? await pipeOut(newValue, value) : newValue;
const diffValue = diff(value, newValue);
// 没有变化时不触发onChange
if (!diffValue) {
return;
}
if (readonly && !init) {
toast.error('不支持修改');
store.setPristine(value);
store.reset();
return;
}
setInit(false);
onChange(newValue, diffValue, (schema, value, id, diff) => {
return submitSubscribers.current.reduce((schema, fn) => {
return fn(schema, value, id, diff);

View File

@ -262,7 +262,15 @@ export function makeSchemaFormRender(
body ? flatten(Array.isArray(body) ? body : [body]) : undefined
);
return ({value, onChange, popOverContainer, id, store, node}: PanelProps) => {
return ({
value,
onChange,
popOverContainer,
id,
store,
node,
readonly
}: PanelProps) => {
const ctx = {...manager.store.ctx};
if (schema?.panelById && schema?.panelById !== node?.id) {
@ -306,6 +314,7 @@ export function makeSchemaFormRender(
node={node}
manager={manager}
justify={schema.justify}
readonly={readonly}
/>
);
};

View File

@ -452,6 +452,7 @@ export interface PanelProps {
store: EditorStoreType;
manager: EditorManager;
popOverContainer?: () => HTMLElement | void;
readonly?: boolean;
}
/**