@jswork/react-ant-resource-form 1.0.26 → 1.0.29
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 +4 -1
- package/dist/main.d.ts +4 -1
- package/dist/main.esm.js +1 -1
- package/dist/main.esm.js.map +1 -1
- package/package.json +6 -4
- package/src/index.tsx +52 -34
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
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var w=Object.defineProperty;var E=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var k=(a,i,e)=>i in a?w(a,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[i]=e,c=(a,i)=>{for(var e in i||(i={}))I.call(i,e)&&k(a,e,i[e]);if(E)for(var e of E(i))x.call(i,e)&&k(a,e,i[e]);return a};var h=(a,i)=>w(a,"name",{value:i,configurable:!0});var R=(a,i)=>{var e={};for(var t in a)I.call(a,t)&&i.indexOf(t)<0&&(e[t]=a[t]);if(a!=null&&E)for(var t of E(a))i.indexOf(t)<0&&x.call(a,t)&&(e[t]=a[t]);return e};var d=(a,i,e)=>k(a,typeof i!="symbol"?i+"":i,e);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 v={"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 _reactrouterdom = require('react-router-dom');var _fastdeepequal = require('fast-deep-equal'); var _fastdeepequal2 = _interopRequireDefault(_fastdeepequal);var _fromentries = require('fromentries'); var _fromentries2 = _interopRequireDefault(_fromentries);var F="react-ant-resource-form",J=h((a,i)=>(_next2.default.forIn(a,e=>{i.includes(e)||delete a[e]}),a),"retainKeys"),f,N=(f=class extends _react.Component{constructor(e){var t;super(e);d(this,"formRef",_react2.default.createRef());d(this,"_isMounted",!1);d(this,"_initialValues",null);d(this,"handleBack",h(()=>{history.back()},"handleBack"));d(this,"setInitialValues",h(e=>{var t;this._initialValues=e||((t=this.formInstance)==null?void 0:t.getFieldsValue())||{}},"setInitialValues"));d(this,"handleFinish",h(e=>{let{params:t,name:s,submitGuard:n}=this.props,r=`${s}_update`,l=`${s}_create`;if(!this.canSave){_antd.message.info(this.t("no_change"));return}if(this.isEdit){let u=c(c({id:t.id},e),t),m=this.handleStateRequest({stage:"update",payload:u}),g={name:s,payload:m,isEdit:!0,values:e,params:t};n==null||n(g).then(()=>{_next2.default.$api[r](m).then(p=>{_antd.message.success(this.t("update_success")),this.handleStateResponse({stage:"update",data:p})}).finally(()=>{this.setState({loading:!1}),this.setInitialValues(),this.handleValuesChange(null,this._initialValues)})})}else{let u=c(c({},e),t),m=this.handleStateRequest({stage:"create",payload:u}),g={name:s,payload:m,isEdit:!1,values:e,params:t};n==null||n(g).then(()=>{_next2.default.$api[l](m).then(p=>{var S;_antd.message.success(this.t("create_success")),this.handleStateResponse({stage:"create",data:p}),(S=this.formInstance)==null||S.resetFields(),history.back()}).finally(()=>this.setState({loading:!1}))})}},"handleFinish"));d(this,"handleKeydown",h(e=>{var n;let{disableHotkeySave:t}=this.props;(e.ctrlKey||e.metaKey)&&(e.key==="s"||e.key==="S")&&(e.preventDefault(),t||(n=this.formInstance)==null||n.submit())},"handleKeydown"));d(this,"handleValuesChange",h((e,t)=>{this.setState({touched:!_fastdeepequal2.default.call(void 0, this._initialValues,t)})},"handleValuesChange"));this.state={loading:e.loading,touched:!1},this.handleStateRequest=this.handleStateRequest.bind(this),this.handleStateResponse=this.handleStateResponse.bind(this),this.initDetailIfNeeded=this.initDetailIfNeeded.bind(this),(t=e.onInit)==null||t.call(e,this)}get isEdit(){let{params:e}=this.props;return!!(e!=null&&e.id)}get canSave(){let{touched:e,loading:t}=this.state;return this.isEdit?e&&!t:!t}get titleView(){let{title:e}=this.props,t=e||(this.isEdit?this.t("update_title"):this.t("create_title"));return _react2.default.createElement(_antd.Space,null,t,_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:e,backText:t,backProps:s}=this.props;return e||_react2.default.createElement(_antd.Button,c({size:"small",icon:_react2.default.createElement(_icons.ArrowLeftOutlined,null),onClick:this.handleBack},s),t||this.t("back"))}get childrenView(){let{okText:e,backText:t,okProps:s,backProps:n,children:r}=this.props,l=e||(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),l||this.t("submit")),_react2.default.createElement(_antd.Button,c({icon:_react2.default.createElement(_icons.ArrowLeftOutlined,null),onClick:this.handleBack},n),t||this.t("back")))}get formInstance(){var e;return(e=this.formRef)==null?void 0:e.current}t(e){let{lang:t}=this.props;return v[t][e]}handleStateRequest(e){var t,s;return this.setState({loading:!0}),((s=(t=this.props).transformRequest)==null?void 0:s.call(t,e))||e.payload}handleStateResponse(e){var s,n,r,l;let{name:t}=this.props;return this.setState({loading:!1}),(n=(s=_next2.default.$event)==null?void 0:s.emit)==null||n.call(s,`${t}:refetch`),((l=(r=this.props).transformResponse)==null?void 0:l.call(r,e))||e.data}componentDidMount(){this._isMounted=!0,window.addEventListener("keydown",this.handleKeydown),this.initDetailIfNeeded()}componentDidUpdate(e){var n,r;let t=(n=e.params)==null?void 0:n.id,s=(r=this.props.params)==null?void 0:r.id;t!==s&&this.initDetailIfNeeded(),e.loading!==this.props.loading&&this.setState({loading:this.props.loading})}componentWillUnmount(){window.removeEventListener("keydown",this.handleKeydown),this._isMounted=!1}initDetailIfNeeded(){let{params:e,name:t,initGuard:s}=this.props,n=`${t}_show`;if(this.isEdit){let r={id:e.id},l=this.handleStateRequest({stage:"show",payload:r}),u={name:t,payload:l,isEdit:!0,params:e};s==null||s(u).then(()=>{_next2.default.$api[n](l).then(m=>{var p,S;if(!this._isMounted)return;let g=this.handleStateResponse({stage:"show",data:m});(S=(p=this.formInstance)==null?void 0:p.setFieldsValue)==null||S.call(p,g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues()})})}else{let r={name:t,payload:null,isEdit:!1,params:e};s==null||s(r).then(()=>{this.setInitialValues(),this.setState({loading:!1})})}}render(){let V=this.props,{className:e,name:t,meta:s,children:n,lang:r,title:l,extra:u,size:m,okText:g,backText:p,okProps:S,backProps:X,classNames:q,params:Y,transformRequest:Z,transformResponse:j,disableHotkeySave:ee,blocker:D,onInit:te,initGuard:se,submitGuard:ae,loading:ie}=V,L=R(V,["className","name","meta","children","lang","title","extra","size","okText","backText","okProps","backProps","classNames","params","transformRequest","transformResponse","disableHotkeySave","blocker","onInit","initGuard","submitGuard","loading"]);return _react2.default.createElement(_antd.Card,{title:this.titleView,extra:this.extraView,size:m,classNames:q,"data-component":F,"data-blocker":D,className:_classnames2.default.call(void 0, F,e)},_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},L),this.childrenView)))}},h(f,"ReactAntResourceForm"),d(f,"defaultProps",{lang:"zh-CN",disableHotkeySave:!1,blocker:!1,initGuard:h(()=>Promise.resolve(),"initGuard"),submitGuard:h(()=>Promise.resolve(),"submitGuard")}),f),Q= exports.ReactAntResourceFormFc =h(a=>{let u=a,{params:i,allowFields:e}=u,t=R(u,["params","allowFields"]),s=_reactrouterdom.useParams.call(void 0, ),[n]=_reactrouterdom.useSearchParams.call(void 0, ),r=_fromentries2.default.call(void 0, n),l=_next2.default.compactObject(c(c(c({},r),s),i));return e!=null&&e.length&&e.length>0&&J(l,e),_react2.default.createElement(N,c({params:l},t))},"ReactAntResourceFormFc"),P=N;var Re=P;exports.ReactAntResourceFormFc = Q; exports.default = Re;
|
|
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","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","__name","history","setInitialValues","values","formInstance","getFieldsValue","handleFinish","params","name","submitGuard","resourceEdit"],"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 { Button, ButtonProps, Card, CardProps, Space, message, Spin } from 'antd';\nimport type { FormInstance } 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 { useParams } from 'react-router-dom';\nimport deepEqual from 'fast-deep-equal';\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 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} & ReactAntdFormSchemaProps;\n\ntype IState = {\n loading: boolean;\n touched: boolean;\n};\n\nconst CLASS_NAME = 'react-ant-resource-form';\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 const { params, name, submitGuard } = this.props;\n const resourceEdit = `${name}_update`;\n const resourceCreate = `${name}_create`;\n\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n\n if (this.isEdit) {\n const payload = { id: params!.id, ...values };\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\n submitGuard?.(submitGuardArgs)\n .then(() => {\n nx.$api[resourceEdit](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n } else {\n const payload = { ...values };\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 submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceCreate](_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 history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\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)\n .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\nconst ReactAntResourceFormFc: FC<ReactAntResourceFormProps> = (props) => {\n const params = useParams();\n return <ReactAntResourceForm params={params} {...props} />;\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","retainKeys","__name","obj","keys","nx","forIn","key","includes","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","history","setInitialValues","values","formInstance","getFieldsValue","handleFinish","params","name","submitGuard","resourceEdit"],"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 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} & 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 const { params, name, submitGuard } = this.props;\n const resourceEdit = `${name}_update`;\n const resourceCreate = `${name}_create`;\n\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n\n if (this.isEdit) {\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\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceEdit](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n } else {\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 submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceCreate](_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 history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\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"]}
|
package/dist/main.d.mts
CHANGED
|
@@ -99,6 +99,9 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
99
99
|
initDetailIfNeeded(): void;
|
|
100
100
|
render(): React.JSX.Element;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
103
|
+
allowFields?: string[];
|
|
104
|
+
};
|
|
105
|
+
declare const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps>;
|
|
103
106
|
|
|
104
107
|
export { ReactAntResourceFormFc, type ReactAntResourceFormProps, ReactAntResourceForm as default };
|
package/dist/main.d.ts
CHANGED
|
@@ -99,7 +99,10 @@ declare class ReactAntResourceForm extends Component<ReactAntResourceFormProps,
|
|
|
99
99
|
initDetailIfNeeded(): void;
|
|
100
100
|
render(): React.JSX.Element;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
103
|
+
allowFields?: string[];
|
|
104
|
+
};
|
|
105
|
+
declare const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps>;
|
|
103
106
|
|
|
104
107
|
// @ts-ignore
|
|
105
108
|
export = ReactAntResourceForm;
|
package/dist/main.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var w=Object.defineProperty;var
|
|
1
|
+
var w=Object.defineProperty;var E=Object.getOwnPropertySymbols;var I=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var k=(a,i,e)=>i in a?w(a,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[i]=e,c=(a,i)=>{for(var e in i||(i={}))I.call(i,e)&&k(a,e,i[e]);if(E)for(var e of E(i))x.call(i,e)&&k(a,e,i[e]);return a};var h=(a,i)=>w(a,"name",{value:i,configurable:!0});var R=(a,i)=>{var e={};for(var t in a)I.call(a,t)&&i.indexOf(t)<0&&(e[t]=a[t]);if(a!=null&&E)for(var t of E(a))i.indexOf(t)<0&&x.call(a,t)&&(e[t]=a[t]);return e};var d=(a,i,e)=>k(a,typeof i!="symbol"?i+"":i,e);import M from"classnames";import o,{Component as O}from"react";import{Button as y,Card as $,message as b,Space as C,Spin as T}from"antd";import B from"@jswork/react-ant-form-schema";import{ArrowLeftOutlined as A,DiffOutlined as K,SaveOutlined as z}from"@ant-design/icons";var v={"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 _ from"@jswork/next";import"@jswork/next-compact-object";import{useParams as U,useSearchParams as H}from"react-router-dom";import G from"fast-deep-equal";import W from"fromentries";var F="react-ant-resource-form",J=h((a,i)=>(_.forIn(a,e=>{i.includes(e)||delete a[e]}),a),"retainKeys"),f,N=(f=class extends O{constructor(e){var t;super(e);d(this,"formRef",o.createRef());d(this,"_isMounted",!1);d(this,"_initialValues",null);d(this,"handleBack",h(()=>{history.back()},"handleBack"));d(this,"setInitialValues",h(e=>{var t;this._initialValues=e||((t=this.formInstance)==null?void 0:t.getFieldsValue())||{}},"setInitialValues"));d(this,"handleFinish",h(e=>{let{params:t,name:s,submitGuard:n}=this.props,r=`${s}_update`,l=`${s}_create`;if(!this.canSave){b.info(this.t("no_change"));return}if(this.isEdit){let u=c(c({id:t.id},e),t),m=this.handleStateRequest({stage:"update",payload:u}),g={name:s,payload:m,isEdit:!0,values:e,params:t};n==null||n(g).then(()=>{_.$api[r](m).then(p=>{b.success(this.t("update_success")),this.handleStateResponse({stage:"update",data:p})}).finally(()=>{this.setState({loading:!1}),this.setInitialValues(),this.handleValuesChange(null,this._initialValues)})})}else{let u=c(c({},e),t),m=this.handleStateRequest({stage:"create",payload:u}),g={name:s,payload:m,isEdit:!1,values:e,params:t};n==null||n(g).then(()=>{_.$api[l](m).then(p=>{var S;b.success(this.t("create_success")),this.handleStateResponse({stage:"create",data:p}),(S=this.formInstance)==null||S.resetFields(),history.back()}).finally(()=>this.setState({loading:!1}))})}},"handleFinish"));d(this,"handleKeydown",h(e=>{var n;let{disableHotkeySave:t}=this.props;(e.ctrlKey||e.metaKey)&&(e.key==="s"||e.key==="S")&&(e.preventDefault(),t||(n=this.formInstance)==null||n.submit())},"handleKeydown"));d(this,"handleValuesChange",h((e,t)=>{this.setState({touched:!G(this._initialValues,t)})},"handleValuesChange"));this.state={loading:e.loading,touched:!1},this.handleStateRequest=this.handleStateRequest.bind(this),this.handleStateResponse=this.handleStateResponse.bind(this),this.initDetailIfNeeded=this.initDetailIfNeeded.bind(this),(t=e.onInit)==null||t.call(e,this)}get isEdit(){let{params:e}=this.props;return!!(e!=null&&e.id)}get canSave(){let{touched:e,loading:t}=this.state;return this.isEdit?e&&!t:!t}get titleView(){let{title:e}=this.props,t=e||(this.isEdit?this.t("update_title"):this.t("create_title"));return o.createElement(C,null,t,o.createElement("span",null,this.touchedView))}get touchedView(){return this.isEdit&&this.state.touched?o.createElement("em",{style:{color:"#f60"}},o.createElement(K,null)):null}get extraView(){let{extra:e,backText:t,backProps:s}=this.props;return e||o.createElement(y,c({size:"small",icon:o.createElement(A,null),onClick:this.handleBack},s),t||this.t("back"))}get childrenView(){let{okText:e,backText:t,okProps:s,backProps:n,children:r}=this.props,l=e||(this.isEdit?this.t("update"):this.t("create"));return r||o.createElement(C,null,o.createElement(y,c({disabled:!this.canSave,htmlType:"submit",type:"primary",icon:o.createElement(z,null)},s),l||this.t("submit")),o.createElement(y,c({icon:o.createElement(A,null),onClick:this.handleBack},n),t||this.t("back")))}get formInstance(){var e;return(e=this.formRef)==null?void 0:e.current}t(e){let{lang:t}=this.props;return v[t][e]}handleStateRequest(e){var t,s;return this.setState({loading:!0}),((s=(t=this.props).transformRequest)==null?void 0:s.call(t,e))||e.payload}handleStateResponse(e){var s,n,r,l;let{name:t}=this.props;return this.setState({loading:!1}),(n=(s=_.$event)==null?void 0:s.emit)==null||n.call(s,`${t}:refetch`),((l=(r=this.props).transformResponse)==null?void 0:l.call(r,e))||e.data}componentDidMount(){this._isMounted=!0,window.addEventListener("keydown",this.handleKeydown),this.initDetailIfNeeded()}componentDidUpdate(e){var n,r;let t=(n=e.params)==null?void 0:n.id,s=(r=this.props.params)==null?void 0:r.id;t!==s&&this.initDetailIfNeeded(),e.loading!==this.props.loading&&this.setState({loading:this.props.loading})}componentWillUnmount(){window.removeEventListener("keydown",this.handleKeydown),this._isMounted=!1}initDetailIfNeeded(){let{params:e,name:t,initGuard:s}=this.props,n=`${t}_show`;if(this.isEdit){let r={id:e.id},l=this.handleStateRequest({stage:"show",payload:r}),u={name:t,payload:l,isEdit:!0,params:e};s==null||s(u).then(()=>{_.$api[n](l).then(m=>{var p,S;if(!this._isMounted)return;let g=this.handleStateResponse({stage:"show",data:m});(S=(p=this.formInstance)==null?void 0:p.setFieldsValue)==null||S.call(p,g)}).finally(()=>{this.setState({loading:!1}),this.setInitialValues()})})}else{let r={name:t,payload:null,isEdit:!1,params:e};s==null||s(r).then(()=>{this.setInitialValues(),this.setState({loading:!1})})}}render(){let V=this.props,{className:e,name:t,meta:s,children:n,lang:r,title:l,extra:u,size:m,okText:g,backText:p,okProps:S,backProps:X,classNames:q,params:Y,transformRequest:Z,transformResponse:j,disableHotkeySave:ee,blocker:D,onInit:te,initGuard:se,submitGuard:ae,loading:ie}=V,L=R(V,["className","name","meta","children","lang","title","extra","size","okText","backText","okProps","backProps","classNames","params","transformRequest","transformResponse","disableHotkeySave","blocker","onInit","initGuard","submitGuard","loading"]);return o.createElement($,{title:this.titleView,extra:this.extraView,size:m,classNames:q,"data-component":F,"data-blocker":D,className:M(F,e)},o.createElement(T,{spinning:this.state.loading},o.createElement(B,c({meta:s,ref:this.formRef,onValuesChange:this.handleValuesChange,onFinish:this.handleFinish},L),this.childrenView)))}},h(f,"ReactAntResourceForm"),d(f,"defaultProps",{lang:"zh-CN",disableHotkeySave:!1,blocker:!1,initGuard:h(()=>Promise.resolve(),"initGuard"),submitGuard:h(()=>Promise.resolve(),"submitGuard")}),f),Q=h(a=>{let u=a,{params:i,allowFields:e}=u,t=R(u,["params","allowFields"]),s=U(),[n]=H(),r=W(n),l=_.compactObject(c(c(c({},r),s),i));return e!=null&&e.length&&e.length>0&&J(l,e),o.createElement(N,c({params:l},t))},"ReactAntResourceFormFc"),P=N;var Re=P;export{Q as ReactAntResourceFormFc,Re 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 { Button, ButtonProps, Card, CardProps, Space, message, Spin } from 'antd';\nimport type { FormInstance } 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 { useParams } from 'react-router-dom';\nimport deepEqual from 'fast-deep-equal';\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 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} & ReactAntdFormSchemaProps;\n\ntype IState = {\n loading: boolean;\n touched: boolean;\n};\n\nconst CLASS_NAME = 'react-ant-resource-form';\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 const { params, name, submitGuard } = this.props;\n const resourceEdit = `${name}_update`;\n const resourceCreate = `${name}_create`;\n\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n\n if (this.isEdit) {\n const payload = { id: params!.id, ...values };\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\n submitGuard?.(submitGuardArgs)\n .then(() => {\n nx.$api[resourceEdit](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n } else {\n const payload = { ...values };\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 submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceCreate](_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 history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\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)\n .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\nconst ReactAntResourceFormFc: FC<ReactAntResourceFormProps> = (props) => {\n const params = useParams();\n return <ReactAntResourceForm params={params} {...props} />;\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","Space","message","Spin","ReactAntdFormSchema","ArrowLeftOutlined","DiffOutlined","SaveOutlined","API_FORM_LOCALES","create","update","create_title","update_title","create_success","update_success","submit","back","no_change","nx","useParams","deepEqual","CLASS_NAME","_a","ReactAntResourceForm","Component","props","formRef","React","createRef","_isMounted","_initialValues","handleBack","__name","history","back","setInitialValues","values","formInstance","getFieldsValue","handleFinish","params","name","submitGuard","resourceEdit","resourceCreate","canSave","message","info","t","isEdit","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","then","nx","$api","res","success","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","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","useParams","index_default","main_default","ReactAntResourceForm"]}
|
|
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 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} & 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 const { params, name, submitGuard } = this.props;\n const resourceEdit = `${name}_update`;\n const resourceCreate = `${name}_create`;\n\n if (!this.canSave) {\n void message.info(this.t('no_change'));\n return;\n }\n\n if (this.isEdit) {\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\n submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceEdit](_payload)\n .then((res: any) => {\n void message.success(this.t('update_success'));\n this.handleStateResponse({ stage: 'update', data: res });\n })\n .finally(() => {\n this.setState({ loading: false });\n this.setInitialValues();\n this.handleValuesChange(null, this._initialValues);\n });\n });\n } else {\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 submitGuard?.(submitGuardArgs).then(() => {\n nx.$api[resourceCreate](_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 history.back();\n })\n .finally(() => this.setState({ loading: false }));\n });\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","params","name","submitGuard","resourceEdit","resourceCreate","canSave","message","info","t","isEdit","payload","__spreadValues","id","_payload","handleStateRequest","stage","submitGuardArgs","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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jswork/react-ant-resource-form",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.29",
|
|
4
4
|
"main": "dist/main.cjs.js",
|
|
5
5
|
"module": "dist/main.esm.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"release": "release-it"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"
|
|
20
|
+
"@jswork/next-compact-object": "^1.0.6",
|
|
21
|
+
"fast-deep-equal": "^3.1.3",
|
|
22
|
+
"fromentries": "^1.3.2"
|
|
21
23
|
},
|
|
22
24
|
"devDependencies": {
|
|
23
25
|
"@ant-design/icons": "^6.1.0",
|
|
@@ -41,10 +43,10 @@
|
|
|
41
43
|
"@jswork/next": "*",
|
|
42
44
|
"@jswork/react-ant-form-schema": "*",
|
|
43
45
|
"antd": "*",
|
|
44
|
-
"react-router-dom": "*",
|
|
45
46
|
"classnames": "*",
|
|
46
47
|
"react": "*",
|
|
47
|
-
"react-dom": "*"
|
|
48
|
+
"react-dom": "*",
|
|
49
|
+
"react-router-dom": "*"
|
|
48
50
|
},
|
|
49
51
|
"publishConfig": {
|
|
50
52
|
"access": "public",
|
package/src/index.tsx
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
// import noop from '@jswork/noop';
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import React, { Component, FC } from 'react';
|
|
4
|
-
import { Button, ButtonProps, Card, CardProps, Space, message, Spin } from 'antd';
|
|
5
4
|
import type { FormInstance } from 'antd';
|
|
5
|
+
import { Button, ButtonProps, Card, CardProps, 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
8
|
import { API_FORM_LOCALES } from './locales';
|
|
9
9
|
import nx from '@jswork/next';
|
|
10
|
-
import
|
|
10
|
+
import '@jswork/next-compact-object';
|
|
11
|
+
import { useParams, useSearchParams } from 'react-router-dom';
|
|
11
12
|
import deepEqual from 'fast-deep-equal';
|
|
13
|
+
import fromEntries from 'fromentries';
|
|
12
14
|
|
|
13
15
|
declare global {
|
|
14
16
|
interface NxStatic {
|
|
@@ -32,7 +34,7 @@ type InitGuardArgs = {
|
|
|
32
34
|
params?: Record<string, any>;
|
|
33
35
|
payload: any;
|
|
34
36
|
isEdit: boolean;
|
|
35
|
-
}
|
|
37
|
+
};
|
|
36
38
|
|
|
37
39
|
type SubmitGuardArgs = {
|
|
38
40
|
name?: string;
|
|
@@ -40,7 +42,7 @@ type SubmitGuardArgs = {
|
|
|
40
42
|
payload: any;
|
|
41
43
|
isEdit: boolean;
|
|
42
44
|
values: any;
|
|
43
|
-
}
|
|
45
|
+
};
|
|
44
46
|
|
|
45
47
|
export type ReactAntResourceFormProps = {
|
|
46
48
|
lang?: string;
|
|
@@ -70,6 +72,15 @@ type IState = {
|
|
|
70
72
|
|
|
71
73
|
const CLASS_NAME = 'react-ant-resource-form';
|
|
72
74
|
|
|
75
|
+
const retainKeys = (obj: Record<string, any>, keys: string[]) => {
|
|
76
|
+
nx.forIn(obj, (key) => {
|
|
77
|
+
if (!keys.includes(key)) {
|
|
78
|
+
delete obj[key];
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return obj;
|
|
82
|
+
};
|
|
83
|
+
|
|
73
84
|
/**
|
|
74
85
|
* 当前 card loading 不要直接使用,因为这个 loading 会导致 Card 里的 formRef 被设置成 null
|
|
75
86
|
* 这个情况仅在 class component 里才会出现,function component 里不会:
|
|
@@ -213,7 +224,7 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
213
224
|
}
|
|
214
225
|
|
|
215
226
|
if (this.isEdit) {
|
|
216
|
-
const payload = { id: params!.id, ...values };
|
|
227
|
+
const payload = { id: params!.id, ...values, ...params };
|
|
217
228
|
const _payload = this.handleStateRequest({ stage: 'update', payload });
|
|
218
229
|
const submitGuardArgs: SubmitGuardArgs = {
|
|
219
230
|
name,
|
|
@@ -223,21 +234,20 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
223
234
|
params,
|
|
224
235
|
};
|
|
225
236
|
|
|
226
|
-
submitGuard?.(submitGuardArgs)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
});
|
|
237
|
+
submitGuard?.(submitGuardArgs).then(() => {
|
|
238
|
+
nx.$api[resourceEdit](_payload)
|
|
239
|
+
.then((res: any) => {
|
|
240
|
+
void message.success(this.t('update_success'));
|
|
241
|
+
this.handleStateResponse({ stage: 'update', data: res });
|
|
242
|
+
})
|
|
243
|
+
.finally(() => {
|
|
244
|
+
this.setState({ loading: false });
|
|
245
|
+
this.setInitialValues();
|
|
246
|
+
this.handleValuesChange(null, this._initialValues);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
239
249
|
} else {
|
|
240
|
-
const payload = { ...values };
|
|
250
|
+
const payload = { ...values, ...params };
|
|
241
251
|
const _payload = this.handleStateRequest({ stage: 'create', payload });
|
|
242
252
|
const submitGuardArgs: SubmitGuardArgs = {
|
|
243
253
|
name,
|
|
@@ -318,19 +328,18 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
318
328
|
isEdit: true,
|
|
319
329
|
params,
|
|
320
330
|
};
|
|
321
|
-
initGuard?.(initGuardArgs)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
});
|
|
331
|
+
initGuard?.(initGuardArgs).then(() => {
|
|
332
|
+
nx.$api[resourceShow](_payload)
|
|
333
|
+
.then((res: any) => {
|
|
334
|
+
if (!this._isMounted) return; // 👈 关键:防止操作已卸载组件
|
|
335
|
+
const data = this.handleStateResponse({ stage: 'show', data: res });
|
|
336
|
+
this.formInstance?.setFieldsValue?.(data);
|
|
337
|
+
})
|
|
338
|
+
.finally(() => {
|
|
339
|
+
this.setState({ loading: false });
|
|
340
|
+
this.setInitialValues();
|
|
341
|
+
});
|
|
342
|
+
});
|
|
334
343
|
} else {
|
|
335
344
|
const initGuardArgs: InitGuardArgs = {
|
|
336
345
|
name,
|
|
@@ -396,9 +405,18 @@ class ReactAntResourceForm extends Component<ReactAntResourceFormProps, IState>
|
|
|
396
405
|
}
|
|
397
406
|
}
|
|
398
407
|
|
|
399
|
-
|
|
408
|
+
export type ReactAntResourceFormFcProps = ReactAntResourceFormProps & {
|
|
409
|
+
allowFields?: string[];
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const ReactAntResourceFormFc: FC<ReactAntResourceFormFcProps> = (props) => {
|
|
413
|
+
const { params: overrideParams, allowFields, ...rest } = props;
|
|
400
414
|
const params = useParams();
|
|
401
|
-
|
|
415
|
+
const [searchParams] = useSearchParams();
|
|
416
|
+
const _searchParams = fromEntries(searchParams as any);
|
|
417
|
+
const _params = nx.compactObject({ ..._searchParams, ...params, ...overrideParams });
|
|
418
|
+
if (allowFields?.length && allowFields.length > 0) retainKeys(_params, allowFields);
|
|
419
|
+
return <ReactAntResourceForm params={_params} {...rest} />;
|
|
402
420
|
};
|
|
403
421
|
|
|
404
422
|
export default ReactAntResourceForm;
|