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

View File

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

View File

@ -67,27 +67,13 @@ export class RightPanels extends React.Component<
handlePanelChangeValue( handlePanelChangeValue(
...arg: Parameters<typeof this.props.manager.panelChangeValue> ...arg: Parameters<typeof this.props.manager.panelChangeValue>
) { ) {
const {manager, readonly} = this.props; const {manager} = this.props;
if (readonly) { manager.panelChangeValue(...arg);
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() { render() {
const {store, manager, theme} = this.props; const {store, manager, theme, readonly} = this.props;
const {isOpenStatus, isFixedStatus} = this.state; const {isOpenStatus, isFixedStatus} = this.state;
const panels = store.getPanels(); const panels = store.getPanels();
const id = store.activeId; const id = store.activeId;
@ -104,7 +90,8 @@ export class RightPanels extends React.Component<
onChange: this.handlePanelChangeValue, onChange: this.handlePanelChangeValue,
store: store, store: store,
manager: manager, manager: manager,
popOverContainer: this.getPopOverContainer popOverContainer: this.getPopOverContainer,
readonly
}) })
) : panel.component ? ( ) : panel.component ? (
<panel.component <panel.component
@ -118,6 +105,7 @@ export class RightPanels extends React.Component<
store={store} store={store}
manager={manager} manager={manager}
popOverContainer={this.getPopOverContainer} popOverContainer={this.getPopOverContainer}
readonly={readonly}
/> />
) : null; ) : null;
}; };

View File

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

View File

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

View File

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