@jswork/react-ant-resource-form 1.0.31 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs.js +1 -1
- package/dist/main.cjs.js.map +1 -1
- package/dist/main.d.mts +26 -7
- package/dist/main.d.ts +26 -7
- package/dist/main.esm.js +1 -1
- package/dist/main.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/index-rc.tsx +37 -0
- package/src/index.tsx +32 -67
- package/src/main.tsx +4 -2
- package/src/types.ts +35 -0
package/dist/main.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var w=Object.defineProperty;var R=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var w=Object.defineProperty;var R=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var k=(a,i,t)=>i in a?w(a,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[i]=t,c=(a,i)=>{for(var t in i||(i={}))I.call(i,t)&&k(a,t,i[t]);if(R)for(var t of R(i))x.call(i,t)&&k(a,t,i[t]);return a};var h=(a,i)=>w(a,"name",{value:i,configurable:!0});var _=(a,i)=>{var t={};for(var e in a)I.call(a,e)&&i.indexOf(e)<0&&(t[e]=a[e]);if(a!=null&&R)for(var e of R(a))i.indexOf(e)<0&&x.call(a,e)&&(t[e]=a[e]);return t};var u=(a,i,t)=>k(a,typeof i!="symbol"?i+"":i,t);var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);var _react = require('react'); var _react2 = _interopRequireDefault(_react);var _antd = require('antd');var _reactantformschema = require('@jswork/react-ant-form-schema'); var _reactantformschema2 = _interopRequireDefault(_reactantformschema);var _icons = require('@ant-design/icons');var _fastdeepequal = require('fast-deep-equal'); var _fastdeepequal2 = _interopRequireDefault(_fastdeepequal);var A={"zh-CN":{create:"\u521B\u5EFA",update:"\u4FDD\u5B58",create_title:"\u521B\u5EFA",update_title:"\u66F4\u65B0",create_success:"\u521B\u5EFA\u6210\u529F",update_success:"\u66F4\u65B0\u6210\u529F",submit:"\u63D0\u4EA4",back:"\u8FD4\u56DE",no_change:"\u6CA1\u6709\u4FEE\u6539"},"en-US":{create:"Create",update:"Save",create_title:"Create",update_title:"Update",create_success:"Create success",update_success:"Update success",submit:"Submit",back:"Back",no_change:"No change"}};var _next = require('@jswork/next'); var _next2 = _interopRequireDefault(_next);require('@jswork/next-compact-object');var v="react-ant-resource-form",f,G=(f=class extends _react.Component{constructor(t){var e;super(t);u(this,"formRef",_react2.default.createRef());u(this,"_isMounted",!1);u(this,"_initialValues",null);u(this,"handleBack",h(()=>{history.back()},"handleBack"));u(this,"setInitialValues",h(t=>{var e;this._initialValues=t||((e=this.formInstance)==null?void 0:e.getFieldsValue())||{}},"setInitialValues"));u(this,"handleFinish",h(t=>{if(!this.canSave){this.msg(this.t("no_change"),"info");return}this.isEdit?this.onResourceUpdate(t):this.onResourceCreate(t)},"handleFinish"));u(this,"onResourceUpdate",h(t=>{let{params:e,name:s,submitGuard:n,onMutate:r}=this.props,o=c(c({id:e.id},t),e),d=this.handleStateRequest({stage:"update",payload:o}),p={name:s,payload:d,isEdit:!0,values:t,params:e},g={name:s,payload:d,isEdit:!0,values:t};n==null||n(p).then(()=>{_next2.default.$api[`${s}_update`](d).then(m=>{this.msg(this.t("update_success")),this.handleStateResponse({stage:"update",data:m}),r==null||r(g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues(),this.handleValuesChange(null,this._initialValues)})})},"onResourceUpdate"));u(this,"onResourceCreate",h(t=>{let{params:e,name:s,submitGuard:n,onMutate:r}=this.props,o=c(c({},t),e),d=this.handleStateRequest({stage:"create",payload:o}),p={name:s,payload:d,isEdit:!1,values:t,params:e},g={name:s,payload:d,isEdit:!1,values:t};n==null||n(p).then(()=>{_next2.default.$api[`${s}_create`](d).then(m=>{var S;this.msg(this.t("create_success")),this.handleStateResponse({stage:"create",data:m}),(S=this.formInstance)==null||S.resetFields(),r==null||r(g),history.back()}).finally(()=>this.setState({loading:!1}))})},"onResourceCreate"));u(this,"handleKeydown",h(t=>{var n;let{disableHotkeySave:e}=this.props;(t.ctrlKey||t.metaKey)&&(t.key==="s"||t.key==="S")&&(t.preventDefault(),e||(n=this.formInstance)==null||n.submit())},"handleKeydown"));u(this,"handleValuesChange",h((t,e)=>{this.setState({touched:!_fastdeepequal2.default.call(void 0, this._initialValues,e)})},"handleValuesChange"));this.state={loading:t.loading,touched:!1},this.handleStateRequest=this.handleStateRequest.bind(this),this.handleStateResponse=this.handleStateResponse.bind(this),this.initDetailIfNeeded=this.initDetailIfNeeded.bind(this),(e=t.onInit)==null||e.call(t,this)}get isEdit(){let{params:t}=this.props;return!!(t!=null&&t.id)}get canSave(){let{touched:t,loading:e}=this.state;return this.isEdit?t&&!e:!e}get titleView(){let{title:t}=this.props,e=t||(this.isEdit?this.t("update_title"):this.t("create_title"));return _react2.default.createElement(_antd.Space,null,e,_react2.default.createElement("span",null,this.touchedView))}get touchedView(){return this.isEdit&&this.state.touched?_react2.default.createElement("em",{style:{color:"#f60"}},_react2.default.createElement(_icons.DiffOutlined,null)):null}get extraView(){let{extra:t,backText:e,backProps:s}=this.props;return t||_react2.default.createElement(_antd.Button,c({size:"small",icon:_react2.default.createElement(_icons.ArrowLeftOutlined,null),onClick:this.handleBack},s),e||this.t("back"))}get childrenView(){let{okText:t,backText:e,okProps:s,backProps:n,children:r}=this.props,o=t||(this.isEdit?this.t("update"):this.t("create"));return r||_react2.default.createElement(_antd.Space,null,_react2.default.createElement(_antd.Button,c({disabled:!this.canSave,htmlType:"submit",type:"primary",icon:_react2.default.createElement(_icons.SaveOutlined,null)},s),o||this.t("submit")),_react2.default.createElement(_antd.Button,c({icon:_react2.default.createElement(_icons.ArrowLeftOutlined,null),onClick:this.handleBack},n),e||this.t("back")))}get formInstance(){var t;return(t=this.formRef)==null?void 0:t.current}t(t){let{lang:e}=this.props;return A[e][t]}msg(t,e="success"){let{mute:s}=this.props;s||_antd.message[e](t)}handleStateRequest(t){var e,s;return this.setState({loading:!0}),((s=(e=this.props).transformRequest)==null?void 0:s.call(e,t))||t.payload}handleStateResponse(t){var s,n,r,o;let{name:e}=this.props;return this.setState({loading:!1}),(n=(s=_next2.default.$event)==null?void 0:s.emit)==null||n.call(s,`${e}:refetch`),((o=(r=this.props).transformResponse)==null?void 0:o.call(r,t))||t.data}componentDidMount(){this._isMounted=!0,window.addEventListener("keydown",this.handleKeydown),this.initDetailIfNeeded()}componentDidUpdate(t){var n,r;let e=(n=t.params)==null?void 0:n.id,s=(r=this.props.params)==null?void 0:r.id;e!==s&&this.initDetailIfNeeded(),t.loading!==this.props.loading&&this.setState({loading:this.props.loading})}componentWillUnmount(){window.removeEventListener("keydown",this.handleKeydown),this._isMounted=!1}initDetailIfNeeded(){let{params:t,name:e,initGuard:s}=this.props,n=`${e}_show`;if(this.isEdit){let r={id:t.id},o=this.handleStateRequest({stage:"show",payload:r}),d={name:e,payload:o,isEdit:!0,params:t};s==null||s(d).then(()=>{_next2.default.$api[n](o).then(p=>{var m,S;if(!this._isMounted)return;let g=this.handleStateResponse({stage:"show",data:p});(S=(m=this.formInstance)==null?void 0:m.setFieldsValue)==null||S.call(m,g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues()})})}else{let r={name:e,payload:null,isEdit:!1,params:t};s==null||s(r).then(()=>{this.setInitialValues(),this.setState({loading:!1})})}}render(){let V=this.props,{className:t,name:e,meta:s,children:n,lang:r,title:o,extra:d,size:p,okText:g,backText:m,okProps:S,backProps:j,classNames:P,params:tt,transformRequest:et,transformResponse:st,disableHotkeySave:at,blocker:q,onInit:it,onMutate:nt,initGuard:rt,submitGuard:ot,loading:lt}=V,D=_(V,["className","name","meta","children","lang","title","extra","size","okText","backText","okProps","backProps","classNames","params","transformRequest","transformResponse","disableHotkeySave","blocker","onInit","onMutate","initGuard","submitGuard","loading"]);return _react2.default.createElement(_antd.Card,{title:this.titleView,extra:this.extraView,size:p,classNames:P,"data-component":v,"data-blocker":q,className:_classnames2.default.call(void 0, v,t)},_react2.default.createElement(_antd.Spin,{spinning:this.state.loading},_react2.default.createElement(_reactantformschema2.default,c({meta:s,ref:this.formRef,onValuesChange:this.handleValuesChange,onFinish:this.handleFinish},D),this.childrenView)))}},h(f,"ReactAntResourceForm"),u(f,"defaultProps",{lang:"zh-CN",disableHotkeySave:!1,blocker:!1,mute:!1,initGuard:h(()=>Promise.resolve(),"initGuard"),submitGuard:h(()=>Promise.resolve(),"submitGuard")}),f),y=G;var _reactrouterdom = require('react-router-dom');var _fromentries = require('fromentries'); var _fromentries2 = _interopRequireDefault(_fromentries);var X=h((a,i)=>(_next2.default.forIn(a,t=>{i.includes(t)||delete a[t]}),a),"retainKeys"),Y=h(a=>{let d=a,{params:i,allowFields:t}=d,e=_(d,["params","allowFields"]),s=_reactrouterdom.useParams.call(void 0, ),[n]=_reactrouterdom.useSearchParams.call(void 0, ),r=_fromentries2.default.call(void 0, n),o=_next2.default.compactObject(c(c(c({},r),s),i));return t!=null&&t.length&&t.length>0&&X(o,t),_react2.default.createElement(y,c({params:o},e))},"ReactAntResourceFormFc"),Z= exports.ReactAntResourceFormFc =Y;var vt=y;exports.ReactAntResourceFormFc = Z; exports.default = vt;
|
|
2
2
|
//# sourceMappingURL=main.cjs.js.map
|
package/dist/main.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/ap7/github/react-ant-resource-form/packages/lib/dist/main.cjs.js","../src/index.tsx","../src/locales.ts"],"names":["API_FORM_LOCALES","create","update","create_title","update_title","create_success","update_success","submit","back","no_change","CLASS_NAME","retainKeys","__name","obj","keys","nx","forIn","key","includes","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","history","setInitialValues","values","formInstance","getFieldsValue","handleFinish","canSave","message","info","t","isEdit","onResourceUpdate","onResourceCreate","params","name","submitGuard","onMutate","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","mutateArgs","then","$api"],"mappings":"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","file":"/Users/ap7/github/react-ant-resource-form/packages/lib/dist/main.cjs.js","sourcesContent":[null,"// import noop from '@jswork/noop';\nimport cx from 'classnames';\nimport React, { Component, FC } from 'react';\nimport type { FormInstance } from 'antd';\nimport { Button, ButtonProps, Card, CardProps, message, Space, Spin } from 'antd';\nimport ReactAntdFormSchema, { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';\nimport { ArrowLeftOutlined, DiffOutlined, SaveOutlined } from '@ant-design/icons';\nimport { API_FORM_LOCALES } from './locales';\nimport nx from '@jswork/next';\nimport '@jswork/next-compact-object';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport deepEqual from 'fast-deep-equal';\nimport fromEntries from 'fromentries';\n\ndeclare global {\n interface NxStatic {\n $api: Record<string, any>;\n $event: any;\n }\n}\n\ntype StagePayload = {\n stage: 'show' | 'create' | 'update';\n payload: any;\n};\n\ntype StageData = {\n stage: 'show' | 'create' | 'update';\n data: any;\n};\n\ntype MutateArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n values: any;\n};\n\ntype InitGuardArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n};\n\ntype SubmitGuardArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n values: any;\n};\n\nexport type ReactAntResourceFormProps = {\n lang?: string;\n loading?: boolean;\n okText?: string;\n backText?: string;\n params?: Record<string, any>;\n blocker?: boolean;\n disableHotkeySave?: boolean;\n initGuard?: (args: InitGuardArgs) => Promise<void>;\n submitGuard?: (args: SubmitGuardArgs) => Promise<void>;\n transformRequest?: (payload: StagePayload) => any;\n transformResponse?: (res: StageData) => any;\n okProps?: ButtonProps;\n backProps?: ButtonProps;\n classNames?: CardProps['classNames'];\n size?: CardProps['size'];\n extra?: CardProps['extra'];\n title?: CardProps['title'];\n onInit?: (ctx: ReactAntResourceForm) => void;\n onMutate?: (args: MutateArgs) => void;\n} & ReactAntdFormSchemaProps;\n\ntype IState = {\n loading: boolean;\n touched: boolean;\n};\n\nconst CLASS_NAME = 'react-ant-resource-form';\n\nconst retainKeys = (obj: Record<string, any>, keys: string[]) => {\n nx.forIn(obj, (key) => {\n if (!keys.includes(key)) {\n delete obj[key];\n }\n });\n return obj;\n};\n\n/**\n * 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null\n * 这个情况仅在 class component 里才会出现,function component 里不会:\n * 报错示例:\n *\n * this.formRef?: null\n * index.tsx:229 this.formRef?: {getFieldValue: ƒ, getFieldsValue: ƒ, getFieldError: ƒ, getFieldWarning: ƒ, getFieldsError: ƒ, …}\n * index.tsx:229 this.formRef?: null\n *\n * initGuard | submitGuard:\n * https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc\n */\n\nclass ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {\n public static defaultProps = {\n lang: 'zh-CN',\n disableHotkeySave: false,\n blocker: false,\n initGuard: () => Promise.resolve(),\n submitGuard: () => Promise.resolve(),\n };\n\n private formRef = React.createRef<FormInstance>(); // 注意类型\n private _isMounted = false;\n private _initialValues = null;\n\n get isEdit() {\n const { params } = this.props;\n return Boolean(params?.id);\n }\n\n get canSave() {\n const { touched, loading } = this.state;\n if (!this.isEdit) return !loading;\n return touched && !loading;\n }\n\n get titleView() {\n const { title } = this.props;\n const _title = title || (this.isEdit ? this.t('update_title') : this.t('create_title'));\n return (\n <Space>\n {_title}\n <span>{this.touchedView}</span>\n </Space>\n );\n }\n\n get touchedView() {\n if (!this.isEdit) return null;\n return this.state.touched ? (\n <em style={{ color: '#f60' }}>\n <DiffOutlined />\n </em>\n ) : null;\n }\n\n get extraView() {\n const { extra, backText, backProps } = this.props;\n if (extra) return extra;\n return (\n <Button size=\"small\" icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n );\n }\n\n get childrenView() {\n const { okText, backText, okProps, backProps, children } = this.props;\n const _okText = okText || (this.isEdit ? this.t('update') : this.t('create'));\n if (children) return children;\n\n return (\n <Space>\n <Button\n disabled={!this.canSave}\n htmlType=\"submit\"\n type=\"primary\"\n icon={<SaveOutlined />}\n {...okProps}>\n {_okText || this.t('submit')}\n </Button>\n <Button icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n </Space>\n );\n }\n\n get formInstance() {\n return this.formRef?.current;\n }\n\n constructor(props: ReactAntResourceFormProps) {\n super(props);\n this.state = {\n loading: props.loading!,\n touched: false,\n };\n\n this.handleStateRequest = this.handleStateRequest.bind(this);\n this.handleStateResponse = this.handleStateResponse.bind(this);\n this.initDetailIfNeeded = this.initDetailIfNeeded.bind(this);\n\n props.onInit?.(this);\n }\n\n private t(key: string) {\n const { lang } = this.props;\n return API_FORM_LOCALES[lang!][key];\n }\n\n private handleBack = () => {\n history.back();\n };\n\n private setInitialValues = (values?: any) => {\n this._initialValues = values || this.formInstance?.getFieldsValue() || {};\n };\n\n handleStateRequest(stagePayload: StagePayload) {\n this.setState({ loading: true });\n return this.props.transformRequest?.(stagePayload) || stagePayload.payload;\n }\n\n handleStateResponse(res: StageData) {\n const { name } = this.props;\n this.setState({ loading: false });\n nx.$event?.emit?.(`${name}:refetch`);\n return this.props.transformResponse?.(res) || res.data;\n }\n\n handleFinish = (values: any) => {\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n this.isEdit ? this.onResourceUpdate(values) : this.onResourceCreate(values);\n };\n\n private onResourceUpdate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { id: params!.id, ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'update', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n params,\n };\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_update`](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n onMutate?.(mutateArgs);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n };\n\n private onResourceCreate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'create', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n params,\n };\n\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_create`](_payload)\n .then((res: any) => {\n void message.success(this.t('create_success'));\n this.handleStateResponse({ stage: 'create', data: res });\n this.formInstance?.resetFields();\n onMutate?.(mutateArgs);\n history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\n };\n\n // hotkey save handler (replaces useKeyboardSave hook)\n handleKeydown = (e: KeyboardEvent) => {\n const { disableHotkeySave } = this.props;\n const isSave = (e.ctrlKey || e.metaKey) && (e.key === 's' || e.key === 'S');\n if (isSave) {\n e.preventDefault();\n if (!disableHotkeySave) {\n this.formInstance?.submit();\n }\n }\n };\n\n handleValuesChange = (_: any, allValues: any) => {\n this.setState({\n touched: !deepEqual(this._initialValues, allValues),\n });\n };\n\n componentDidMount() {\n this._isMounted = true;\n // attach hotkey listener\n window.addEventListener('keydown', this.handleKeydown);\n // initialize detail if editing\n this.initDetailIfNeeded();\n }\n\n componentDidUpdate(prevProps: ReactAntResourceFormProps) {\n const prevId = prevProps.params?.id;\n const curId = this.props.params?.id;\n // re-init when id changed or from create -> edit\n if (prevId !== curId) {\n this.initDetailIfNeeded();\n }\n\n // loading update\n if (prevProps.loading !== this.props.loading) {\n this.setState({ loading: this.props.loading! });\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('keydown', this.handleKeydown);\n this._isMounted = false;\n }\n\n initDetailIfNeeded() {\n const { params, name, initGuard } = this.props;\n const resourceShow = `${name}_show`;\n\n if (this.isEdit) {\n const payload = { id: params!.id };\n const _payload = this.handleStateRequest({ stage: 'show', payload });\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n nx.$api[resourceShow](_payload)\n .then((res: any) => {\n if (!this._isMounted) return; // 👈 关键:防止操作已卸载组件\n const data = this.handleStateResponse({ stage: 'show', data: res });\n this.formInstance?.setFieldsValue?.(data);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n });\n });\n } else {\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: null,\n isEdit: false,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n this.setInitialValues();\n this.setState({ loading: false });\n });\n }\n }\n\n render() {\n const {\n className,\n name,\n meta,\n children,\n lang,\n title,\n extra,\n size,\n okText,\n backText,\n okProps,\n backProps,\n classNames,\n params,\n transformRequest,\n transformResponse,\n disableHotkeySave,\n blocker,\n onInit,\n initGuard,\n submitGuard,\n loading,\n ...rest\n } = this.props;\n\n return (\n <Card\n title={this.titleView}\n extra={this.extraView}\n size={size}\n classNames={classNames}\n data-component={CLASS_NAME}\n data-blocker={blocker}\n className={cx(CLASS_NAME, className)}>\n <Spin spinning={this.state.loading}>\n <ReactAntdFormSchema\n meta={meta}\n ref={this.formRef}\n onValuesChange={this.handleValuesChange}\n onFinish={this.handleFinish}\n {...rest}>\n {this.childrenView}\n </ReactAntdFormSchema>\n </Spin>\n </Card>\n );\n }\n}\n\nexport type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {\n allowFields?: string[];\n}\n\nconst ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {\n const { params: overrideParams, allowFields, ...rest } = props;\n const params = useParams();\n const [searchParams] = useSearchParams();\n const _searchParams = fromEntries(searchParams as any);\n const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });\n if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);\n return <ReactAntResourceForm params={_params} {...rest} />;\n};\n\nexport default ReactAntResourceForm;\nexport { ReactAntResourceFormFc };\n","export const API_FORM_LOCALES = {\n 'zh-CN': {\n create: '创建',\n update: '保存',\n create_title: '创建',\n update_title: '更新',\n create_success: '创建成功',\n update_success: '更新成功',\n submit: '提交',\n back: '返回',\n no_change: '没有修改',\n },\n 'en-US': {\n create: 'Create',\n update: 'Save',\n create_title: 'Create',\n update_title: 'Update',\n create_success: 'Create success',\n update_success: 'Update success',\n submit: 'Submit',\n back: 'Back',\n no_change: 'No change',\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/ap7/github/react-ant-resource-form/packages/lib/dist/main.cjs.js","../src/index.tsx","../src/locales.ts"],"names":["API_FORM_LOCALES","create","update","create_title","update_title","create_success","update_success","submit","back","no_change","CLASS_NAME","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","__name","history","setInitialValues","values","formInstance","getFieldsValue","handleFinish","canSave","msg","t","isEdit","onResourceUpdate","onResourceCreate","params","name","submitGuard","onMutate","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","mutateArgs","then","nx","$api"],"mappings":"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","file":"/Users/ap7/github/react-ant-resource-form/packages/lib/dist/main.cjs.js","sourcesContent":[null,"// import noop from '@jswork/noop';\nimport cx from 'classnames';\nimport React, { Component } from 'react';\nimport { ButtonProps, CardProps, FormInstance } from 'antd';\nimport { Button, Card, message, Space, Spin } from 'antd';\nimport ReactAntdFormSchema, { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';\nimport { ArrowLeftOutlined, DiffOutlined, SaveOutlined } from '@ant-design/icons';\nimport deepEqual from 'fast-deep-equal';\nimport {\n InitGuardArgs,\n MsgType,\n MutateArgs,\n StageData,\n StagePayload,\n SubmitGuardArgs,\n} from './types';\nimport { API_FORM_LOCALES } from './locales';\nimport nx from '@jswork/next';\nimport '@jswork/next-compact-object';\n\ndeclare global {\n interface NxStatic {\n $api: Record<string, any>;\n $event: any;\n }\n}\n\nconst CLASS_NAME = 'react-ant-resource-form';\n\nexport type ReactAntResourceFormProps = {\n lang?: string;\n loading?: boolean;\n okText?: string;\n backText?: string;\n params?: Record<string, any>;\n blocker?: boolean;\n mute?: boolean;\n disableHotkeySave?: boolean;\n initGuard?: (args: InitGuardArgs) => Promise<void>;\n submitGuard?: (args: SubmitGuardArgs) => Promise<void>;\n transformRequest?: (payload: StagePayload) => any;\n transformResponse?: (res: StageData) => any;\n okProps?: ButtonProps;\n backProps?: ButtonProps;\n classNames?: CardProps['classNames'];\n size?: CardProps['size'];\n extra?: CardProps['extra'];\n title?: CardProps['title'];\n onInit?: (ctx: ReactAntResourceForm) => void;\n onMutate?: (args: MutateArgs) => void;\n} & ReactAntdFormSchemaProps;\n\nexport type IState = {\n loading: boolean;\n touched: boolean;\n};\n\n/**\n * 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null\n * 这个情况仅在 class component 里才会出现,function component 里不会:\n * 报错示例:\n *\n * this.formRef?: null\n * index.tsx:229 this.formRef?: {getFieldValue: ƒ, getFieldsValue: ƒ, getFieldError: ƒ, getFieldWarning: ƒ, getFieldsError: ƒ, …}\n * index.tsx:229 this.formRef?: null\n *\n * initGuard | submitGuard:\n * https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc\n *\n * onMutate:\n * 在 create/update 成功后,需要刷新列表,可以用 onMutate 继续后续处理。\n *\n * blocker:\n * 这个解决的问题是,目前 nice-form 里默认是 grid layout,导致部分情况下,卡片内部的 style 表现很不正常。\n * 特别是有非 antd 组件的情况下,比如我自己的 react-ckeditor\n */\n\nclass ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {\n public static defaultProps = {\n lang: 'zh-CN',\n disableHotkeySave: false,\n blocker: false,\n mute: false,\n initGuard: () => Promise.resolve(),\n submitGuard: () => Promise.resolve(),\n };\n\n private formRef = React.createRef<FormInstance>(); // 注意类型\n private _isMounted = false;\n private _initialValues = null;\n\n get isEdit() {\n const { params } = this.props;\n return Boolean(params?.id);\n }\n\n get canSave() {\n const { touched, loading } = this.state;\n if (!this.isEdit) return !loading;\n return touched && !loading;\n }\n\n get titleView() {\n const { title } = this.props;\n const _title = title || (this.isEdit ? this.t('update_title') : this.t('create_title'));\n return (\n <Space>\n {_title}\n <span>{this.touchedView}</span>\n </Space>\n );\n }\n\n get touchedView() {\n if (!this.isEdit) return null;\n return this.state.touched ? (\n <em style={{ color: '#f60' }}>\n <DiffOutlined />\n </em>\n ) : null;\n }\n\n get extraView() {\n const { extra, backText, backProps } = this.props;\n if (extra) return extra;\n return (\n <Button size=\"small\" icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n );\n }\n\n get childrenView() {\n const { okText, backText, okProps, backProps, children } = this.props;\n const _okText = okText || (this.isEdit ? this.t('update') : this.t('create'));\n if (children) return children;\n\n return (\n <Space>\n <Button\n disabled={!this.canSave}\n htmlType=\"submit\"\n type=\"primary\"\n icon={<SaveOutlined />}\n {...okProps}>\n {_okText || this.t('submit')}\n </Button>\n <Button icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n </Space>\n );\n }\n\n get formInstance() {\n return this.formRef?.current;\n }\n\n constructor(props: ReactAntResourceFormProps) {\n super(props);\n this.state = {\n loading: props.loading!,\n touched: false,\n };\n\n this.handleStateRequest = this.handleStateRequest.bind(this);\n this.handleStateResponse = this.handleStateResponse.bind(this);\n this.initDetailIfNeeded = this.initDetailIfNeeded.bind(this);\n\n props.onInit?.(this);\n }\n\n private t(key: string) {\n const { lang } = this.props;\n return API_FORM_LOCALES[lang!][key];\n }\n\n private msg(msg: string, type: MsgType = 'success') {\n const { mute } = this.props;\n if (!mute) message[type](msg);\n }\n\n private handleBack = () => {\n history.back();\n };\n\n private setInitialValues = (values?: any) => {\n this._initialValues = values || this.formInstance?.getFieldsValue() || {};\n };\n\n handleStateRequest(stagePayload: StagePayload) {\n this.setState({ loading: true });\n return this.props.transformRequest?.(stagePayload) || stagePayload.payload;\n }\n\n handleStateResponse(res: StageData) {\n const { name } = this.props;\n this.setState({ loading: false });\n nx.$event?.emit?.(`${name}:refetch`);\n return this.props.transformResponse?.(res) || res.data;\n }\n\n handleFinish = (values: any) => {\n if (!this.canSave) {\n this.msg(this.t('no_change'), 'info');\n return;\n }\n this.isEdit ? this.onResourceUpdate(values) : this.onResourceCreate(values);\n };\n\n private onResourceUpdate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { id: params!.id, ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'update', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n params,\n };\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_update`](_payload)\n .then((res: any) => {\n this.msg(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n onMutate?.(mutateArgs);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n };\n\n private onResourceCreate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'create', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n params,\n };\n\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_create`](_payload)\n .then((res: any) => {\n this.msg(this.t('create_success'));\n this.handleStateResponse({ stage: 'create', data: res });\n this.formInstance?.resetFields();\n onMutate?.(mutateArgs);\n history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\n };\n\n // hotkey save handler (replaces useKeyboardSave hook)\n handleKeydown = (e: KeyboardEvent) => {\n const { disableHotkeySave } = this.props;\n const isSave = (e.ctrlKey || e.metaKey) && (e.key === 's' || e.key === 'S');\n if (isSave) {\n e.preventDefault();\n if (!disableHotkeySave) {\n this.formInstance?.submit();\n }\n }\n };\n\n handleValuesChange = (_: any, allValues: any) => {\n this.setState({\n touched: !deepEqual(this._initialValues, allValues),\n });\n };\n\n componentDidMount() {\n this._isMounted = true;\n // attach hotkey listener\n window.addEventListener('keydown', this.handleKeydown);\n // initialize detail if editing\n this.initDetailIfNeeded();\n }\n\n componentDidUpdate(prevProps: ReactAntResourceFormProps) {\n const prevId = prevProps.params?.id;\n const curId = this.props.params?.id;\n // re-init when id changed or from create -> edit\n if (prevId !== curId) {\n this.initDetailIfNeeded();\n }\n\n // loading update\n if (prevProps.loading !== this.props.loading) {\n this.setState({ loading: this.props.loading! });\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('keydown', this.handleKeydown);\n this._isMounted = false;\n }\n\n initDetailIfNeeded() {\n const { params, name, initGuard } = this.props;\n const resourceShow = `${name}_show`;\n\n if (this.isEdit) {\n const payload = { id: params!.id };\n const _payload = this.handleStateRequest({ stage: 'show', payload });\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n nx.$api[resourceShow](_payload)\n .then((res: any) => {\n if (!this._isMounted) return; // 👈 关键:防止操作已卸载组件\n const data = this.handleStateResponse({ stage: 'show', data: res });\n this.formInstance?.setFieldsValue?.(data);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n });\n });\n } else {\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: null,\n isEdit: false,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n this.setInitialValues();\n this.setState({ loading: false });\n });\n }\n }\n\n render() {\n const {\n className,\n name,\n meta,\n children,\n lang,\n title,\n extra,\n size,\n okText,\n backText,\n okProps,\n backProps,\n classNames,\n params,\n transformRequest,\n transformResponse,\n disableHotkeySave,\n blocker,\n onInit,\n onMutate,\n initGuard,\n submitGuard,\n loading,\n ...rest\n } = this.props;\n\n return (\n <Card\n title={this.titleView}\n extra={this.extraView}\n size={size}\n classNames={classNames}\n data-component={CLASS_NAME}\n data-blocker={blocker}\n className={cx(CLASS_NAME, className)}>\n <Spin spinning={this.state.loading}>\n <ReactAntdFormSchema\n meta={meta}\n ref={this.formRef}\n onValuesChange={this.handleValuesChange}\n onFinish={this.handleFinish}\n {...rest}>\n {this.childrenView}\n </ReactAntdFormSchema>\n </Spin>\n </Card>\n );\n }\n}\n\n\nexport default ReactAntResourceForm;\n","export const API_FORM_LOCALES = {\n 'zh-CN': {\n create: '创建',\n update: '保存',\n create_title: '创建',\n update_title: '更新',\n create_success: '创建成功',\n update_success: '更新成功',\n submit: '提交',\n back: '返回',\n no_change: '没有修改',\n },\n 'en-US': {\n create: 'Create',\n update: 'Save',\n create_title: 'Create',\n update_title: 'Update',\n create_success: 'Create success',\n update_success: 'Update success',\n submit: 'Submit',\n back: 'Back',\n no_change: 'No change',\n },\n};\n"]}
|
package/dist/main.d.mts
CHANGED
|
@@ -3,12 +3,6 @@ import React, { Component, FC } from 'react';
|
|
|
3
3
|
import { ButtonProps, CardProps, FormInstance } from 'antd';
|
|
4
4
|
import { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';
|
|
5
5
|
|
|
6
|
-
declare global {
|
|
7
|
-
interface NxStatic {
|
|
8
|
-
$api: Record<string, any>;
|
|
9
|
-
$event: any;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
6
|
type StagePayload = {
|
|
13
7
|
stage: 'show' | 'create' | 'update';
|
|
14
8
|
payload: any;
|
|
@@ -37,6 +31,13 @@ type SubmitGuardArgs = {
|
|
|
37
31
|
isEdit: boolean;
|
|
38
32
|
values: any;
|
|
39
33
|
};
|
|
34
|
+
|
|
35
|
+
declare global {
|
|
36
|
+
interface NxStatic {
|
|
37
|
+
$api: Record<string, any>;
|
|
38
|
+
$event: any;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
40
41
|
type ReactAntResourceFormProps = {
|
|
41
42
|
lang?: string;
|
|
42
43
|
loading?: boolean;
|
|
@@ -44,6 +45,7 @@ type ReactAntResourceFormProps = {
|
|
|
44
45
|
backText?: string;
|
|
45
46
|
params?: Record<string, any>;
|
|
46
47
|
blocker?: boolean;
|
|
48
|
+
mute?: boolean;
|
|
47
49
|
disableHotkeySave?: boolean;
|
|
48
50
|
initGuard?: (args: InitGuardArgs) => Promise<void>;
|
|
49
51
|
submitGuard?: (args: SubmitGuardArgs) => Promise<void>;
|
|
@@ -73,12 +75,20 @@ type IState = {
|
|
|
73
75
|
*
|
|
74
76
|
* initGuard | submitGuard:
|
|
75
77
|
* https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc
|
|
78
|
+
*
|
|
79
|
+
* onMutate:
|
|
80
|
+
* 在 create/update 成功后,需要刷新列表,可以用 onMutate 继续后续处理。
|
|
81
|
+
*
|
|
82
|
+
* blocker:
|
|
83
|
+
* 这个解决的问题是,目前 nice-form 里默认是 grid layout,导致部分情况下,卡片内部的 style 表现很不正常。
|
|
84
|
+
* 特别是有非 antd 组件的情况下,比如我自己的 react-ckeditor
|
|
76
85
|
*/
|
|
77
86
|
declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {
|
|
78
87
|
static defaultProps: {
|
|
79
88
|
lang: string;
|
|
80
89
|
disableHotkeySave: boolean;
|
|
81
90
|
blocker: boolean;
|
|
91
|
+
mute: boolean;
|
|
82
92
|
initGuard: () => Promise<void>;
|
|
83
93
|
submitGuard: () => Promise<void>;
|
|
84
94
|
};
|
|
@@ -94,6 +104,7 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
94
104
|
get formInstance(): FormInstance<any> | null;
|
|
95
105
|
constructor(props: ReactAntResourceFormProps);
|
|
96
106
|
private t;
|
|
107
|
+
private msg;
|
|
97
108
|
private handleBack;
|
|
98
109
|
private setInitialValues;
|
|
99
110
|
handleStateRequest(stagePayload: StagePayload): any;
|
|
@@ -109,9 +120,17 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
109
120
|
initDetailIfNeeded(): void;
|
|
110
121
|
render(): React.JSX.Element;
|
|
111
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @Author: aric 1290657123@qq.com
|
|
126
|
+
* @Date: 2025-10-31 13:20:41
|
|
127
|
+
* @LastEditors: aric 1290657123@qq.com
|
|
128
|
+
* @LastEditTime: 2025-10-31 13:24:38
|
|
129
|
+
*/
|
|
130
|
+
|
|
112
131
|
type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
113
132
|
allowFields?: string[];
|
|
114
133
|
};
|
|
115
134
|
declare const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps>;
|
|
116
135
|
|
|
117
|
-
export { ReactAntResourceFormFc, type ReactAntResourceFormProps, ReactAntResourceForm as default };
|
|
136
|
+
export { ReactAntResourceFormFc, type ReactAntResourceFormFcProps, type ReactAntResourceFormProps, ReactAntResourceForm as default };
|
package/dist/main.d.ts
CHANGED
|
@@ -3,12 +3,6 @@ import React, { Component, FC } from 'react';
|
|
|
3
3
|
import { ButtonProps, CardProps, FormInstance } from 'antd';
|
|
4
4
|
import { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';
|
|
5
5
|
|
|
6
|
-
declare global {
|
|
7
|
-
interface NxStatic {
|
|
8
|
-
$api: Record<string, any>;
|
|
9
|
-
$event: any;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
6
|
type StagePayload = {
|
|
13
7
|
stage: 'show' | 'create' | 'update';
|
|
14
8
|
payload: any;
|
|
@@ -37,6 +31,13 @@ type SubmitGuardArgs = {
|
|
|
37
31
|
isEdit: boolean;
|
|
38
32
|
values: any;
|
|
39
33
|
};
|
|
34
|
+
|
|
35
|
+
declare global {
|
|
36
|
+
interface NxStatic {
|
|
37
|
+
$api: Record<string, any>;
|
|
38
|
+
$event: any;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
40
41
|
type ReactAntResourceFormProps = {
|
|
41
42
|
lang?: string;
|
|
42
43
|
loading?: boolean;
|
|
@@ -44,6 +45,7 @@ type ReactAntResourceFormProps = {
|
|
|
44
45
|
backText?: string;
|
|
45
46
|
params?: Record<string, any>;
|
|
46
47
|
blocker?: boolean;
|
|
48
|
+
mute?: boolean;
|
|
47
49
|
disableHotkeySave?: boolean;
|
|
48
50
|
initGuard?: (args: InitGuardArgs) => Promise<void>;
|
|
49
51
|
submitGuard?: (args: SubmitGuardArgs) => Promise<void>;
|
|
@@ -73,12 +75,20 @@ type IState = {
|
|
|
73
75
|
*
|
|
74
76
|
* initGuard | submitGuard:
|
|
75
77
|
* https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc
|
|
78
|
+
*
|
|
79
|
+
* onMutate:
|
|
80
|
+
* 在 create/update 成功后,需要刷新列表,可以用 onMutate 继续后续处理。
|
|
81
|
+
*
|
|
82
|
+
* blocker:
|
|
83
|
+
* 这个解决的问题是,目前 nice-form 里默认是 grid layout,导致部分情况下,卡片内部的 style 表现很不正常。
|
|
84
|
+
* 特别是有非 antd 组件的情况下,比如我自己的 react-ckeditor
|
|
76
85
|
*/
|
|
77
86
|
declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {
|
|
78
87
|
static defaultProps: {
|
|
79
88
|
lang: string;
|
|
80
89
|
disableHotkeySave: boolean;
|
|
81
90
|
blocker: boolean;
|
|
91
|
+
mute: boolean;
|
|
82
92
|
initGuard: () => Promise<void>;
|
|
83
93
|
submitGuard: () => Promise<void>;
|
|
84
94
|
};
|
|
@@ -94,6 +104,7 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
94
104
|
get formInstance(): FormInstance<any> | null;
|
|
95
105
|
constructor(props: ReactAntResourceFormProps);
|
|
96
106
|
private t;
|
|
107
|
+
private msg;
|
|
97
108
|
private handleBack;
|
|
98
109
|
private setInitialValues;
|
|
99
110
|
handleStateRequest(stagePayload: StagePayload): any;
|
|
@@ -109,6 +120,14 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
109
120
|
initDetailIfNeeded(): void;
|
|
110
121
|
render(): React.JSX.Element;
|
|
111
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @Author: aric 1290657123@qq.com
|
|
126
|
+
* @Date: 2025-10-31 13:20:41
|
|
127
|
+
* @LastEditors: aric 1290657123@qq.com
|
|
128
|
+
* @LastEditTime: 2025-10-31 13:24:38
|
|
129
|
+
*/
|
|
130
|
+
|
|
112
131
|
type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
113
132
|
allowFields?: string[];
|
|
114
133
|
};
|
|
@@ -116,4 +135,4 @@ declare const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps>;
|
|
|
116
135
|
|
|
117
136
|
// @ts-ignore
|
|
118
137
|
export = ReactAntResourceForm;
|
|
119
|
-
export { ReactAntResourceFormFc, type ReactAntResourceFormProps };
|
|
138
|
+
export { ReactAntResourceFormFc, type ReactAntResourceFormFcProps, type ReactAntResourceFormProps };
|
package/dist/main.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var w=Object.defineProperty;var R=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var
|
|
1
|
+
var w=Object.defineProperty;var R=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var k=(a,i,t)=>i in a?w(a,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[i]=t,c=(a,i)=>{for(var t in i||(i={}))I.call(i,t)&&k(a,t,i[t]);if(R)for(var t of R(i))x.call(i,t)&&k(a,t,i[t]);return a};var h=(a,i)=>w(a,"name",{value:i,configurable:!0});var _=(a,i)=>{var t={};for(var e in a)I.call(a,e)&&i.indexOf(e)<0&&(t[e]=a[e]);if(a!=null&&R)for(var e of R(a))i.indexOf(e)<0&&x.call(a,e)&&(t[e]=a[e]);return t};var u=(a,i,t)=>k(a,typeof i!="symbol"?i+"":i,t);import L from"classnames";import l,{Component as O}from"react";import{Button as b,Card as $,message as M,Space as C,Spin as T}from"antd";import U from"@jswork/react-ant-form-schema";import{ArrowLeftOutlined as F,DiffOutlined as B,SaveOutlined as K}from"@ant-design/icons";import z from"fast-deep-equal";var A={"zh-CN":{create:"\u521B\u5EFA",update:"\u4FDD\u5B58",create_title:"\u521B\u5EFA",update_title:"\u66F4\u65B0",create_success:"\u521B\u5EFA\u6210\u529F",update_success:"\u66F4\u65B0\u6210\u529F",submit:"\u63D0\u4EA4",back:"\u8FD4\u56DE",no_change:"\u6CA1\u6709\u4FEE\u6539"},"en-US":{create:"Create",update:"Save",create_title:"Create",update_title:"Update",create_success:"Create success",update_success:"Update success",submit:"Submit",back:"Back",no_change:"No change"}};import E from"@jswork/next";import"@jswork/next-compact-object";var v="react-ant-resource-form",f,G=(f=class extends O{constructor(t){var e;super(t);u(this,"formRef",l.createRef());u(this,"_isMounted",!1);u(this,"_initialValues",null);u(this,"handleBack",h(()=>{history.back()},"handleBack"));u(this,"setInitialValues",h(t=>{var e;this._initialValues=t||((e=this.formInstance)==null?void 0:e.getFieldsValue())||{}},"setInitialValues"));u(this,"handleFinish",h(t=>{if(!this.canSave){this.msg(this.t("no_change"),"info");return}this.isEdit?this.onResourceUpdate(t):this.onResourceCreate(t)},"handleFinish"));u(this,"onResourceUpdate",h(t=>{let{params:e,name:s,submitGuard:n,onMutate:r}=this.props,o=c(c({id:e.id},t),e),d=this.handleStateRequest({stage:"update",payload:o}),p={name:s,payload:d,isEdit:!0,values:t,params:e},g={name:s,payload:d,isEdit:!0,values:t};n==null||n(p).then(()=>{E.$api[`${s}_update`](d).then(m=>{this.msg(this.t("update_success")),this.handleStateResponse({stage:"update",data:m}),r==null||r(g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues(),this.handleValuesChange(null,this._initialValues)})})},"onResourceUpdate"));u(this,"onResourceCreate",h(t=>{let{params:e,name:s,submitGuard:n,onMutate:r}=this.props,o=c(c({},t),e),d=this.handleStateRequest({stage:"create",payload:o}),p={name:s,payload:d,isEdit:!1,values:t,params:e},g={name:s,payload:d,isEdit:!1,values:t};n==null||n(p).then(()=>{E.$api[`${s}_create`](d).then(m=>{var S;this.msg(this.t("create_success")),this.handleStateResponse({stage:"create",data:m}),(S=this.formInstance)==null||S.resetFields(),r==null||r(g),history.back()}).finally(()=>this.setState({loading:!1}))})},"onResourceCreate"));u(this,"handleKeydown",h(t=>{var n;let{disableHotkeySave:e}=this.props;(t.ctrlKey||t.metaKey)&&(t.key==="s"||t.key==="S")&&(t.preventDefault(),e||(n=this.formInstance)==null||n.submit())},"handleKeydown"));u(this,"handleValuesChange",h((t,e)=>{this.setState({touched:!z(this._initialValues,e)})},"handleValuesChange"));this.state={loading:t.loading,touched:!1},this.handleStateRequest=this.handleStateRequest.bind(this),this.handleStateResponse=this.handleStateResponse.bind(this),this.initDetailIfNeeded=this.initDetailIfNeeded.bind(this),(e=t.onInit)==null||e.call(t,this)}get isEdit(){let{params:t}=this.props;return!!(t!=null&&t.id)}get canSave(){let{touched:t,loading:e}=this.state;return this.isEdit?t&&!e:!e}get titleView(){let{title:t}=this.props,e=t||(this.isEdit?this.t("update_title"):this.t("create_title"));return l.createElement(C,null,e,l.createElement("span",null,this.touchedView))}get touchedView(){return this.isEdit&&this.state.touched?l.createElement("em",{style:{color:"#f60"}},l.createElement(B,null)):null}get extraView(){let{extra:t,backText:e,backProps:s}=this.props;return t||l.createElement(b,c({size:"small",icon:l.createElement(F,null),onClick:this.handleBack},s),e||this.t("back"))}get childrenView(){let{okText:t,backText:e,okProps:s,backProps:n,children:r}=this.props,o=t||(this.isEdit?this.t("update"):this.t("create"));return r||l.createElement(C,null,l.createElement(b,c({disabled:!this.canSave,htmlType:"submit",type:"primary",icon:l.createElement(K,null)},s),o||this.t("submit")),l.createElement(b,c({icon:l.createElement(F,null),onClick:this.handleBack},n),e||this.t("back")))}get formInstance(){var t;return(t=this.formRef)==null?void 0:t.current}t(t){let{lang:e}=this.props;return A[e][t]}msg(t,e="success"){let{mute:s}=this.props;s||M[e](t)}handleStateRequest(t){var e,s;return this.setState({loading:!0}),((s=(e=this.props).transformRequest)==null?void 0:s.call(e,t))||t.payload}handleStateResponse(t){var s,n,r,o;let{name:e}=this.props;return this.setState({loading:!1}),(n=(s=E.$event)==null?void 0:s.emit)==null||n.call(s,`${e}:refetch`),((o=(r=this.props).transformResponse)==null?void 0:o.call(r,t))||t.data}componentDidMount(){this._isMounted=!0,window.addEventListener("keydown",this.handleKeydown),this.initDetailIfNeeded()}componentDidUpdate(t){var n,r;let e=(n=t.params)==null?void 0:n.id,s=(r=this.props.params)==null?void 0:r.id;e!==s&&this.initDetailIfNeeded(),t.loading!==this.props.loading&&this.setState({loading:this.props.loading})}componentWillUnmount(){window.removeEventListener("keydown",this.handleKeydown),this._isMounted=!1}initDetailIfNeeded(){let{params:t,name:e,initGuard:s}=this.props,n=`${e}_show`;if(this.isEdit){let r={id:t.id},o=this.handleStateRequest({stage:"show",payload:r}),d={name:e,payload:o,isEdit:!0,params:t};s==null||s(d).then(()=>{E.$api[n](o).then(p=>{var m,S;if(!this._isMounted)return;let g=this.handleStateResponse({stage:"show",data:p});(S=(m=this.formInstance)==null?void 0:m.setFieldsValue)==null||S.call(m,g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues()})})}else{let r={name:e,payload:null,isEdit:!1,params:t};s==null||s(r).then(()=>{this.setInitialValues(),this.setState({loading:!1})})}}render(){let V=this.props,{className:t,name:e,meta:s,children:n,lang:r,title:o,extra:d,size:p,okText:g,backText:m,okProps:S,backProps:j,classNames:P,params:tt,transformRequest:et,transformResponse:st,disableHotkeySave:at,blocker:q,onInit:it,onMutate:nt,initGuard:rt,submitGuard:ot,loading:lt}=V,D=_(V,["className","name","meta","children","lang","title","extra","size","okText","backText","okProps","backProps","classNames","params","transformRequest","transformResponse","disableHotkeySave","blocker","onInit","onMutate","initGuard","submitGuard","loading"]);return l.createElement($,{title:this.titleView,extra:this.extraView,size:p,classNames:P,"data-component":v,"data-blocker":q,className:L(v,t)},l.createElement(T,{spinning:this.state.loading},l.createElement(U,c({meta:s,ref:this.formRef,onValuesChange:this.handleValuesChange,onFinish:this.handleFinish},D),this.childrenView)))}},h(f,"ReactAntResourceForm"),u(f,"defaultProps",{lang:"zh-CN",disableHotkeySave:!1,blocker:!1,mute:!1,initGuard:h(()=>Promise.resolve(),"initGuard"),submitGuard:h(()=>Promise.resolve(),"submitGuard")}),f),y=G;import H from"react";import{useParams as W,useSearchParams as J}from"react-router-dom";import Q from"fromentries";import N from"@jswork/next";var X=h((a,i)=>(N.forIn(a,t=>{i.includes(t)||delete a[t]}),a),"retainKeys"),Y=h(a=>{let d=a,{params:i,allowFields:t}=d,e=_(d,["params","allowFields"]),s=W(),[n]=J(),r=Q(n),o=N.compactObject(c(c(c({},r),s),i));return t!=null&&t.length&&t.length>0&&X(o,t),H.createElement(y,c({params:o},e))},"ReactAntResourceFormFc"),Z=Y;var vt=y;export{Z as ReactAntResourceFormFc,vt as default};
|
|
2
2
|
//# sourceMappingURL=main.esm.js.map
|
package/dist/main.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/locales.ts","../src/main.tsx"],"sourcesContent":["// import noop from '@jswork/noop';\nimport cx from 'classnames';\nimport React, { Component, FC } from 'react';\nimport type { FormInstance } from 'antd';\nimport { Button, ButtonProps, Card, CardProps, message, Space, Spin } from 'antd';\nimport ReactAntdFormSchema, { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';\nimport { ArrowLeftOutlined, DiffOutlined, SaveOutlined } from '@ant-design/icons';\nimport { API_FORM_LOCALES } from './locales';\nimport nx from '@jswork/next';\nimport '@jswork/next-compact-object';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport deepEqual from 'fast-deep-equal';\nimport fromEntries from 'fromentries';\n\ndeclare global {\n interface NxStatic {\n $api: Record<string, any>;\n $event: any;\n }\n}\n\ntype StagePayload = {\n stage: 'show' | 'create' | 'update';\n payload: any;\n};\n\ntype StageData = {\n stage: 'show' | 'create' | 'update';\n data: any;\n};\n\ntype MutateArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n values: any;\n};\n\ntype InitGuardArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n};\n\ntype SubmitGuardArgs = {\n name?: string;\n params?: Record<string, any>;\n payload: any;\n isEdit: boolean;\n values: any;\n};\n\nexport type ReactAntResourceFormProps = {\n lang?: string;\n loading?: boolean;\n okText?: string;\n backText?: string;\n params?: Record<string, any>;\n blocker?: boolean;\n disableHotkeySave?: boolean;\n initGuard?: (args: InitGuardArgs) => Promise<void>;\n submitGuard?: (args: SubmitGuardArgs) => Promise<void>;\n transformRequest?: (payload: StagePayload) => any;\n transformResponse?: (res: StageData) => any;\n okProps?: ButtonProps;\n backProps?: ButtonProps;\n classNames?: CardProps['classNames'];\n size?: CardProps['size'];\n extra?: CardProps['extra'];\n title?: CardProps['title'];\n onInit?: (ctx: ReactAntResourceForm) => void;\n onMutate?: (args: MutateArgs) => void;\n} & ReactAntdFormSchemaProps;\n\ntype IState = {\n loading: boolean;\n touched: boolean;\n};\n\nconst CLASS_NAME = 'react-ant-resource-form';\n\nconst retainKeys = (obj: Record<string, any>, keys: string[]) => {\n nx.forIn(obj, (key) => {\n if (!keys.includes(key)) {\n delete obj[key];\n }\n });\n return obj;\n};\n\n/**\n * 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null\n * 这个情况仅在 class component 里才会出现,function component 里不会:\n * 报错示例:\n *\n * this.formRef?: null\n * index.tsx:229 this.formRef?: {getFieldValue: ƒ, getFieldsValue: ƒ, getFieldError: ƒ, getFieldWarning: ƒ, getFieldsError: ƒ, …}\n * index.tsx:229 this.formRef?: null\n *\n * initGuard | submitGuard:\n * https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc\n */\n\nclass ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {\n public static defaultProps = {\n lang: 'zh-CN',\n disableHotkeySave: false,\n blocker: false,\n initGuard: () => Promise.resolve(),\n submitGuard: () => Promise.resolve(),\n };\n\n private formRef = React.createRef<FormInstance>(); // 注意类型\n private _isMounted = false;\n private _initialValues = null;\n\n get isEdit() {\n const { params } = this.props;\n return Boolean(params?.id);\n }\n\n get canSave() {\n const { touched, loading } = this.state;\n if (!this.isEdit) return !loading;\n return touched && !loading;\n }\n\n get titleView() {\n const { title } = this.props;\n const _title = title || (this.isEdit ? this.t('update_title') : this.t('create_title'));\n return (\n <Space>\n {_title}\n <span>{this.touchedView}</span>\n </Space>\n );\n }\n\n get touchedView() {\n if (!this.isEdit) return null;\n return this.state.touched ? (\n <em style={{ color: '#f60' }}>\n <DiffOutlined />\n </em>\n ) : null;\n }\n\n get extraView() {\n const { extra, backText, backProps } = this.props;\n if (extra) return extra;\n return (\n <Button size=\"small\" icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n );\n }\n\n get childrenView() {\n const { okText, backText, okProps, backProps, children } = this.props;\n const _okText = okText || (this.isEdit ? this.t('update') : this.t('create'));\n if (children) return children;\n\n return (\n <Space>\n <Button\n disabled={!this.canSave}\n htmlType=\"submit\"\n type=\"primary\"\n icon={<SaveOutlined />}\n {...okProps}>\n {_okText || this.t('submit')}\n </Button>\n <Button icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n </Space>\n );\n }\n\n get formInstance() {\n return this.formRef?.current;\n }\n\n constructor(props: ReactAntResourceFormProps) {\n super(props);\n this.state = {\n loading: props.loading!,\n touched: false,\n };\n\n this.handleStateRequest = this.handleStateRequest.bind(this);\n this.handleStateResponse = this.handleStateResponse.bind(this);\n this.initDetailIfNeeded = this.initDetailIfNeeded.bind(this);\n\n props.onInit?.(this);\n }\n\n private t(key: string) {\n const { lang } = this.props;\n return API_FORM_LOCALES[lang!][key];\n }\n\n private handleBack = () => {\n history.back();\n };\n\n private setInitialValues = (values?: any) => {\n this._initialValues = values || this.formInstance?.getFieldsValue() || {};\n };\n\n handleStateRequest(stagePayload: StagePayload) {\n this.setState({ loading: true });\n return this.props.transformRequest?.(stagePayload) || stagePayload.payload;\n }\n\n handleStateResponse(res: StageData) {\n const { name } = this.props;\n this.setState({ loading: false });\n nx.$event?.emit?.(`${name}:refetch`);\n return this.props.transformResponse?.(res) || res.data;\n }\n\n handleFinish = (values: any) => {\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n this.isEdit ? this.onResourceUpdate(values) : this.onResourceCreate(values);\n };\n\n private onResourceUpdate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { id: params!.id, ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'update', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n params,\n };\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_update`](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n onMutate?.(mutateArgs);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n };\n\n private onResourceCreate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'create', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n params,\n };\n\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_create`](_payload)\n .then((res: any) => {\n void message.success(this.t('create_success'));\n this.handleStateResponse({ stage: 'create', data: res });\n this.formInstance?.resetFields();\n onMutate?.(mutateArgs);\n history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\n };\n\n // hotkey save handler (replaces useKeyboardSave hook)\n handleKeydown = (e: KeyboardEvent) => {\n const { disableHotkeySave } = this.props;\n const isSave = (e.ctrlKey || e.metaKey) && (e.key === 's' || e.key === 'S');\n if (isSave) {\n e.preventDefault();\n if (!disableHotkeySave) {\n this.formInstance?.submit();\n }\n }\n };\n\n handleValuesChange = (_: any, allValues: any) => {\n this.setState({\n touched: !deepEqual(this._initialValues, allValues),\n });\n };\n\n componentDidMount() {\n this._isMounted = true;\n // attach hotkey listener\n window.addEventListener('keydown', this.handleKeydown);\n // initialize detail if editing\n this.initDetailIfNeeded();\n }\n\n componentDidUpdate(prevProps: ReactAntResourceFormProps) {\n const prevId = prevProps.params?.id;\n const curId = this.props.params?.id;\n // re-init when id changed or from create -> edit\n if (prevId !== curId) {\n this.initDetailIfNeeded();\n }\n\n // loading update\n if (prevProps.loading !== this.props.loading) {\n this.setState({ loading: this.props.loading! });\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('keydown', this.handleKeydown);\n this._isMounted = false;\n }\n\n initDetailIfNeeded() {\n const { params, name, initGuard } = this.props;\n const resourceShow = `${name}_show`;\n\n if (this.isEdit) {\n const payload = { id: params!.id };\n const _payload = this.handleStateRequest({ stage: 'show', payload });\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n nx.$api[resourceShow](_payload)\n .then((res: any) => {\n if (!this._isMounted) return; // 👈 关键:防止操作已卸载组件\n const data = this.handleStateResponse({ stage: 'show', data: res });\n this.formInstance?.setFieldsValue?.(data);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n });\n });\n } else {\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: null,\n isEdit: false,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n this.setInitialValues();\n this.setState({ loading: false });\n });\n }\n }\n\n render() {\n const {\n className,\n name,\n meta,\n children,\n lang,\n title,\n extra,\n size,\n okText,\n backText,\n okProps,\n backProps,\n classNames,\n params,\n transformRequest,\n transformResponse,\n disableHotkeySave,\n blocker,\n onInit,\n initGuard,\n submitGuard,\n loading,\n ...rest\n } = this.props;\n\n return (\n <Card\n title={this.titleView}\n extra={this.extraView}\n size={size}\n classNames={classNames}\n data-component={CLASS_NAME}\n data-blocker={blocker}\n className={cx(CLASS_NAME, className)}>\n <Spin spinning={this.state.loading}>\n <ReactAntdFormSchema\n meta={meta}\n ref={this.formRef}\n onValuesChange={this.handleValuesChange}\n onFinish={this.handleFinish}\n {...rest}>\n {this.childrenView}\n </ReactAntdFormSchema>\n </Spin>\n </Card>\n );\n }\n}\n\nexport type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {\n allowFields?: string[];\n}\n\nconst ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {\n const { params: overrideParams, allowFields, ...rest } = props;\n const params = useParams();\n const [searchParams] = useSearchParams();\n const _searchParams = fromEntries(searchParams as any);\n const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });\n if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);\n return <ReactAntResourceForm params={_params} {...rest} />;\n};\n\nexport default ReactAntResourceForm;\nexport { ReactAntResourceFormFc };\n","export const API_FORM_LOCALES = {\n 'zh-CN': {\n create: '创建',\n update: '保存',\n create_title: '创建',\n update_title: '更新',\n create_success: '创建成功',\n update_success: '更新成功',\n submit: '提交',\n back: '返回',\n no_change: '没有修改',\n },\n 'en-US': {\n create: 'Create',\n update: 'Save',\n create_title: 'Create',\n update_title: 'Update',\n create_success: 'Create success',\n update_success: 'Update success',\n submit: 'Submit',\n back: 'Back',\n no_change: 'No change',\n },\n};\n","import ReactAntResourceForm, { ReactAntResourceFormFc } from '.';\nimport type { ReactAntResourceFormProps } from '.';\n\nexport default ReactAntResourceForm;\nexport { ReactAntResourceFormFc };\nexport type { ReactAntResourceFormProps };\n"],"mappings":"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","names":["cx","React","Component","Button","Card","message","Space","Spin","ReactAntdFormSchema","ArrowLeftOutlined","DiffOutlined","SaveOutlined","API_FORM_LOCALES","create","update","create_title","update_title","create_success","update_success","submit","back","no_change","nx","useParams","useSearchParams","deepEqual","fromEntries","CLASS_NAME","retainKeys","__name","obj","keys","nx","forIn","key","includes","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","history","back","setInitialValues","values","formInstance","getFieldsValue","handleFinish","canSave","message","info","t","isEdit","onResourceUpdate","onResourceCreate","params","name","submitGuard","onMutate","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","mutateArgs","then","$api","res","success","handleStateResponse","data","finally","setState","loading","handleValuesChange","resetFields","handleKeydown","e","disableHotkeySave","ctrlKey","metaKey","preventDefault","submit","_","allValues","touched","deepEqual","state","bind","initDetailIfNeeded","onInit","Boolean","titleView","title","_title","Space","span","touchedView","em","style","color","DiffOutlined","extraView","extra","backText","backProps","Button","size","icon","ArrowLeftOutlined","onClick","childrenView","okText","okProps","children","_okText","disabled","htmlType","type","SaveOutlined","current","lang","API_FORM_LOCALES","stagePayload","_b","transformRequest","_c","_d","$event","emit","transformResponse","componentDidMount","window","addEventListener","componentDidUpdate","prevProps","prevId","curId","componentWillUnmount","removeEventListener","initGuard","resourceShow","initGuardArgs","setFieldsValue","render","className","meta","classNames","blocker","rest","Card","data-component","data-blocker","cx","Spin","spinning","ReactAntdFormSchema","ref","onValuesChange","onFinish","__publicField","defaultProps","Promise","resolve","ReactAntResourceFormFc","overrideParams","allowFields","useParams","searchParams","useSearchParams","_searchParams","fromEntries","_params","compactObject","length","index_default","main_default","ReactAntResourceForm"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/locales.ts","../src/index-rc.tsx","../src/main.tsx"],"sourcesContent":["// import noop from '@jswork/noop';\nimport cx from 'classnames';\nimport React, { Component } from 'react';\nimport { ButtonProps, CardProps, FormInstance } from 'antd';\nimport { Button, Card, message, Space, Spin } from 'antd';\nimport ReactAntdFormSchema, { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';\nimport { ArrowLeftOutlined, DiffOutlined, SaveOutlined } from '@ant-design/icons';\nimport deepEqual from 'fast-deep-equal';\nimport {\n InitGuardArgs,\n MsgType,\n MutateArgs,\n StageData,\n StagePayload,\n SubmitGuardArgs,\n} from './types';\nimport { API_FORM_LOCALES } from './locales';\nimport nx from '@jswork/next';\nimport '@jswork/next-compact-object';\n\ndeclare global {\n interface NxStatic {\n $api: Record<string, any>;\n $event: any;\n }\n}\n\nconst CLASS_NAME = 'react-ant-resource-form';\n\nexport type ReactAntResourceFormProps = {\n lang?: string;\n loading?: boolean;\n okText?: string;\n backText?: string;\n params?: Record<string, any>;\n blocker?: boolean;\n mute?: boolean;\n disableHotkeySave?: boolean;\n initGuard?: (args: InitGuardArgs) => Promise<void>;\n submitGuard?: (args: SubmitGuardArgs) => Promise<void>;\n transformRequest?: (payload: StagePayload) => any;\n transformResponse?: (res: StageData) => any;\n okProps?: ButtonProps;\n backProps?: ButtonProps;\n classNames?: CardProps['classNames'];\n size?: CardProps['size'];\n extra?: CardProps['extra'];\n title?: CardProps['title'];\n onInit?: (ctx: ReactAntResourceForm) => void;\n onMutate?: (args: MutateArgs) => void;\n} & ReactAntdFormSchemaProps;\n\nexport type IState = {\n loading: boolean;\n touched: boolean;\n};\n\n/**\n * 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null\n * 这个情况仅在 class component 里才会出现,function component 里不会:\n * 报错示例:\n *\n * this.formRef?: null\n * index.tsx:229 this.formRef?: {getFieldValue: ƒ, getFieldsValue: ƒ, getFieldError: ƒ, getFieldWarning: ƒ, getFieldsError: ƒ, …}\n * index.tsx:229 this.formRef?: null\n *\n * initGuard | submitGuard:\n * https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc\n *\n * onMutate:\n * 在 create/update 成功后,需要刷新列表,可以用 onMutate 继续后续处理。\n *\n * blocker:\n * 这个解决的问题是,目前 nice-form 里默认是 grid layout,导致部分情况下,卡片内部的 style 表现很不正常。\n * 特别是有非 antd 组件的情况下,比如我自己的 react-ckeditor\n */\n\nclass ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {\n public static defaultProps = {\n lang: 'zh-CN',\n disableHotkeySave: false,\n blocker: false,\n mute: false,\n initGuard: () => Promise.resolve(),\n submitGuard: () => Promise.resolve(),\n };\n\n private formRef = React.createRef<FormInstance>(); // 注意类型\n private _isMounted = false;\n private _initialValues = null;\n\n get isEdit() {\n const { params } = this.props;\n return Boolean(params?.id);\n }\n\n get canSave() {\n const { touched, loading } = this.state;\n if (!this.isEdit) return !loading;\n return touched && !loading;\n }\n\n get titleView() {\n const { title } = this.props;\n const _title = title || (this.isEdit ? this.t('update_title') : this.t('create_title'));\n return (\n <Space>\n {_title}\n <span>{this.touchedView}</span>\n </Space>\n );\n }\n\n get touchedView() {\n if (!this.isEdit) return null;\n return this.state.touched ? (\n <em style={{ color: '#f60' }}>\n <DiffOutlined />\n </em>\n ) : null;\n }\n\n get extraView() {\n const { extra, backText, backProps } = this.props;\n if (extra) return extra;\n return (\n <Button size=\"small\" icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n );\n }\n\n get childrenView() {\n const { okText, backText, okProps, backProps, children } = this.props;\n const _okText = okText || (this.isEdit ? this.t('update') : this.t('create'));\n if (children) return children;\n\n return (\n <Space>\n <Button\n disabled={!this.canSave}\n htmlType=\"submit\"\n type=\"primary\"\n icon={<SaveOutlined />}\n {...okProps}>\n {_okText || this.t('submit')}\n </Button>\n <Button icon={<ArrowLeftOutlined />} onClick={this.handleBack} {...backProps}>\n {backText || this.t('back')}\n </Button>\n </Space>\n );\n }\n\n get formInstance() {\n return this.formRef?.current;\n }\n\n constructor(props: ReactAntResourceFormProps) {\n super(props);\n this.state = {\n loading: props.loading!,\n touched: false,\n };\n\n this.handleStateRequest = this.handleStateRequest.bind(this);\n this.handleStateResponse = this.handleStateResponse.bind(this);\n this.initDetailIfNeeded = this.initDetailIfNeeded.bind(this);\n\n props.onInit?.(this);\n }\n\n private t(key: string) {\n const { lang } = this.props;\n return API_FORM_LOCALES[lang!][key];\n }\n\n private msg(msg: string, type: MsgType = 'success') {\n const { mute } = this.props;\n if (!mute) message[type](msg);\n }\n\n private handleBack = () => {\n history.back();\n };\n\n private setInitialValues = (values?: any) => {\n this._initialValues = values || this.formInstance?.getFieldsValue() || {};\n };\n\n handleStateRequest(stagePayload: StagePayload) {\n this.setState({ loading: true });\n return this.props.transformRequest?.(stagePayload) || stagePayload.payload;\n }\n\n handleStateResponse(res: StageData) {\n const { name } = this.props;\n this.setState({ loading: false });\n nx.$event?.emit?.(`${name}:refetch`);\n return this.props.transformResponse?.(res) || res.data;\n }\n\n handleFinish = (values: any) => {\n if (!this.canSave) {\n this.msg(this.t('no_change'), 'info');\n return;\n }\n this.isEdit ? this.onResourceUpdate(values) : this.onResourceCreate(values);\n };\n\n private onResourceUpdate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { id: params!.id, ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'update', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n params,\n };\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: true,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_update`](_payload)\n .then((res: any) => {\n this.msg(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n onMutate?.(mutateArgs);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n };\n\n private onResourceCreate = (values: any) => {\n const { params, name, submitGuard, onMutate } = this.props;\n const payload = { ...values, ...params };\n const _payload = this.handleStateRequest({ stage: 'create', payload });\n const submitGuardArgs: SubmitGuardArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n params,\n };\n\n const mutateArgs: MutateArgs = {\n name,\n payload: _payload,\n isEdit: false,\n values,\n };\n\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[`${name}_create`](_payload)\n .then((res: any) => {\n this.msg(this.t('create_success'));\n this.handleStateResponse({ stage: 'create', data: res });\n this.formInstance?.resetFields();\n onMutate?.(mutateArgs);\n history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\n };\n\n // hotkey save handler (replaces useKeyboardSave hook)\n handleKeydown = (e: KeyboardEvent) => {\n const { disableHotkeySave } = this.props;\n const isSave = (e.ctrlKey || e.metaKey) && (e.key === 's' || e.key === 'S');\n if (isSave) {\n e.preventDefault();\n if (!disableHotkeySave) {\n this.formInstance?.submit();\n }\n }\n };\n\n handleValuesChange = (_: any, allValues: any) => {\n this.setState({\n touched: !deepEqual(this._initialValues, allValues),\n });\n };\n\n componentDidMount() {\n this._isMounted = true;\n // attach hotkey listener\n window.addEventListener('keydown', this.handleKeydown);\n // initialize detail if editing\n this.initDetailIfNeeded();\n }\n\n componentDidUpdate(prevProps: ReactAntResourceFormProps) {\n const prevId = prevProps.params?.id;\n const curId = this.props.params?.id;\n // re-init when id changed or from create -> edit\n if (prevId !== curId) {\n this.initDetailIfNeeded();\n }\n\n // loading update\n if (prevProps.loading !== this.props.loading) {\n this.setState({ loading: this.props.loading! });\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('keydown', this.handleKeydown);\n this._isMounted = false;\n }\n\n initDetailIfNeeded() {\n const { params, name, initGuard } = this.props;\n const resourceShow = `${name}_show`;\n\n if (this.isEdit) {\n const payload = { id: params!.id };\n const _payload = this.handleStateRequest({ stage: 'show', payload });\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: _payload,\n isEdit: true,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n nx.$api[resourceShow](_payload)\n .then((res: any) => {\n if (!this._isMounted) return; // 👈 关键:防止操作已卸载组件\n const data = this.handleStateResponse({ stage: 'show', data: res });\n this.formInstance?.setFieldsValue?.(data);\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n });\n });\n } else {\n const initGuardArgs: InitGuardArgs = {\n name,\n payload: null,\n isEdit: false,\n params,\n };\n initGuard?.(initGuardArgs).then(() => {\n this.setInitialValues();\n this.setState({ loading: false });\n });\n }\n }\n\n render() {\n const {\n className,\n name,\n meta,\n children,\n lang,\n title,\n extra,\n size,\n okText,\n backText,\n okProps,\n backProps,\n classNames,\n params,\n transformRequest,\n transformResponse,\n disableHotkeySave,\n blocker,\n onInit,\n onMutate,\n initGuard,\n submitGuard,\n loading,\n ...rest\n } = this.props;\n\n return (\n <Card\n title={this.titleView}\n extra={this.extraView}\n size={size}\n classNames={classNames}\n data-component={CLASS_NAME}\n data-blocker={blocker}\n className={cx(CLASS_NAME, className)}>\n <Spin spinning={this.state.loading}>\n <ReactAntdFormSchema\n meta={meta}\n ref={this.formRef}\n onValuesChange={this.handleValuesChange}\n onFinish={this.handleFinish}\n {...rest}>\n {this.childrenView}\n </ReactAntdFormSchema>\n </Spin>\n </Card>\n );\n }\n}\n\n\nexport default ReactAntResourceForm;\n","export const API_FORM_LOCALES = {\n 'zh-CN': {\n create: '创建',\n update: '保存',\n create_title: '创建',\n update_title: '更新',\n create_success: '创建成功',\n update_success: '更新成功',\n submit: '提交',\n back: '返回',\n no_change: '没有修改',\n },\n 'en-US': {\n create: 'Create',\n update: 'Save',\n create_title: 'Create',\n update_title: 'Update',\n create_success: 'Create success',\n update_success: 'Update success',\n submit: 'Submit',\n back: 'Back',\n no_change: 'No change',\n },\n};\n","/**\n * @Author: aric 1290657123@qq.com\n * @Date: 2025-10-31 13:20:41\n * @LastEditors: aric 1290657123@qq.com\n * @LastEditTime: 2025-10-31 13:24:38\n */\nimport React, { FC } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport fromEntries from 'fromentries';\nimport nx from '@jswork/next';\nimport ReactAntResourceForm, { ReactAntResourceFormProps } from '.';\n\nconst retainKeys = (obj: Record<string, any>, keys: string[]) => {\n nx.forIn(obj, (key) => {\n if (!keys.includes(key)) {\n delete obj[key];\n }\n });\n return obj;\n};\n\n\nexport type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {\n allowFields?: string[];\n}\n\nconst ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {\n const { params: overrideParams, allowFields, ...rest } = props;\n const params = useParams();\n const [searchParams] = useSearchParams();\n const _searchParams = fromEntries(searchParams as any);\n const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });\n if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);\n return <ReactAntResourceForm params={_params} {...rest} />;\n};\n\nexport default ReactAntResourceFormFc;\n","import ReactAntResourceForm from '.';\nimport ReactAntResourceFormFc from './index-rc';\nimport type { ReactAntResourceFormProps } from '.';\nimport type { ReactAntResourceFormFcProps } from './index-rc';\n\nexport default ReactAntResourceForm;\nexport { ReactAntResourceFormFc };\nexport type { ReactAntResourceFormFcProps, ReactAntResourceFormProps };\n"],"mappings":"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","names":["cx","React","Component","Button","Card","message","Space","Spin","ReactAntdFormSchema","ArrowLeftOutlined","DiffOutlined","SaveOutlined","deepEqual","API_FORM_LOCALES","create","update","create_title","update_title","create_success","update_success","submit","back","no_change","nx","CLASS_NAME","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","__name","history","back","setInitialValues","values","formInstance","getFieldsValue","handleFinish","canSave","msg","t","isEdit","onResourceUpdate","onResourceCreate","params","name","submitGuard","onMutate","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","mutateArgs","then","nx","$api","res","handleStateResponse","data","finally","setState","loading","handleValuesChange","resetFields","handleKeydown","e","disableHotkeySave","ctrlKey","metaKey","key","preventDefault","submit","_","allValues","touched","deepEqual","state","bind","initDetailIfNeeded","onInit","Boolean","titleView","title","_title","Space","span","touchedView","em","style","color","DiffOutlined","extraView","extra","backText","backProps","Button","size","icon","ArrowLeftOutlined","onClick","childrenView","okText","okProps","children","_okText","disabled","htmlType","type","SaveOutlined","current","lang","API_FORM_LOCALES","mute","message","stagePayload","_b","transformRequest","_c","_d","$event","emit","transformResponse","componentDidMount","window","addEventListener","componentDidUpdate","prevProps","prevId","curId","componentWillUnmount","removeEventListener","initGuard","resourceShow","initGuardArgs","setFieldsValue","render","className","meta","classNames","blocker","rest","Card","data-component","data-blocker","cx","Spin","spinning","ReactAntdFormSchema","ref","onValuesChange","onFinish","__publicField","defaultProps","Promise","resolve","index_default","React","useParams","useSearchParams","fromEntries","nx","retainKeys","__name","obj","keys","nx","forIn","key","includes","ReactAntResourceFormFc","props","params","overrideParams","allowFields","rest","useParams","searchParams","useSearchParams","_searchParams","fromEntries","_params","compactObject","__spreadValues","length","React","ReactAntResourceForm","index_rc_default","main_default","ReactAntResourceForm"]}
|
package/package.json
CHANGED
package/src/index-rc.tsx
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author: aric 1290657123@qq.com
|
|
3
|
+
* @Date: 2025-10-31 13:20:41
|
|
4
|
+
* @LastEditors: aric 1290657123@qq.com
|
|
5
|
+
* @LastEditTime: 2025-10-31 13:24:38
|
|
6
|
+
*/
|
|
7
|
+
import React, { FC } from 'react';
|
|
8
|
+
import { useParams, useSearchParams } from 'react-router-dom';
|
|
9
|
+
import fromEntries from 'fromentries';
|
|
10
|
+
import nx from '@jswork/next';
|
|
11
|
+
import ReactAntResourceForm, { ReactAntResourceFormProps } from '.';
|
|
12
|
+
|
|
13
|
+
const retainKeys = (obj: Record<string, any>, keys: string[]) => {
|
|
14
|
+
nx.forIn(obj, (key) => {
|
|
15
|
+
if (!keys.includes(key)) {
|
|
16
|
+
delete obj[key];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return obj;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
24
|
+
allowFields?: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {
|
|
28
|
+
const { params: overrideParams, allowFields, ...rest } = props;
|
|
29
|
+
const params = useParams();
|
|
30
|
+
const [searchParams] = useSearchParams();
|
|
31
|
+
const _searchParams = fromEntries(searchParams as any);
|
|
32
|
+
const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });
|
|
33
|
+
if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);
|
|
34
|
+
return <ReactAntResourceForm params={_params} {...rest} />;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default ReactAntResourceFormFc;
|
package/src/index.tsx
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
// import noop from '@jswork/noop';
|
|
2
2
|
import cx from 'classnames';
|
|
3
|
-
import React, { Component
|
|
4
|
-
import
|
|
5
|
-
import { Button,
|
|
3
|
+
import React, { Component } from 'react';
|
|
4
|
+
import { ButtonProps, CardProps, FormInstance } from 'antd';
|
|
5
|
+
import { Button, Card, message, Space, Spin } from 'antd';
|
|
6
6
|
import ReactAntdFormSchema, { ReactAntdFormSchemaProps } from '@jswork/react-ant-form-schema';
|
|
7
7
|
import { ArrowLeftOutlined, DiffOutlined, SaveOutlined } from '@ant-design/icons';
|
|
8
|
+
import deepEqual from 'fast-deep-equal';
|
|
9
|
+
import {
|
|
10
|
+
InitGuardArgs,
|
|
11
|
+
MsgType,
|
|
12
|
+
MutateArgs,
|
|
13
|
+
StageData,
|
|
14
|
+
StagePayload,
|
|
15
|
+
SubmitGuardArgs,
|
|
16
|
+
} from './types';
|
|
8
17
|
import { API_FORM_LOCALES } from './locales';
|
|
9
18
|
import nx from '@jswork/next';
|
|
10
19
|
import '@jswork/next-compact-object';
|
|
11
|
-
import { useParams, useSearchParams } from 'react-router-dom';
|
|
12
|
-
import deepEqual from 'fast-deep-equal';
|
|
13
|
-
import fromEntries from 'fromentries';
|
|
14
20
|
|
|
15
21
|
declare global {
|
|
16
22
|
interface NxStatic {
|
|
@@ -19,38 +25,7 @@ declare global {
|
|
|
19
25
|
}
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
stage: 'show' | 'create' | 'update';
|
|
24
|
-
payload: any;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type StageData = {
|
|
28
|
-
stage: 'show' | 'create' | 'update';
|
|
29
|
-
data: any;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
type MutateArgs = {
|
|
33
|
-
name?: string;
|
|
34
|
-
params?: Record<string, any>;
|
|
35
|
-
payload: any;
|
|
36
|
-
isEdit: boolean;
|
|
37
|
-
values: any;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
type InitGuardArgs = {
|
|
41
|
-
name?: string;
|
|
42
|
-
params?: Record<string, any>;
|
|
43
|
-
payload: any;
|
|
44
|
-
isEdit: boolean;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type SubmitGuardArgs = {
|
|
48
|
-
name?: string;
|
|
49
|
-
params?: Record<string, any>;
|
|
50
|
-
payload: any;
|
|
51
|
-
isEdit: boolean;
|
|
52
|
-
values: any;
|
|
53
|
-
};
|
|
28
|
+
const CLASS_NAME = 'react-ant-resource-form';
|
|
54
29
|
|
|
55
30
|
export type ReactAntResourceFormProps = {
|
|
56
31
|
lang?: string;
|
|
@@ -59,6 +34,7 @@ export type ReactAntResourceFormProps = {
|
|
|
59
34
|
backText?: string;
|
|
60
35
|
params?: Record<string, any>;
|
|
61
36
|
blocker?: boolean;
|
|
37
|
+
mute?: boolean;
|
|
62
38
|
disableHotkeySave?: boolean;
|
|
63
39
|
initGuard?: (args: InitGuardArgs) => Promise<void>;
|
|
64
40
|
submitGuard?: (args: SubmitGuardArgs) => Promise<void>;
|
|
@@ -74,22 +50,11 @@ export type ReactAntResourceFormProps = {
|
|
|
74
50
|
onMutate?: (args: MutateArgs) => void;
|
|
75
51
|
} & ReactAntdFormSchemaProps;
|
|
76
52
|
|
|
77
|
-
type IState = {
|
|
53
|
+
export type IState = {
|
|
78
54
|
loading: boolean;
|
|
79
55
|
touched: boolean;
|
|
80
56
|
};
|
|
81
57
|
|
|
82
|
-
const CLASS_NAME = 'react-ant-resource-form';
|
|
83
|
-
|
|
84
|
-
const retainKeys = (obj: Record<string, any>, keys: string[]) => {
|
|
85
|
-
nx.forIn(obj, (key) => {
|
|
86
|
-
if (!keys.includes(key)) {
|
|
87
|
-
delete obj[key];
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
return obj;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
58
|
/**
|
|
94
59
|
* 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null
|
|
95
60
|
* 这个情况仅在 class component 里才会出现,function component 里不会:
|
|
@@ -101,6 +66,13 @@ const retainKeys = (obj: Record<string, any>, keys: string[]) => {
|
|
|
101
66
|
*
|
|
102
67
|
* initGuard | submitGuard:
|
|
103
68
|
* https://chat.qwen.ai/c/60329863-0e5e-47f9-a075-a65ad30940cc
|
|
69
|
+
*
|
|
70
|
+
* onMutate:
|
|
71
|
+
* 在 create/update 成功后,需要刷新列表,可以用 onMutate 继续后续处理。
|
|
72
|
+
*
|
|
73
|
+
* blocker:
|
|
74
|
+
* 这个解决的问题是,目前 nice-form 里默认是 grid layout,导致部分情况下,卡片内部的 style 表现很不正常。
|
|
75
|
+
* 特别是有非 antd 组件的情况下,比如我自己的 react-ckeditor
|
|
104
76
|
*/
|
|
105
77
|
|
|
106
78
|
class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState> {
|
|
@@ -108,6 +80,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
108
80
|
lang: 'zh-CN',
|
|
109
81
|
disableHotkeySave: false,
|
|
110
82
|
blocker: false,
|
|
83
|
+
mute: false,
|
|
111
84
|
initGuard: () => Promise.resolve(),
|
|
112
85
|
submitGuard: () => Promise.resolve(),
|
|
113
86
|
};
|
|
@@ -202,6 +175,11 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
202
175
|
return API_FORM_LOCALES[lang!][key];
|
|
203
176
|
}
|
|
204
177
|
|
|
178
|
+
private msg(msg: string, type: MsgType = 'success') {
|
|
179
|
+
const { mute } = this.props;
|
|
180
|
+
if (!mute) message[type](msg);
|
|
181
|
+
}
|
|
182
|
+
|
|
205
183
|
private handleBack = () => {
|
|
206
184
|
history.back();
|
|
207
185
|
};
|
|
@@ -224,7 +202,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
224
202
|
|
|
225
203
|
handleFinish = (values: any) => {
|
|
226
204
|
if (!this.canSave) {
|
|
227
|
-
|
|
205
|
+
this.msg(this.t('no_change'), 'info');
|
|
228
206
|
return;
|
|
229
207
|
}
|
|
230
208
|
this.isEdit ? this.onResourceUpdate(values) : this.onResourceCreate(values);
|
|
@@ -251,7 +229,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
251
229
|
submitGuard?.(submitGuardArgs).then(() => {
|
|
252
230
|
nx.$api[`${name}_update`](_payload)
|
|
253
231
|
.then((res: any) => {
|
|
254
|
-
|
|
232
|
+
this.msg(this.t('update_success'));
|
|
255
233
|
this.handleStateResponse({ stage: 'update', data: res });
|
|
256
234
|
onMutate?.(mutateArgs);
|
|
257
235
|
})
|
|
@@ -285,7 +263,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
285
263
|
submitGuard?.(submitGuardArgs).then(() => {
|
|
286
264
|
nx.$api[`${name}_create`](_payload)
|
|
287
265
|
.then((res: any) => {
|
|
288
|
-
|
|
266
|
+
this.msg(this.t('create_success'));
|
|
289
267
|
this.handleStateResponse({ stage: 'create', data: res });
|
|
290
268
|
this.formInstance?.resetFields();
|
|
291
269
|
onMutate?.(mutateArgs);
|
|
@@ -400,6 +378,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
400
378
|
disableHotkeySave,
|
|
401
379
|
blocker,
|
|
402
380
|
onInit,
|
|
381
|
+
onMutate,
|
|
403
382
|
initGuard,
|
|
404
383
|
submitGuard,
|
|
405
384
|
loading,
|
|
@@ -430,19 +409,5 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
430
409
|
}
|
|
431
410
|
}
|
|
432
411
|
|
|
433
|
-
export type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
434
|
-
allowFields?: string[];
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {
|
|
438
|
-
const { params: overrideParams, allowFields, ...rest } = props;
|
|
439
|
-
const params = useParams();
|
|
440
|
-
const [searchParams] = useSearchParams();
|
|
441
|
-
const _searchParams = fromEntries(searchParams as any);
|
|
442
|
-
const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });
|
|
443
|
-
if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);
|
|
444
|
-
return <ReactAntResourceForm params={_params} {...rest} />;
|
|
445
|
-
};
|
|
446
412
|
|
|
447
413
|
export default ReactAntResourceForm;
|
|
448
|
-
export { ReactAntResourceFormFc };
|
package/src/main.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import ReactAntResourceForm
|
|
1
|
+
import ReactAntResourceForm from '.';
|
|
2
|
+
import ReactAntResourceFormFc from './index-rc';
|
|
2
3
|
import type { ReactAntResourceFormProps } from '.';
|
|
4
|
+
import type { ReactAntResourceFormFcProps } from './index-rc';
|
|
3
5
|
|
|
4
6
|
export default ReactAntResourceForm;
|
|
5
7
|
export { ReactAntResourceFormFc };
|
|
6
|
-
export type { ReactAntResourceFormProps };
|
|
8
|
+
export type { ReactAntResourceFormFcProps, ReactAntResourceFormProps };
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type StagePayload = {
|
|
2
|
+
stage: 'show' | 'create' | 'update';
|
|
3
|
+
payload: any;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type StageData = {
|
|
7
|
+
stage: 'show' | 'create' | 'update';
|
|
8
|
+
data: any;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type MutateArgs = {
|
|
12
|
+
name?: string;
|
|
13
|
+
params?: Record<string, any>;
|
|
14
|
+
payload: any;
|
|
15
|
+
isEdit: boolean;
|
|
16
|
+
values: any;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type MsgType = 'info' | 'success' | 'warning' | 'error';
|
|
20
|
+
|
|
21
|
+
export type InitGuardArgs = {
|
|
22
|
+
name?: string;
|
|
23
|
+
params?: Record<string, any>;
|
|
24
|
+
payload: any;
|
|
25
|
+
isEdit: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type SubmitGuardArgs = {
|
|
29
|
+
name?: string;
|
|
30
|
+
params?: Record<string, any>;
|
|
31
|
+
payload: any;
|
|
32
|
+
isEdit: boolean;
|
|
33
|
+
values: any;
|
|
34
|
+
};
|
|
35
|
+
|