@materialui-reactjs/admin 1.0.5 → 2.0.0

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.
Files changed (116) hide show
  1. package/CHANGELOG.md +292 -0
  2. package/LICENSE +21 -0
  3. package/README.md +584 -453
  4. package/dist/Common-1GAoFU4L.js +261 -0
  5. package/dist/Common-BBYXssMH.cjs +11 -0
  6. package/dist/Env-DoS-iQjs.cjs +1 -0
  7. package/dist/Env-SHztUA3s.js +16 -0
  8. package/dist/HeaderUpdate-DIwc8EAA.cjs +1 -0
  9. package/dist/{chunks/HeaderUpdate-CYN7fndV.js → HeaderUpdate-UXncZcAD.js} +8 -4
  10. package/dist/SortableItem-C3KzO8Xh.cjs +1 -0
  11. package/dist/SpinnerLoader-BujLjvC3.cjs +1 -0
  12. package/dist/{chunks/SpinnerLoader-h8RDIarB.js → SpinnerLoader-CyhOQC6d.js} +2 -2
  13. package/dist/UDragFile-BqGt1-gK.js +96 -0
  14. package/dist/UDragFile-oJ05zNLR.cjs +1 -0
  15. package/dist/Validator-BcydBvOg.cjs +1 -0
  16. package/dist/{chunks/Validator-CXYkI7vJ.js → Validator-aKlMgoxl.js} +50 -42
  17. package/dist/assets/css/form.css +1 -1
  18. package/dist/assets/css/index.css +1 -1
  19. package/dist/common-CHDJQ2Ca.cjs +1 -0
  20. package/dist/common-DVWX6AUQ.js +19 -0
  21. package/dist/components/echarts/index.cjs +1 -0
  22. package/dist/components/echarts/index.js +1 -1
  23. package/dist/components/form/AdvancedMultiSelect.d.ts +6 -3
  24. package/dist/components/form/AsxhUImages.d.ts +1 -1
  25. package/dist/components/form/BoxAddRow.d.ts +11 -1
  26. package/dist/components/form/CheckTreeBox.d.ts +12 -3
  27. package/dist/components/form/DateInput.d.ts +2 -1
  28. package/dist/components/form/EfFile.d.ts +2 -1
  29. package/dist/components/form/EfImage.d.ts +1 -1
  30. package/dist/components/form/EfImages.d.ts +1 -1
  31. package/dist/components/form/PImage.d.ts +1 -1
  32. package/dist/components/form/SelectAddRowBox.d.ts +9 -5
  33. package/dist/components/form/UDragFile.d.ts +1 -1
  34. package/dist/components/form/UFile.d.ts +1 -1
  35. package/dist/components/form/UFiles.d.ts +1 -1
  36. package/dist/components/form/UImages.d.ts +1 -1
  37. package/dist/components/form/index.cjs +1 -0
  38. package/dist/components/form/index.js +2 -2
  39. package/dist/components/loader/SpinnerLoader.d.ts +5 -1
  40. package/dist/components/loader/index.cjs +1 -0
  41. package/dist/components/loader/index.js +1 -2
  42. package/dist/components/meta/CardTable.d.ts +7 -3
  43. package/dist/components/meta/CardTable.types.d.ts +51 -0
  44. package/dist/components/meta/CusTooltip.d.ts +1 -1
  45. package/dist/components/meta/Head.d.ts +1 -1
  46. package/dist/components/meta/HeaderUpdate.d.ts +5 -1
  47. package/dist/components/meta/ModalForm.d.ts +41 -11
  48. package/dist/components/meta/Navtabs.d.ts +1 -1
  49. package/dist/components/meta/SearchBox.d.ts +6 -4
  50. package/dist/components/meta/SortableItem.d.ts +1 -1
  51. package/dist/components/meta/index.cjs +1 -0
  52. package/dist/components/meta/index.d.ts +1 -0
  53. package/dist/components/meta/index.js +3 -3
  54. package/dist/components/sidebar/Sidebar.types.d.ts +9 -7
  55. package/dist/components/sidebar/index.cjs +1 -0
  56. package/dist/components/sidebar/index.js +1 -1
  57. package/dist/components/single/Detail.d.ts +8 -3
  58. package/dist/components/single/Fields.d.ts +10 -4
  59. package/dist/components/single/Import.d.ts +8 -3
  60. package/dist/components/single/List.d.ts +18 -3
  61. package/dist/components/single/Update.d.ts +8 -3
  62. package/dist/components/single/UpdateDetail.d.ts +3 -2
  63. package/dist/components/single/UpdateTableDetail.d.ts +3 -3
  64. package/dist/components/single/index.cjs +1 -0
  65. package/dist/components/single/index.js +1 -1
  66. package/dist/components/top-navbar/index.cjs +1 -0
  67. package/dist/components/top-navbar/index.js +78 -2
  68. package/dist/echarts-Dla22xas.cjs +1 -0
  69. package/dist/{chunks/form-DirVyglJ.js → form-BNAbGCXe.js} +6860 -6794
  70. package/dist/form-DUL_O4IY.cjs +65 -0
  71. package/dist/hook/common.d.ts +65 -0
  72. package/dist/hook/detail.cjs +1 -0
  73. package/dist/hook/detail.d.ts +9 -15
  74. package/dist/hook/detail.js +1 -11
  75. package/dist/hook/fields.cjs +1 -0
  76. package/dist/hook/fields.d.ts +6 -14
  77. package/dist/hook/fields.js +1 -11
  78. package/dist/hook/import.d.ts +6 -11
  79. package/dist/hook/index.cjs +1 -0
  80. package/dist/hook/index.d.ts +28 -20
  81. package/dist/hook/index.js +13 -10
  82. package/dist/hook/update.cjs +1 -0
  83. package/dist/hook/update.d.ts +9 -17
  84. package/dist/hook/update.js +2 -2
  85. package/dist/index.cjs +1 -0
  86. package/dist/index.d.ts +16 -0
  87. package/dist/index.js +14 -11
  88. package/dist/meta-CXHXSPbq.cjs +1 -0
  89. package/dist/{chunks/meta-BkJxF49g.js → meta-Dhll5zt9.js} +45 -39
  90. package/dist/rolldown-runtime-BocRIvOZ.cjs +1 -0
  91. package/dist/{chunks/sidebar-Dj4Xr9du.js → sidebar-CVORMKBY.js} +9 -12
  92. package/dist/sidebar-G5Ody16K.cjs +1 -0
  93. package/dist/{chunks/single-DfnwtW2f.js → single-CqD5cgNi.js} +353 -259
  94. package/dist/single-CsUaxEjQ.cjs +1 -0
  95. package/dist/style.cjs +0 -0
  96. package/dist/style.d.ts +0 -0
  97. package/dist/style.js +0 -0
  98. package/dist/types/Menu.d.ts +25 -0
  99. package/dist/utils/Common.d.ts +128 -16
  100. package/dist/utils/CusRoute.d.ts +21 -1
  101. package/dist/utils/Env.d.ts +23 -2
  102. package/dist/utils/Group.d.ts +12 -1
  103. package/dist/utils/Validator.d.ts +34 -12
  104. package/dist/utils/index.cjs +11 -0
  105. package/dist/utils/index.d.ts +2 -1
  106. package/dist/utils/index.js +188 -151
  107. package/package.json +190 -163
  108. package/dist/chunks/Common-C_ZhT4L6.js +0 -217
  109. package/dist/chunks/Env-DRXhvUcb.js +0 -16
  110. package/dist/chunks/UDragFile-CAiSfTsp.js +0 -92
  111. package/dist/chunks/loader-BUiOnhOH.js +0 -1
  112. package/dist/chunks/top-navbar-FBw88y_o.js +0 -78
  113. package/scripts/postinstall.cjs +0 -80
  114. /package/dist/{chunks/SortableItem-B4-Zsso3.js → SortableItem-B4-Zsso3.js} +0 -0
  115. /package/dist/{chunks/echarts-CRmndsxC.js → echarts-CRmndsxC.js} +0 -0
  116. /package/dist/{components/meta/Pdfviewer.d.ts → hook/import.cjs} +0 -0
@@ -0,0 +1 @@
1
+ const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./Env-DoS-iQjs.cjs"),n=require("./Common-BBYXssMH.cjs"),r=require("./Validator-BcydBvOg.cjs"),i=require("./UDragFile-oJ05zNLR.cjs"),a=require("./SpinnerLoader-BujLjvC3.cjs"),o=require("./HeaderUpdate-DIwc8EAA.cjs"),s=require("./common-CHDJQ2Ca.cjs");let c=require("react");c=e.t(c,1);let l=require("react/jsx-runtime"),u=require("react-router-dom"),d=require("react-helmet-async");var f=(e,t,n,r,i,a)=>{if(!a)return!1;if(a===1)return!0;if(!Array.isArray(e))return!1;for(let o of e)if(o){if(o.module===t&&o.controller===n&&o.action===r&&Number(o.code)===Number(i))return o.status!==0&&!!o.isPer;if(Array.isArray(o.subs)&&o.subs.length>0&&f(o.subs,t,n,r,i,a))return!0}return!1},p=class extends c.default.Component{effectRan=!1;module=`admins`;controller=``;state={data:{filter:{}},formValue:{},item:void 0,isDetail:void 0};title=``;cUri=``;_envOverride={};_cLinkOverride;get API_URL(){return this._envOverride.API_URL??t.t().API_URL??``}set API_URL(e){this._envOverride.API_URL=e}get ADMIN_URI(){return this._envOverride.ADMIN_URI??t.t().ADMIN_URI??``}set ADMIN_URI(e){this._envOverride.ADMIN_URI=e}get cLink(){return this._cLinkOverride??this.ADMIN_URI+this.cUri}set cLink(e){this._cLinkOverride=e}getDataUrl=``;ctype=`application/json`;fluid=!1;isBackUri=!0;debug=!1;renderForm=()=>(0,l.jsx)(l.Fragment,{});syncPermissionsAndState=async()=>{let{menuData:e,user:t}=this.props,r={isDetail:f(e,this.module,this.controller,`detail`,0,t.groupId)};this.setState(r,async()=>{let e=n.l();if(e&&r.isDetail){let t=await n.n(this.getDataUrl+`/`+e,{},`GET`,`application/json`,!1),r=t?t.data:void 0;this.setState({item:r||!1,formValue:r?JSON.parse(JSON.stringify(r)):{}},async()=>{await this.componentDidMountAfter()})}})};async initDidMount(){try{if(this.effectRan)return;this.effectRan=!0,this.props.user?.groupId&&await this.syncPermissionsAndState()}catch(e){e.message==`invalid_404`&&this.props.navigate(this.cUri),n.y(e.message)}}componentDidMount(){this.initDidMount()}componentDidMountAfter=async()=>{};renderHeaderDetail(){return(0,l.jsx)(o.r,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri})}handleChange=async e=>{e.preventDefault();let t=s.n(e);this.debug&&console.log(`handleChange:`,e.target.name,e.target.value),this.setState(e=>({formValue:{...e.formValue,...t}}))};render(){let{isDetail:e,item:t}=this.state;return e?t===!1?(0,l.jsx)(o.i,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | Chi tiết`}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsx)(`title`,{children:this.title})}),(0,l.jsxs)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:[this.renderHeaderDetail(),(0,l.jsx)(`div`,{className:`position-relative`,children:(0,l.jsx)(a.t,{loading:!t,style:{minHeight:200,marginTop:20},children:this.renderForm()})})]})]}):(0,l.jsx)(o.a,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | Chi tiết`,fluid:this.fluid})}};function m(e){if(!e)return;let t=e.id;if(t==null||t===``)return;let n=Number(t);return Number.isNaN(n)?void 0:n}var h=class extends c.default.Component{effectRan=!1;module=`admins`;controller=``;table=``;state={formValue:{},item:void 0,isField:!1,isDetail:!1};title=``;cUri=``;_envOverride={};_cLinkOverride;get API_URL(){return this._envOverride.API_URL??t.t().API_URL??``}set API_URL(e){this._envOverride.API_URL=e}get ADMIN_URI(){return this._envOverride.ADMIN_URI??t.t().ADMIN_URI??``}set ADMIN_URI(e){this._envOverride.ADMIN_URI=e}get cLink(){return this._cLinkOverride??this.ADMIN_URI+this.cUri}set cLink(e){this._cLinkOverride=e}getDataUrl=``;editUrl=``;createUrl=``;ctype=`application/json`;fluid=!1;isBackUri=!1;debug=!1;renderForm=()=>(0,l.jsx)(l.Fragment,{});renderAfterForm=()=>(0,l.jsx)(l.Fragment,{});handleChange=async e=>{e.preventDefault();let t=s.n(e);this.debug&&console.log(`handleChange:`,e.target.name,e.target.value),this.setState(e=>({formValue:{...e.formValue,...t}}))};syncPermissionsAndState=async()=>{let{menuData:e,user:t}=this.props,i={isDetail:f(e,this.module,this.controller,`detail`,0,t.groupId)};this.setState(i,async()=>{try{let e=await n.n(this.getDataUrl,{table:this.table},`GET`,`application/json`,!1),t=e?e.data:void 0;this.setState({item:t||!1,formValue:t?{...t}:{}}),new r.t(`#fieldUpdate`).run()}catch(e){e.message==`invalid_404`&&this.props.navigate(this.cUri),n.y(e.message)}})};async initDidMount(){try{if(this.effectRan)return;this.effectRan=!0,this.props.user?.groupId&&(await this.syncPermissionsAndState(),await this.componentDidMountAfter())}catch(e){e.message==`invalid_404`&&this.props.navigate(this.cUri),n.y(e.message)}}componentDidMount(){this.initDidMount()}componentDidMountAfter=async()=>{};handleSubmit=async e=>{e.preventDefault();let{formValue:t}=this.state,i=new r.t(`#fieldUpdate`);if(!i.hasErrors()&&!i.isIncomplete()){n.x(`#fieldUpdate`,!0);try{t.table||=this.table;let e=await n.n(this.editUrl,t,`POST`,this.ctype);if(n.b(`Cập nhật thành công`,`top-end`,!0),e.data.id){if(this.isBackUri)return this.props.navigate(this.cUri);this.props.navigate(this.cUri+`/fields`),this.setState({item:{...e.data},formValue:{...e.data}},async()=>{await this.afterSubmit(e.data)})}}catch(e){n.y(e.message)}finally{n.x(`#fieldUpdate`,!1)}}};afterSubmit=async e=>{};renderHeaderUpdate(){return(0,l.jsx)(o.t,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri,itemId:m(this.state.item)})}render(){let{isDetail:e,item:t}=this.state;return e===!1?(0,l.jsx)(o.a,{cUriTitle:this.title,cUri:this.cUri,title:this.title,fluid:this.fluid}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsxs)(`title`,{children:[this.title,` | Tùy chỉnh dữ liệu`]})}),(0,l.jsx)(`div`,{className:`position-relative mb-3 ${this.fluid?`container-fluid`:`container`}`,children:(0,l.jsx)(u.Form,{id:`fieldUpdate`,className:`position-relative`,method:`post`,encType:`multipart/form-data`,"data-toggle":`validator`,role:`form`,onSubmit:this.handleSubmit,children:(0,l.jsxs)(a.t,{loading:!t,style:{minHeight:200,marginTop:20},children:[this.renderHeaderUpdate(),this.renderForm()]})})}),this.renderAfterForm()]})}},g=class extends c.default.Component{module=`admins`;controller=``;state={formValue:{},error:{},isCre:!1,isEdit:!1};title=``;cUri=``;_envOverride={};_cLinkOverride;get API_URL(){return this._envOverride.API_URL??t.t().API_URL??``}set API_URL(e){this._envOverride.API_URL=e}get ADMIN_URI(){return this._envOverride.ADMIN_URI??t.t().ADMIN_URI??``}set ADMIN_URI(e){this._envOverride.ADMIN_URI=e}get cLink(){return this._cLinkOverride??this.ADMIN_URI+this.cUri}set cLink(e){this._cLinkOverride=e}importUrl=``;importFile=`assetorigin.xlsx`;ctype=`multipart/form-data`;fluid=!1;handleChange=async e=>{e.preventDefault();let{name:t,type:n,value:r}=e.target;if(n===`file`){let n=e.target.files;this.setState(e=>({formValue:{...e.formValue,[t]:n?n[0]:null}}))}else this.setState(e=>({formValue:{...e.formValue,[t]:r}}))};syncPermissionsAndState=()=>{let{menuData:e,user:t}=this.props,n={isCre:f(e,this.module,this.controller,`update`,0,t.groupId),isEdit:f(e,this.module,this.controller,`update`,1,t.groupId)};this.setState(n,async()=>{new r.t(`#itemImport`).run()})};async initDidMount(){try{this.props.user?.groupId&&(this.syncPermissionsAndState(),this.componentDidMountAfter())}catch(e){e.message==`invalid_404`&&this.props.navigate(this.cUri),n.y(e.message)}}componentDidMount(){this.initDidMount()}componentDidMountAfter=async()=>{};handleSubmit=async e=>{e.preventDefault();let{formValue:t}=this.state,i=new r.t(`#itemImport`);if(!i.hasErrors()&&!i.isIncomplete()){n.x(`#itemImport`,!0);try{let e=await n.n(this.importUrl,t,`POST`,this.ctype);e.data?.error?.length?e.data.error&&this.setState({error:Object.fromEntries(e.data.error.map((e,t)=>[t,e]))}):(this.props.navigate(this.cUri),n.b(`Import thành công`,`top-end`,!0))}catch(e){n.y(e.message)}finally{n.x(`#itemImport`,!1)}}};renderForm=()=>(0,l.jsx)(l.Fragment,{children:(0,l.jsx)(i.t,{onChange:this.handleChange,label:`Import excel`,name:`importfile`,ext:`.xlsx,.xls`})});render(){let{isCre:e,isEdit:t}=this.state;return e===!1&&t===!1?(0,l.jsx)(o.a,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | Import`,fluid:this.fluid}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsxs)(`title`,{children:[this.title,` | `,`Import`]})}),(0,l.jsx)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:(0,l.jsxs)(u.Form,{id:`itemImport`,className:`position-relative`,action:this.importUrl,method:`post`,encType:`multipart/form-data`,"data-toggle":`validator`,role:`form`,onSubmit:this.handleSubmit,children:[(0,l.jsxs)(`div`,{className:`navbar navbar-main navbar-expand-lg px-0 shadow-none border-radius-xl py-3`,children:[(0,l.jsx)(`nav`,{"aria-label":`breadcrumb`,children:(0,l.jsxs)(`ol`,{className:`breadcrumb bg-transparent m-0 p-0`,children:[(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:this.ADMIN_URI||`/`,children:(0,l.jsx)(`i`,{className:`fal fa-home`})})}),(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:this.cUri,children:this.title})}),(0,l.jsx)(`li`,{className:`breadcrumb-item text-white active`,"aria-current":`page`,children:`Import`})]})}),(0,l.jsxs)(`div`,{className:`ms-auto`,children:[(0,l.jsx)(u.Link,{target:`_blank`,to:this.API_URL+`/importfile/`+this.importFile,className:`btn btn-sm btn-icon btn-info me-2`,title:`Tải xuống biểu mẫu`,children:(0,l.jsx)(`i`,{className:`material-icons text-white position-relative text-lg`,children:`file_download`})}),(0,l.jsx)(u.Link,{to:this.cUri,className:`btn btn-sm btn-icon btn-secondary`,title:`Trở lại`,children:(0,l.jsx)(`i`,{className:`material-icons text-white position-relative text-lg`,children:`reply`})})]})]}),(0,l.jsx)(`div`,{className:`card`,children:(0,l.jsx)(`div`,{className:`card-body pb-0`,children:(0,l.jsx)(`div`,{className:`row justify-content-center`,children:(0,l.jsxs)(`div`,{className:`col-md-8 pt-5 pb-4`,children:[(0,l.jsx)(`div`,{dangerouslySetInnerHTML:{__html:n._(this.state.error)}}),this.renderForm(),(0,l.jsx)(`div`,{className:`w-100 d-flex`,children:(0,l.jsx)(`button`,{title:`Import`,type:`submit`,className:`btn btn-success mb-4 mx-auto`,children:`Import`})})]})})})})]})})]})}},_=class extends c.default.Component{effectRan=!1;fluid=!1;module=`admins`;controller=``;table=``;hasField=!1;state={loading:!0,data:{items:[],page:1,filter:{},length:10,pageTotal:0,recordTotal:0},isDel:void 0,isCre:void 0,isEdit:void 0,isDelOne:void 0,isDetail:void 0,isIndex:void 0,isImport:void 0,isExport:void 0,isCopy:void 0,selectedIds:[],ftfield:[],tbfield:[]};activeMethod=[`ind`,`det`,`cre`,`edit`,`delone`,`del`];cUri=``;_envOverride={};_cLinkOverride;get API_URL(){return this._envOverride.API_URL??t.t().API_URL??``}set API_URL(e){this._envOverride.API_URL=e}get ADMIN_URI(){return this._envOverride.ADMIN_URI??t.t().ADMIN_URI??``}set ADMIN_URI(e){this._envOverride.ADMIN_URI=e}get cLink(){return this._cLinkOverride??this.ADMIN_URI+this.cUri}set cLink(e){this._cLinkOverride=e}getDataUrl=``;deleteUrl=``;copyUrl=``;exportUrl=``;title=``;handleChange=async e=>{try{e.preventDefault();let{name:t}=e.target,r=await o.l(e,this.state.data.filter||{});if(t===`pageLen`){await this.setFilter(r);let e=r?n.a(r):``;this.props.navigate(`${this.cUri}?${e}`,{replace:!0}),await this.fetchData()}else this.setState(e=>({data:{...e.data,filter:r}}))}catch(e){console.log(e)}};handleSearchForm=async e=>{try{e.preventDefault();let t=await o.c(this.state.data.filter||{},this.cUri,this.props.navigate);await this.setFilter(t),await this.fetchData()}catch(e){console.log(e)}};handleClickPage=async e=>{try{e.preventDefault();let t=await o.s(e,this.state.data.filter||{},this.cUri,this.props.navigate);await this.setFilter(t),await this.fetchData()}catch(e){n.y(e.message)}};handleDeleteOne=async e=>{n.v().then(async()=>{try{await n.n(`${this.deleteUrl}/${e}`,{},`DELETE`),n.b(`Xoá thành công!`,`top-end`,!0),await this.fetchData()}catch(e){n.y(e.message)}})};handleDelete=async()=>{this.state.selectedIds.length?n.v().then(async()=>{try{await n.n(this.deleteUrl,{selected:this.state.selectedIds},`POST`),n.b(`Xoá thành công!`,`top-end`,!0),await this.fetchData()}catch(e){n.y(e.message)}}):n.y(`Vui lòng chọn thông tin`)};handleCopy=async()=>{this.state.selectedIds.length?n.v().then(async()=>{try{await n.n(this.copyUrl,{selected:this.state.selectedIds},`POST`),n.b(`Sao chép thành công!`,`top-end`,!0),await this.fetchData()}catch(e){n.y(e.message)}}):n.y(`Vui lòng chọn thông tin`)};handleExport=async()=>{try{let{data:e}=this.state,t=n.a(e.filter||{});this.exportUrl&&(window.location.href=this.exportUrl+`?${t}`)}catch(e){n.y(e.message)}};handleSelectOne=(e,t)=>{this.setState(n=>({selectedIds:t?[...new Set([...n.selectedIds,e])]:n.selectedIds.filter(t=>t!==e)}))};handleSelectAll=(e,t=[])=>{this.setState({selectedIds:e?this.state.data.items.map(e=>e.id).filter(e=>e!==void 0&&!t.includes(e)):[]})};setFilter(e){return new Promise(t=>{this.setState(t=>({data:{...t.data,filter:e}}),t)})}fetchData=async()=>{try{let e=await o.o(this.state.data.filter||{},this.getDataUrl);if(!e||!(`items`in e))return;this.setState({data:{...e,filter:e.filter??this.state.data.filter},selectedIds:[]})}catch(e){console.error(e.message)}};syncGetField=async()=>({userfield:{},tablefield:{}});syncPermissionsAndState=async()=>{let{menuData:e,user:t}=this.props,n={isCre:this.activeMethod.includes(`cre`)?f(e,this.module,this.controller,`update`,0,t.groupId):!1,isEdit:this.activeMethod.includes(`edit`)?f(e,this.module,this.controller,`update`,1,t.groupId):!1,isDel:this.activeMethod.includes(`del`)?f(e,this.module,this.controller,`delete`,0,t.groupId):!1,isDelOne:this.activeMethod.includes(`delone`)?f(e,this.module,this.controller,`delete`,1,t.groupId):!1,isIndex:this.activeMethod.includes(`ind`)?f(e,this.module,this.controller,`index`,0,t.groupId):!1,isDetail:this.activeMethod.includes(`det`)?f(e,this.module,this.controller,`detail`,0,t.groupId):!1,isImport:!!this.activeMethod.includes(`imp`),isExport:!!this.activeMethod.includes(`exp`),isCopy:!!this.activeMethod.includes(`cpy`)};this.setState(n,async()=>{if(n.isIndex){if(this.hasField){let{userfield:e,tablefield:t}=await this.syncGetField(),n=e?.data?.ftfield||t?.data?.deft||[],r=e?.data?.tbfield||t?.data?.detb||[];this.setState(e=>({...e,ftfield:n,tbfield:r}))}await this.fetchData(),this.setState({loading:!1}),await this.componentDidMountAfter()}})};async initDidMount(){try{if(this.effectRan)return;this.effectRan=!0;let e=new URLSearchParams(window.location.search),t=Object.fromEntries(e.entries()),n={...this.state.data.filter||{},page:1,...t};await this.setFilter(n),this.props.user?.groupId&&await this.syncPermissionsAndState()}catch(e){n.y(e.message)}}componentDidMount(){this.initDidMount()}componentDidMountAfter=async()=>{};renderHeaderIndex(){return(0,l.jsx)(o.n,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri,isExp:this.state.isExport,isImp:this.state.isImport,isCre:this.state.isCre,isDel:this.state.isDel,isCpy:this.state.isCopy,isField:this.hasField,onExport:this.handleExport,onCopy:this.handleCopy,onDelete:this.handleDelete})}renderTable=()=>(0,l.jsx)(l.Fragment,{});renderSearch=()=>(0,l.jsx)(l.Fragment,{});render(){let{isIndex:e,data:t,loading:n}=this.state;return e===!1?(0,l.jsx)(o.a,{cUriTitle:this.title,cUri:this.cUri,title:this.title,fluid:this.fluid}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsx)(`title`,{children:this.title})}),(0,l.jsx)(a.t,{loading:n,children:e&&(0,l.jsxs)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:[this.renderHeaderIndex(),(0,l.jsx)(`div`,{className:`card position-relative`,children:(0,l.jsx)(`div`,{className:`card-body`,style:{minHeight:`200px`},children:(0,l.jsxs)(`div`,{className:`searchForm`,children:[(0,l.jsx)(`form`,{onSubmit:this.handleSearchForm,children:this.renderSearch()}),t.items.length?(0,l.jsx)(o.u,{data:t,onChange:this.handleChange,onClickPage:this.handleClickPage}):``,(0,l.jsx)(`div`,{className:`table-responsive mt-2`,children:this.renderTable()}),t.items.length?(0,l.jsx)(o.u,{data:t,onChange:this.handleChange,onClickPage:this.handleClickPage}):``]})})})]})})]})}},v=({adminUri:e,cUri:t,title:n,itemId:r,isSave:i=!0,titleAction:a})=>(0,l.jsxs)(`div`,{className:`navbar navbar-main navbar-expand-lg px-0 shadow-none border-radius-xl py-3`,children:[(0,l.jsx)(`nav`,{"aria-label":`breadcrumb`,children:(0,l.jsxs)(`ol`,{className:`breadcrumb bg-transparent m-0 p-0`,children:[(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:e||`/`,children:(0,l.jsx)(`i`,{className:`fal fa-home`})})}),(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:t,children:n})}),(0,l.jsx)(`li`,{className:`breadcrumb-item text-white active`,"aria-current":`page`,children:a??(r?`Chỉnh sửa`:`Thêm mới`)})]})}),(0,l.jsxs)(`div`,{className:`ms-auto`,children:[i&&(0,l.jsx)(o.d,{title:`Lưu lại`,children:(0,l.jsx)(`button`,{type:`submit`,className:`btn btn-sm btn-icon btn-success me-1`,children:(0,l.jsx)(`i`,{className:`material-icons text-white position-relative text-lg`,children:`save`})})}),(0,l.jsx)(o.d,{title:`Trở lại`,children:(0,l.jsx)(u.Link,{to:t,className:`btn btn-sm btn-icon btn-secondary`,children:(0,l.jsx)(`i`,{className:`material-icons text-white position-relative text-lg`,children:`reply`})})})]})]}),y=({title:e=``,cUri:t=``,fluid:n=!1,cUriTitle:r=``})=>(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsx)(`title`,{children:e||`Truy cập không được phép`})}),(0,l.jsxs)(`div`,{className:`${n?`container-fluid`:`container`}`,children:[(0,l.jsx)(`div`,{className:`navbar navbar-main navbar-expand-lg px-0 shadow-none border-radius-xl py-3`,children:(0,l.jsx)(`nav`,{"aria-label":`breadcrumb`,children:(0,l.jsxs)(`ol`,{className:`breadcrumb bg-transparent m-0 p-0`,children:[(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:`/`,children:(0,l.jsx)(`i`,{className:`fal fa-home`})})}),(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:t,children:r})})]})})}),(0,l.jsx)(`div`,{style:{minHeight:`50vh`},className:`d-flex align-items-center`,children:(0,l.jsxs)(`div`,{className:`m-auto text-center`,children:[(0,l.jsx)(`h1`,{className:`display-1 text-bolder text-white`,children:`403`}),(0,l.jsx)(`h2`,{className:`text-white`,children:`Truy cập không được phép`}),(0,l.jsx)(`p`,{className:`lead text-white`,children:`Xin lỗi, bạn không có quyền truy cập vào trang này.`}),(0,l.jsx)(u.Link,{to:`/`,className:`btn btn-outline-white mt-4`,children:`trang chủ`})]})})]})]}),b=({title:e=``,cUri:t=``,fluid:n=!1,cUriTitle:r=``})=>(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsx)(`title`,{children:e||`Không tìm thấy dữ liệu`})}),(0,l.jsxs)(`div`,{className:`${n?`container-fluid`:`container`}`,children:[(0,l.jsx)(`div`,{className:`navbar navbar-main navbar-expand-lg px-0 shadow-none border-radius-xl py-3`,children:(0,l.jsx)(`nav`,{"aria-label":`breadcrumb`,children:(0,l.jsxs)(`ol`,{className:`breadcrumb bg-transparent m-0 p-0`,children:[(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:`/`,children:(0,l.jsx)(`i`,{className:`fal fa-home`})})}),(0,l.jsx)(`li`,{className:`breadcrumb-item`,children:(0,l.jsx)(u.Link,{className:`text-white`,to:t,children:r})})]})})}),(0,l.jsx)(`div`,{style:{minHeight:`50vh`},className:`d-flex align-items-center`,children:(0,l.jsxs)(`div`,{className:`m-auto text-center`,children:[(0,l.jsx)(`h1`,{className:`display-1 text-bolder text-white`,children:`404`}),(0,l.jsx)(`h2`,{className:`text-white`,children:`Không tìm thấy dữ liệu`}),(0,l.jsx)(`p`,{className:`lead text-white`,children:`Xin lỗi, dữ liệu của bạn không được tìm thấy`}),(0,l.jsx)(u.Link,{to:`/`,className:`btn btn-outline-white mt-4`,children:`trang chủ`})]})})]})]}),x=class extends c.default.Component{effectRan=!1;module=`admins`;controller=``;state={formValue:{},error:{},loading:!0,item:void 0,isCre:void 0,isEdit:void 0,isDetail:void 0};title=``;cUri=``;_envOverride={};_cLinkOverride;get API_URL(){return this._envOverride.API_URL??t.t().API_URL??``}set API_URL(e){this._envOverride.API_URL=e}get ADMIN_URI(){return this._envOverride.ADMIN_URI??t.t().ADMIN_URI??``}set ADMIN_URI(e){this._envOverride.ADMIN_URI=e}get cLink(){return this._cLinkOverride??this.ADMIN_URI+this.cUri}set cLink(e){this._cLinkOverride=e}getDataUrl=``;editUrl=``;createUrl=``;ctype=`application/json`;formRef;fluid=!1;isBackUri=!0;debug=!1;constructor(e){super(e),this.formRef=c.default.createRef()}renderForm=()=>(0,l.jsx)(l.Fragment,{});renderAfterForm=()=>(0,l.jsx)(l.Fragment,{});handleChange=e=>{e.preventDefault();let t=r.r(e);this.setState(e=>({formValue:r.n(e.formValue,t)}))};syncPermissionsAndState=async()=>{let{menuData:e,user:t}=this.props,i={isCre:f(e,this.module,this.controller,`update`,0,t.groupId),isEdit:f(e,this.module,this.controller,`update`,1,t.groupId),isDetail:f(e,this.module,this.controller,`detail`,0,t.groupId)};this.setState(i,async()=>{let e=n.l();if(e&&i.isEdit){let t=await n.n(this.getDataUrl+`/`+e,{},`GET`,`application/json`,!1),i=t?t.data:void 0;this.setState({item:i||!1,formValue:i?JSON.parse(JSON.stringify(i)):{}},async()=>{this.setState({loading:!1}),await this.componentDidMountAfter(),this.formRef.current&&new r.t(this.formRef.current).run()})}else{if(this.setState({loading:!1}),await this.componentDidMountAfter(),!this.formRef.current)return;new r.t(this.formRef.current).run()}})};async initDidMount(){try{if(this.effectRan)return;this.effectRan=!0,this.props.user?.groupId&&await this.syncPermissionsAndState()}catch(e){e.message==`invalid_404`&&this.props.navigate(this.cUri),n.y(e.message)}}componentDidMount=()=>{this.initDidMount()};componentDidMountAfter=async()=>{};beforeSubmit=()=>new Promise(e=>{e(!0)});handleSubmit=async e=>{e.preventDefault();let{item:t,formValue:i}=this.state,a=m(t),o=new r.t(this.formRef.current);!o.hasErrors()&&!o.isIncomplete()&&this.formRef.current&&this.beforeSubmit().then(async()=>{this.setState({loading:!0});try{let e=a?this.editUrl+`/`+a:this.createUrl,t=await n.n(e,i,`POST`,this.ctype);if(a?n.b(`Cập nhật thành công`,`top-end`,!0):n.b(`Thêm mới thành công`,`top-end`,!0),t?.data?.id){if(this.isBackUri)return this.props.navigate(this.cUri);this.props.navigate(this.cUri+`/edit/`+Number(t.data.id)),this.setState({item:{...t.data},formValue:{...t.data}},async()=>{await this.afterSubmit(t.data)})}}catch(e){n.y(e.message)}finally{this.setState({loading:!1})}})};afterSubmit=async e=>{};renderHeaderUpdate(){return(0,l.jsx)(v,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri,itemId:m(this.state.item)})}render(){let e=n.l(),{isCre:t,isEdit:r,isDetail:i,item:o}=this.state;return t===!1&&r===!1&&i===!1||t===!1&&e==null||(r===!1||i===!1)&&e?(0,l.jsx)(y,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`),fluid:this.fluid}):e&&o===!1?(0,l.jsx)(b,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`)}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsxs)(`title`,{children:[this.title,` | `,m(o)?`Chỉnh sửa`:`Thêm mới`]})}),(0,l.jsxs)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:[(0,l.jsx)(`div`,{dangerouslySetInnerHTML:{__html:n._(this.state.error)}}),(0,l.jsx)(u.Form,{ref:this.formRef,className:`position-relative`,method:`post`,encType:`multipart/form-data`,"data-toggle":`validator`,role:`form`,onSubmit:this.handleSubmit,children:(0,l.jsxs)(a.t,{loading:!!this.state.loading,style:{minHeight:200,marginTop:20},children:[this.renderHeaderUpdate(),this.renderForm()]})}),this.renderAfterForm()]})]})}},S=class extends x{urlUpdateDetail=``;render(){let e=n.l(),{isCre:t,isEdit:r,isDetail:i,item:o}=this.state;if(t===!1&&r===!1&&i===!1||t===!1&&e==null||(r===!1||i===!1)&&e)return(0,l.jsx)(y,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`),fluid:this.fluid});if(e&&o===!1)return(0,l.jsx)(b,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`)});let s=m(o);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsxs)(`title`,{children:[this.title,` | `,s?`Chỉnh sửa`:`Thêm mới`]})}),(0,l.jsxs)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:[(0,l.jsx)(v,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri,isSave:!1,itemId:s}),(0,l.jsx)(`div`,{dangerouslySetInnerHTML:{__html:n._(this.state.error)}}),(0,l.jsx)(`div`,{className:`position-relative`,children:(0,l.jsx)(a.t,{loading:!!this.state.loading,style:{minHeight:200,marginTop:0},children:this.renderForm()})})]})]})}handleDetailSubmit=async(e,t)=>{try{let r=m(this.state.item);r&&e?.length&&(n.x(t,!0),await n.n(this.urlUpdateDetail,{itemid:r,details:e}),n.x(t,!1),n.b(`Thêm tài sản thành công`,`top-end`,!0),await this.editDetailAfter(r),this.props.navigate(this.cUri+`/edit/`+r))}catch(e){n.y(e.message),n.x(t,!1)}};editDetailAfter=async e=>{}},C=class extends x{urlGetDeTableList=``;urlGetDeTable=``;urlCreDeTable=``;urlEditDeTable=``;urlDelDeTable=``;modalRef;isBackUri=!1;constructor(e){super(e),this.modalRef=(0,c.createRef)()}async fetchDataDetails(){return{}}render(){let e=n.l(),{isCre:t,isEdit:r,isDetail:i,item:a}=this.state;if(t===!1&&r===!1&&i===!1||t===!1&&e==null||(r===!1||i===!1)&&e)return(0,l.jsx)(y,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`),fluid:this.fluid});if(e&&a===!1)return(0,l.jsx)(b,{cUriTitle:this.title,cUri:this.cUri,title:this.title+` | `+(e?`Chỉnh sửa`:`Thêm mới`)});let o=m(a);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(d.Helmet,{children:(0,l.jsxs)(`title`,{children:[this.title,` | `,o?`Chỉnh sửa`:`Thêm mới`]})}),(0,l.jsxs)(`div`,{className:`mb-3 ${this.fluid?`container-fluid`:`container`}`,children:[(0,l.jsx)(v,{adminUri:this.ADMIN_URI,title:this.title,cUri:this.cUri,isSave:!1,itemId:o}),a?this.renderDeTable():null,this.renderForm()]})]})}renderDeTable(){return(0,l.jsx)(l.Fragment,{})}renderModalDeBody=(e,t)=>(0,l.jsx)(l.Fragment,{});handleDetailSubmit=async e=>{e.preventDefault()};editDetailAfter=async e=>{}};Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return C}});
package/dist/style.cjs ADDED
File without changes
File without changes
package/dist/style.js ADDED
File without changes
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Hình dạng tối thiểu của một menu mà lớp phân quyền cần để quyết định.
3
+ *
4
+ * Tách ra khỏi `MenuItem` của Sidebar để tránh phụ thuộc vòng:
5
+ * `utils/Group` và `hook` dùng kiểu này, còn `Sidebar.types` mở rộng nó
6
+ * thêm các trường hiển thị (icon, sortOrder, ...).
7
+ *
8
+ * `MenuItem` gán được cho `MenuPermissionItem` một cách cấu trúc (structural),
9
+ * nên `menuData: MenuItem[]` vẫn truyền được vào đây.
10
+ */
11
+ export interface MenuPermissionItem {
12
+ module: string;
13
+ controller: string;
14
+ action: string;
15
+ /**
16
+ * Mã hành động. Cho phép `string` vì API có thể trả về `"0"` thay vì `0` —
17
+ * `checkPermission` so sánh bằng `Number(...)` nên cả hai đều hợp lệ.
18
+ */
19
+ code: number | string;
20
+ /** `0` = đã ẩn/khóa (không tính quyền), khác `0` = đang hoạt động. */
21
+ status: number;
22
+ /** Người dùng hiện tại có quyền với mục này hay không. */
23
+ isPer: boolean;
24
+ subs?: MenuPermissionItem[];
25
+ }
@@ -1,30 +1,103 @@
1
1
  import { default as Decimal } from 'decimal.js';
2
+ import { CrudItem, FormValue } from '../hook/common';
2
3
  export declare const loadScript: (src: string) => Promise<void>;
3
4
  export declare const loadScripts: (scripts: string[]) => Promise<void>;
4
5
  export declare const spinnerLoader: (box: string | Element, action?: boolean) => void;
5
6
  export declare const buildFormData: (data: Record<string, any>) => FormData;
6
- export declare const callFetchApi: (url: string, data?: any, type?: string, ctype?: string) => Promise<any>;
7
- export declare const callFetchApiToken: (url: string, data?: any, type?: string, ctype?: string, isTry?: boolean) => Promise<any>;
7
+ export declare class ApiError extends Error {
8
+ errorCode: string;
9
+ constructor(message: string, errorCode: string);
10
+ }
11
+ /**
12
+ * Envelope chuẩn của API.
13
+ *
14
+ * @typeParam T kiểu của `data`. Mặc định là `Record<string, unknown>` — chặn
15
+ * ở mức "object có khoá" thay vì `any`, nhưng vẫn cho phép consumer tự chỉ
16
+ * định rõ khi biết trước: `callFetchApiToken<Product[]>("/api/p")`.
17
+ */
18
+ export interface ApiResponse<T = Record<string, unknown>> {
19
+ status: number;
20
+ msg?: string;
21
+ errorCode?: string;
22
+ data: T;
23
+ }
24
+ export declare const callFetchApi: <T = Record<string, unknown>>(url: string, data?: FormValue, type?: string, ctype?: string) => Promise<ApiResponse<T>>;
25
+ /**
26
+ * Gọi API kèm cookie phiên (`credentials: "include"`).
27
+ *
28
+ * `isTry = false` biến mọi lỗi thành `false` thay vì ném — dùng cho các chỗ
29
+ * cần "không có dữ liệu cũng chấp nhận" (ví dụ nạp chi tiết, rỗng -> 404).
30
+ *
31
+ * OVERLOADS: khi `isTry` là `true` (mặc định) hàm luôn ném lỗi, **không bao giờ**
32
+ * trả `false` — nên kiểu trả về là `ApiResponse<T>`. Chỉ khi truyền `isTry: false`
33
+ * mới phải kiểm tra `false` trước khi đọc `.data`.
34
+ */
35
+ export declare function callFetchApiToken<T = Record<string, unknown>>(url: string, data?: FormValue, type?: string, ctype?: string, isTry?: true): Promise<ApiResponse<T>>;
36
+ export declare function callFetchApiToken<T = Record<string, unknown>>(url: string, data: FormValue | undefined, type: string | undefined, ctype: string | undefined, isTry: false): Promise<ApiResponse<T> | false>;
8
37
  export declare const showSweetAlert: (text?: string, confirmText?: string) => Promise<import('sweetalert2').SweetAlertResult<any>>;
9
38
  export declare const showSweetAlertOk: (title: string, pos?: any, toast?: boolean) => void;
10
39
  export declare const showSweetAlertWarning: (title: string) => void;
11
40
  export declare const showSweetAlertError: (title: string) => void;
12
- export declare const getName: (id: number, items: any[], keyName?: string) => any;
13
- export declare const getNames: (ids: number[], items: any, keyName?: string) => string;
41
+ /**
42
+ * Tra nhãn hiển thị của một bản ghi theo `id`.
43
+ *
44
+ * @param keyName tên trường chứa nhãn, mặc định `name`.
45
+ * @returns giá trị tương ứng, hoặc `null` nếu không tìm thấy.
46
+ */
47
+ export declare const getName: (id: number, items: CrudItem[], keyName?: string) => string | null;
48
+ /** Nối nhãn của nhiều `id` thành chuỗi, bỏ qua id không tồn tại. */
49
+ export declare const getNames: (ids: number[], items: CrudItem[], keyName?: string) => string;
14
50
  export declare const getLinkFiles: (files: string[]) => string;
15
- export declare const getActiveStatus: (id: string | boolean | number, color?: boolean) => any;
16
- export declare const getPublishStatus: (id: string | boolean | number, color?: boolean) => any;
17
- export declare const getTrueFlaseStatus: (id: string | boolean | number, color?: boolean) => any;
51
+ /** Một mục trong bảng trạng thái (kích hoạt / xuất bản / có-không). */
52
+ export interface StatusOption {
53
+ id: number;
54
+ name: string;
55
+ color: string;
56
+ }
57
+ /**
58
+ * Dựng nhãn trạng thái từ bảng tra cứu.
59
+ *
60
+ * Trả về chính `table` khi `id === false` — đó là quy ước cũ: consumer dùng để
61
+ * lấy luôn danh sách để dựng dropdown, chứ không phải một giá trị hiển thị.
62
+ */
63
+ export declare const getStatus: (id: string | boolean | number, table: StatusOption[], color?: boolean) => string | StatusOption[];
64
+ export declare const getActiveStatus: (id: string | boolean | number, color?: boolean) => string | StatusOption[];
65
+ export declare const getPublishStatus: (id: string | boolean | number, color?: boolean) => string | StatusOption[];
66
+ export declare const getTrueFlaseStatus: (id: string | boolean | number, color?: boolean) => string | StatusOption[];
18
67
  export declare function parseDate(date: string | Date): Date;
19
68
  export declare function strToDate(input?: string | Date): Date;
20
- export declare const formatDateTime: (date: any) => string;
21
- export declare const formatDate: (date: any) => string;
22
- export declare const formatYear: (date: any) => string;
23
- export declare const formatDateSql: (date: any) => string;
24
- export declare const getParams: (name?: string | null) => string | Record<string, string | null> | null;
69
+ /**
70
+ * Kiểu mà các hàm định dạng ngày chấp nhận.
71
+ *
72
+ * `new Date(x)` chỉ nhận `string | number | Date`; trước đây tham số là `any`
73
+ * nên truyền nhầm kiểu (object, mảng...) chỉ lộ ra khi render ra
74
+ * "Invalid Date" ở production.
75
+ */
76
+ export type DateInput = string | number | Date | null | undefined;
77
+ export declare const formatDateTime: (date: DateInput) => string;
78
+ export declare const formatDate: (date: DateInput) => string;
79
+ export declare const formatYear: (date: DateInput) => string;
80
+ export declare const formatDateSql: (date: DateInput) => string;
81
+ /**
82
+ * Đọc query string hiện tại.
83
+ * @param name không truyền -> trả toàn bộ params dạng object;
84
+ * truyền chuỗi -> trá 1 giá trị;
85
+ * truyền mảng chuỗi -> trả object { key: value | null }.
86
+ */
87
+ export declare const getParams: (name?: string | string[] | null) => string | Record<string, string | null> | null;
25
88
  export declare const setParams: (newParams: Record<string, string | null>) => string;
26
89
  export declare const createQueryString: (params: Record<string, any>) => string;
27
- export declare const getIdParams: () => number | null;
90
+ /**
91
+ * Lấy `:id` từ URL hiện tại.
92
+ *
93
+ * Route do `CusRoute.addGS()` sinh ra có dạng `.../detail/:id` hoặc `.../edit/:id`,
94
+ * nên `:id` KHÔNG nằm ở cuối pathname. Regex cũ (`/\/(\d+)(\/)?$/`) chỉ khớp khi
95
+ * id nằm cuối -> trả `null` sai, dẫn tới nhánh 403/404 render sai.
96
+ *
97
+ * @param pathname mặc định lấy từ `window.location.pathname` (truyền vào để test hoặc dùng trong router)
98
+ * @param pattern route pattern, mặc định theo convention của `CusRoute`
99
+ */
100
+ export declare const getIdParams: (pathname?: string, pattern?: RegExp) => number | null;
28
101
  export declare const getImage: (image: string, df?: string) => string;
29
102
  export declare const getFile: (file: string) => string;
30
103
  export declare const getPubImage: (image: string, df?: string) => string;
@@ -32,10 +105,48 @@ export declare const getUploadImage: (image: string, df?: string) => string;
32
105
  export declare const getUploadFile: (file: string, df?: string) => string;
33
106
  export declare function randomString(length: number): string;
34
107
  export declare function htmlToText(html: string): string;
35
- export declare const checkUploadFile: (files: any, size?: number, type?: any) => Promise<unknown>;
108
+ /**
109
+ * Dựng RegExp kiểm tra phần mở rộng từ thuộc tính `accept` của `<input type="file">`.
110
+ *
111
+ * ⚠ SỬA LỖI BẢO MẬT: bản cũ lặp ở 7 component dùng
112
+ * new RegExp(`\.(` + acceptAttr.replace(...) + `)$`, 'i')
113
+ * Trong template literal, `\.` là escape KHÔNG hợp lệ nên chuỗi thực tế là
114
+ * `.(pdf|docx)$` — dấu `.` ở regex nghĩa là "ký tự bất kỳ".
115
+ * Hậu quả: file `malwarepdf`, `hongbang.txtpdf`... đều PASS kiểm tra đuôi file.
116
+ * Phải viết `\\.` để regex nhận đúng dấu chấm literal.
117
+ *
118
+ * @param acceptAttr giá trị `accept`, ví dụ `".pdf, .docx"`, `"image/png"` hoặc `".pdf"`
119
+ * @param fallback regex dùng khi `acceptAttr` rỗng (thường là allowlist mặc định)
120
+ */
121
+ export declare const buildAcceptRegExp: (acceptAttr: string | null | undefined, fallback: RegExp) => RegExp;
122
+ /**
123
+ * Kiểm tra danh sách file trước khi upload.
124
+ *
125
+ * Bản cũ có 3 lỗi chuỗi:
126
+ * 1. `type ? type : (regex)` là no-op -> `type` mặc định `false` gây `TypeError: type.test is not a function`;
127
+ * 2. `return false` bên trong Promise executor KHÔNG reject -> promise treo vĩnh viễn,
128
+ * `.then()` ở call-site không bao giờ chạy (form im lặng dù alert đã hiện);
129
+ * 3. `resolve(this)` -> `this` là `undefined` trong arrow function.
130
+ *
131
+ * Nay: reject với `Error` để call-site bắt được, vẫn hiện alert cho UX.
132
+ */
133
+ export declare const checkUploadFile: (files: FileList | File[] | null | undefined, size?: number, type?: RegExp) => Promise<void>;
134
+ /** Escape 5 ký tự HTML nguy hiểm — dùng cho mọi dữ liệu không tin cậy trước khi nhúng vào `__html`. */
135
+ export declare const escapeHtml: (value: unknown) => string;
136
+ /**
137
+ * Render thông báo lỗi thành HTML alert.
138
+ *
139
+ * Đã thêm escape: `errors` đến từ response API (`res.data.error`) — nếu server trả
140
+ * về chuỗi chứa HTML/script thì `dangerouslySetInnerHTML` sẽ thành XSS stored.
141
+ * `type` cũng được kiểm tra theo allowlist để không chèn được class tuỳ ý.
142
+ *
143
+ * Muốn render HTML cố ý thì truyền `{ raw: true }` (chỉ dùng với nội dung do dev sinh).
144
+ */
36
145
  export declare const showMessage: (errors?: {
37
146
  [key: string]: string;
38
- } | string, type?: string) => string;
147
+ } | string, type?: string, options?: {
148
+ raw?: boolean;
149
+ }) => string;
39
150
  export declare const resetForm: (form: HTMLFormElement) => HTMLFormElement;
40
151
  export declare const mapDataForm: (form: HTMLFormElement, data: Record<string, any>, hidden?: boolean) => Promise<Record<string, any>>;
41
152
  export declare const elFinderPopup: (el: string, options?: Record<string, any>) => Promise<unknown>;
@@ -54,7 +165,8 @@ export declare const showFinderFileModal: (btnEl: HTMLDivElement, modalCls: stri
54
165
  }) => void) | false, fnHide?: (() => void) | false) => void;
55
166
  export declare const filterIds: (input: any[] | string) => number[];
56
167
  export declare function stringToJson(input: any, df?: {}, type?: string): any;
57
- export declare const formatNumber: (number: number, options?: {}, type?: string) => string | 0;
168
+ /** Luôn trả về chuỗi đã format (0 -> "0", null -> "0") để không lệch return type. */
169
+ export declare const formatNumber: (number: number, options?: Intl.NumberFormatOptions, type?: string) => string;
58
170
  export declare const decimalNumber: (value: string | number) => Decimal;
59
171
  /**
60
172
  * Lấy ra một mảng giá trị của cùng một field từ mảng object
@@ -1,7 +1,27 @@
1
1
  import { RouteObject } from 'react-router-dom';
2
+ import { ReactNode } from 'react';
3
+ /**
4
+ * Một "màn hình" trong route: element của react-router, hoặc `false` để báo
5
+ * "không cài màn hình này".
6
+ *
7
+ * Trước đây tham số này là `any = false` — không rõ ý nghĩa, và sai kiểu vẫn
8
+ * chạy được cho tới lúc runtime.
9
+ */
10
+ export type RouteElement = ReactNode | false;
2
11
  export declare class CusRoute {
3
12
  private routes;
4
- addGS(link: string, layout: any, Index: any, Update?: any, Detail?: any, Import?: any, Fields?: any): Promise<void>;
13
+ /**
14
+ * Thêm một nhóm route CRUD cho một resource.
15
+ *
16
+ * @param link path gốc, ví dụ `/admin/products`
17
+ * @param layout component bọc ngoài
18
+ * @param Index component danh sách
19
+ * @param Update component thêm/sửa — bật cả route `create` và `edit/:id`
20
+ * @param Detail component chi tiết
21
+ * @param Import component import
22
+ * @param Fields component tuỳ chỉnh trường
23
+ */
24
+ addGS(link: string, layout: RouteElement, Index: RouteElement, Update?: RouteElement, Detail?: RouteElement, Import?: RouteElement, Fields?: RouteElement): Promise<void>;
5
25
  addRoute(routeList?: RouteObject[]): void;
6
26
  getRouter(): RouteObject[];
7
27
  }
@@ -1,2 +1,23 @@
1
- export declare function loadEnv(): Promise<any>;
2
- export declare function getEnv(): any;
1
+ export interface EnvType {
2
+ API_URL?: string;
3
+ ADMIN_URI?: string;
4
+ SECRET_KEY?: string;
5
+ STATIC_URL?: string;
6
+ UPLOADS_URL?: string;
7
+ [key: string]: any;
8
+ }
9
+ /**
10
+ * Tải cấu hình runtime từ `/env.json`.
11
+ *
12
+ * - KHÔNG BAO GIỜ reject: nếu 404 / network lỗi / parse lỗi thì trả về `{}`.
13
+ * Mục đích: một config thiếu không được làm trắng màn hình toàn bộ app.
14
+ * - Kết quả được cache sau lần gọi đầu tiên; dùng `reloadEnv()` để thử lại.
15
+ */
16
+ export declare function loadEnv(): Promise<EnvType>;
17
+ /**
18
+ * Đọc cấu hình đã tải. Trả `{}` nếu chưa tải xong — cố tình KHÔNG throw để
19
+ * component render được với giá trị rỗng thay vì sập cả cây.
20
+ */
21
+ export declare function getEnv(): EnvType;
22
+ /** Ép tải lại `/env.json` (dùng để retry sau khi lần load đầu thất bại). */
23
+ export declare function reloadEnv(): Promise<EnvType>;
@@ -1 +1,12 @@
1
- export declare const checkPermission: (menuData: any[], moduleText: string, controller: string, action: string, code: number, groupId: number) => any;
1
+ import { MenuPermissionItem } from '../types/Menu';
2
+ /**
3
+ * Kiểm tra quyền của user đối với một hành động.
4
+ *
5
+ * Quy ước `status`: `0` = đã ẩn/khóa (không tính), khác `0` = đang hoạt động.
6
+ * Khớp với bộ lọc ở `Sidebar.tsx` / `SidebarItem.tsx` để menu hiển thị và
7
+ * quyền kiểm tra luôn nhất quán.
8
+ *
9
+ * Fail-closed: không tìm thấy menu tương ứng thì trả `false`
10
+ * (thay vì `true` như bản cũ — fail-open là lỗ hổng phân quyền).
11
+ */
12
+ export declare const checkPermission: (menuData: MenuPermissionItem[], moduleText: string, controller: string, action: string, code: number, groupId: number) => boolean;
@@ -1,3 +1,24 @@
1
+ /**
2
+ * jQuery phải được nạp sẵn (script tag hoặc `import "jquery"` ở app).
3
+ *
4
+ * Resolve LAZY thay vì đọc `window.jQuery` lúc module-eval, để:
5
+ * - import package trong môi trường không có DOM (SSR / test) không crash;
6
+ * - lỗi "chưa nạp jQuery" chỉ nổ ra đúng lúc thực sự validate,
7
+ * kèm thông báo rõ ràng thay vì "x is not a function".
8
+ */
9
+ /**
10
+ * Collection jQuery.
11
+ *
12
+ * CỐ TÌNH không dùng kiểu `JQuery` của `@types/jquery`: bản v4 đã bỏ generic
13
+ * của nó và bỏ luôn `JQuery.Promise`. Nếu những kiểu đó lọt vào `.d.ts` thì mọi
14
+ * consumer chạy `strict` + `skipLibCheck: false` đều **không typecheck được** —
15
+ * đã kiểm chứng bằng cách pack và cài vào một project sạch.
16
+ *
17
+ * Đây là bản port của plugin jQuery Bootstrap Validator, các call site thực sự
18
+ * là động (`$el[0]`, `$el.val()`, `$el.data()`...) nên `any` ở đây là mô tả
19
+ * trung thực, không phải lười.
20
+ */
21
+ type Jq = any;
1
22
  export declare class Validator {
2
23
  options: any;
3
24
  validators: any;
@@ -25,29 +46,30 @@ export declare class Validator {
25
46
  };
26
47
  static VALIDATORS: {
27
48
  native: ($el: any) => any;
28
- match: ($el: JQuery) => string | false | undefined;
29
- minlength: ($el: JQuery) => string | false;
30
- maxlength: ($el: JQuery) => string | false;
31
- filesize: ($el: JQuery<HTMLInputElement>) => boolean;
32
- accept: ($el: JQuery<HTMLInputElement>) => boolean;
33
- pattern: ($el: JQuery) => boolean;
49
+ match: ($el: Jq) => any;
50
+ minlength: ($el: Jq) => string | false;
51
+ maxlength: ($el: Jq) => string | false;
52
+ filesize: ($el: Jq) => boolean;
53
+ accept: ($el: Jq) => boolean;
54
+ pattern: ($el: Jq) => boolean;
34
55
  };
35
56
  constructor(element: any, options?: any);
36
- static getValue($el: JQuery): boolean | number | string | string[];
57
+ static getValue($el: Jq): boolean | number | string | string[];
37
58
  update: () => this;
38
59
  onInput: (e: any) => void;
39
- validateInput: ($el: JQuery, deferErrors: any) => JQuery.Promise<any, any, any> | undefined;
40
- runValidators: ($el: JQuery) => JQuery.Promise<any, any, any>;
60
+ validateInput: ($el: Jq, deferErrors: any) => any;
61
+ runValidators: ($el: Jq) => any;
41
62
  validate: () => this;
42
63
  focusError: () => void;
43
- showErrors: ($el: JQuery) => void;
44
- clearErrors: ($el: JQuery) => void;
64
+ showErrors: ($el: Jq) => void;
65
+ clearErrors: ($el: Jq) => void;
45
66
  hasErrors: () => boolean;
46
67
  isIncomplete: () => boolean;
47
68
  onSubmit: (e: any) => void;
48
69
  toggleSubmit: () => void;
49
- defer: ($el: JQuery, callback: any) => any;
70
+ defer: ($el: Jq, callback: any) => any;
50
71
  reset: () => this;
51
72
  destroy: () => this;
52
73
  run: () => void;
53
74
  }
75
+ export {};
@@ -0,0 +1,11 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../rolldown-runtime-BocRIvOZ.cjs"),t=require("../Env-DoS-iQjs.cjs");let n=require("sweetalert2");n=e.t(n,1);let r=require("sweetalert2-react-content");r=e.t(r,1);let i=require("bootstrap"),a=require("date-fns"),o=require("decimal.js");o=e.t(o,1),t.n();var s=e=>t.t()[e]??``,c=e=>new Promise((t,n)=>{if(document.querySelector(`script[src="${e}"]`)){t();return}let r=document.createElement(`script`);r.src=e,r.onload=()=>t(),r.onerror=()=>n(Error(`Failed to load script ${e}`)),document.body.appendChild(r)}),l=async e=>{for(let t of e)await c(t)},ee=(e,t=!0)=>{let n=typeof e==`string`?document.querySelector(e):e;if(n){if(t)n.querySelector(`.boxSpinner`)||n.insertAdjacentHTML(`afterbegin`,`<div class="boxSpinner rounded">
2
+ <div class="spinner">
3
+ <div class="rect1"></div>
4
+ <div class="rect2"></div>
5
+ <div class="rect3"></div>
6
+ <div class="rect4"></div>
7
+ <div class="rect5"></div>
8
+ <div class="rect6"></div>
9
+ <div class="rect7"></div>
10
+ </div>
11
+ </div>`);else{let e=n.querySelector(`.boxSpinner`);e&&e.remove()}}},u=e=>{let t=new FormData;return Object.entries(e).forEach(([e,n])=>{if(n!=null){if(n instanceof FileList){Array.from(n).forEach(n=>t.append(e,n));return}if(n instanceof File){t.append(e,n);return}if(Array.isArray(n)&&n.every(e=>e instanceof File)){n.forEach(n=>t.append(e,n));return}if(Array.isArray(n)&&n.every(e=>[`string`,`number`,`boolean`].includes(typeof e))){n.forEach(n=>t.append(e,n.toString()));return}if(typeof n==`object`){t.append(e,JSON.stringify(n));return}t.append(e,n)}}),t},d=class extends Error{errorCode;constructor(e,t){super(e),this.name=`ApiError`,this.errorCode=t}},te=async(e,t={},n=`POST`,r=`application/json`)=>{let i={method:n,headers:{"Content-Type":r,"Secret-Key":s(`SECRET_KEY`)},credentials:`include`};n==`POST`&&(i.body=JSON.stringify(t));let a=await(await fetch(e,i)).json();if(a.status==200)return a;throw a.msg?new d(a.msg,a.errorCode??`unknown`):Error(`invalid_response`)};async function f(e,t={},n=`POST`,r=`application/json`,i=!0){let a={"Secret-Key":s(`SECRET_KEY`)};r!==`multipart/form-data`&&(a[`Content-Type`]=r);let o={method:n,headers:a,credentials:`include`};if(n==`POST`&&(o.body=r===`multipart/form-data`?u(t):JSON.stringify(t)),n===`GET`&&Object.keys(t).length>0){let n=new URLSearchParams;Object.entries(t).forEach(([e,t])=>{Array.isArray(t)?t.forEach(t=>n.append(e,String(t))):n.append(e,String(t))});let r=n.toString();e+=(e.includes(`?`)?`&`:`?`)+r}let c=await(await fetch(e,o)).text(),l=null;if(c)try{l=JSON.parse(c)}catch{l=c}if(l&&typeof l!=`string`&&l.status==200)return l;if(l&&typeof l!=`string`&&l.msg&&i)throw new d(l.msg,l.errorCode??`unknown`);if(i)throw Error(`invalid_response`);return!1}var p=(e=`Bạn có chắc muốn thực hiện thao tác này ?`,t=`Đồng ý`)=>(0,r.default)(n.default).fire({title:`Xác nhận`,text:e,icon:`warning`,showCancelButton:!0,confirmButtonColor:`#4CAF50`,cancelButtonColor:`#F44336`,confirmButtonText:t,cancelButtonText:`Hủy`,position:`top`}),m=(e,t=`top`,i=!1)=>{(0,r.default)(n.default).fire({toast:i,icon:`success`,position:t,title:e,showConfirmButton:!1,timer:1500})},ne=e=>{(0,r.default)(n.default).fire({icon:`warning`,title:e,showConfirmButton:!1,timer:1500})},h=e=>{(0,r.default)(n.default).fire({icon:`error`,position:`top`,title:e,showConfirmButton:!1})},re=(e,t,n=`name`)=>{let r=t?.find(t=>t.id===e);return r?r[n]??null:null},ie=(e,t,n=`name`)=>e.map(e=>{let r=t.find(t=>t.id===e);return r?r[n]:null}).filter(Boolean).join(`, `),ae=e=>Array.isArray(e)?e.map((e,t)=>`<p class="mb-0"><a class="text-info" target="_blank" rel="noopener noreferrer" href="${V(F(e,`#`))}">Tập tin ${t+1}</a></p>`).filter(Boolean).join(``):``,g=(e,t,n=!1)=>{if(e===!1)return t;let r=t.find(t=>t.id===Number(e));return r?n?`<span class="badge badge-sm bg-gradient-${r.color}">${r.name}</span>`:r.name:``},oe=[{id:1,name:`Kích hoạt`,color:`success`},{id:0,name:`Khóa`,color:`danger`}],se=[{id:1,name:`Xuất bản`,color:`success`},{id:0,name:`Nháp`,color:`danger`}],ce=[{id:1,name:`Có`,color:`success`},{id:0,name:`Không`,color:`secondary`}],_=(e,t=!1)=>g(e,oe,t),v=(e,t=!1)=>g(e,se,t),y=(e,t=!1)=>g(e,ce,t);function b(e){let t=e instanceof Date?e:new Date(e);if(isNaN(t.getTime()))throw Error(`Ngày không hợp lệ: `+e);return t}function x(e){if(!e)return new Date;if(e instanceof Date)return new Date(e);let t=e.trim().toLowerCase();if(t===`now`)return new Date;let n=new Date,r=t.match(/^([+-]?\d+)\s*(year|years|month|months|week|weeks|day|days|hour|hours|minute|minutes|min|mins|second|seconds|sec|secs)$/);if(r){let e=Number(r[1]);switch(r[2]){case`year`:case`years`:n.setFullYear(n.getFullYear()+e);break;case`month`:case`months`:n.setMonth(n.getMonth()+e);break;case`week`:case`weeks`:n.setDate(n.getDate()+e*7);break;case`day`:case`days`:n.setDate(n.getDate()+e);break;case`hour`:case`hours`:n.setHours(n.getHours()+e);break;case`minute`:case`minutes`:case`min`:case`mins`:n.setMinutes(n.getMinutes()+e);break;case`second`:case`seconds`:case`sec`:case`secs`:n.setSeconds(n.getSeconds()+e)}return n}let i=new Date(t);if(!isNaN(i.getTime()))return i;throw Error(`Invalid date expression: ${e}`)}var S=e=>{if(!e)return null;let t=new Date(e);return isNaN(t.getTime())?null:{dd:String(t.getDate()).padStart(2,`0`),MM:String(t.getMonth()+1).padStart(2,`0`),yyyy:t.getFullYear(),hh:String(t.getHours()).padStart(2,`0`),mm:String(t.getMinutes()).padStart(2,`0`),ss:String(t.getSeconds()).padStart(2,`0`)}},C=e=>{let t=S(e);return t?`${t.dd}/${t.MM}/${t.yyyy} ${t.hh}:${t.mm}:${t.ss}`:e?`Invalid Date`:``},w=e=>{let t=S(e);return t?`${t.dd}/${t.MM}/${t.yyyy}`:e?`Invalid Date`:``},T=e=>{let t=S(e);return t?`${t.yyyy}`:e?`Invalid Date`:``},E=e=>{let t=S(e);return t?`${t.yyyy}-${t.MM}-${t.dd}`:e?`Invalid Date`:``},D=e=>{let t=new URLSearchParams(window.location.search);return e?Array.isArray(e)?e.reduce((e,n)=>(e[n]=t.get(n),e),{}):t.get(e):Object.fromEntries(t.entries())},O=e=>{let t=new URLSearchParams(window.location.search);return Object.entries(e).forEach(([e,n])=>{n===null?t.delete(e):t.set(e,n)}),t.toString()},k=e=>{let t=new URLSearchParams;return Object.entries(e).forEach(([e,n])=>{Array.isArray(n)?n.forEach(n=>{n!=null&&t.append(e,String(n))}):n!=null&&t.set(e,String(n))}),t.toString()},A=(e=typeof window<`u`?window.location.pathname:``,t=/\/(?:edit|detail|update)\/(\d+)(?=\/|$)/i)=>{let n=new RegExp(t.source,t.flags.includes(`g`)?t.flags:t.flags+`g`),r=null,i;for(;(i=n.exec(e))!==null;)r=i;if(!r)return null;let a=Number(r[1]);return Number.isFinite(a)?a:null},j=(e,t=`/styles/default.jpg`)=>e?s(`STATIC_URL`)+(`/`+e).replaceAll(`//`,`/`):t,M=e=>e?s(`STATIC_URL`)+(`/`+e).replaceAll(`//`,`/`):``,N=(e,t=`/styles/default.jpg`)=>e?s(`API_URL`)+(`/`+e).replaceAll(`//`,`/`):t,P=(e,t=`/styles/default.jpg`)=>e?s(`UPLOADS_URL`)+`/`+e:t,F=(e,t=`/styles/default.jpg`)=>e?s(`UPLOADS_URL`)+`/`+e:t;function I(e){let t=``;for(let n=0;n<e;n++){let e=Math.floor(Math.random()*62);t+=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`[e]}return t}function L(e){return new DOMParser().parseFromString(e,`text/html`).body.textContent||``}var R=/\.(jpg|jpeg|png|jfif|doc|docx|xls|xlsx|pdf)$/i,z=(e,t)=>{if(!e)return t;let n=e.split(`,`).map(e=>{let t=e.trim();return(t.includes(`/`)?t.slice(t.indexOf(`/`)+1):t).replace(/^\./,``)}).filter(Boolean);if(n.length===0)return t;let r=n.map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));return RegExp(`\\.(${r.join(`|`)})$`,`i`)},B=(e,t=20,n=R)=>new Promise((r,i)=>{let a=Array.from(e??[]);if(a.length===0)return i(Error(`Tập tin không tồn tại`));for(let e of a){if(!n.test(e.name))return h(`Tập tin không hợp lệ`),i(Error(`Tập tin không hợp lệ`));if(e.size>t*1024*1024)return h(`Tập tin tải lên không quá ${t}M`),i(Error(`Tập tin tải lên không quá ${t}M`))}r()}),le={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`},V=e=>String(e??``).replace(/[&<>"']/g,e=>le[e]),H=new Set([`danger`,`success`,`warning`,`info`,`primary`,`secondary`,`light`,`dark`]),U=(e=``,t=`danger`,n={})=>{let r=H.has(t)?t:`danger`,i=e=>n.raw?e:V(e);return typeof e==`string`?e.trim()===``?``:`<div class="alert alert-${r}">${i(e)}</div>`:!e||typeof e!=`object`?``:Object.values(e).filter(e=>e!=null&&String(e).trim()!==``).map(e=>`<div class="alert alert-${r}">${i(String(e))}</div>`).join(``)},W=e=>(e.querySelectorAll(`input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not(.noReset), textarea`).forEach(e=>{e.value=``,e.dispatchEvent(new Event(`change`,{bubbles:!0}))}),e.querySelectorAll(`select:not(.noReset)`).forEach(e=>{let t=e.querySelector(`option[value=""]`);t?t.selected=!0:e.options.length>0&&(e.selectedIndex=0),e.dispatchEvent(new Event(`change`,{bubbles:!0}))}),e.querySelectorAll(`input[type="checkbox"]:not(.noReset)`).forEach(e=>{e.checked=!1,e.dispatchEvent(new Event(`change`,{bubbles:!0}))}),e.querySelectorAll(`input[type="radio"]:not(.noReset)`).forEach(e=>{e.checked=!1,e.dispatchEvent(new Event(`change`,{bubbles:!0}))}),e),ue=async(e,t,n=!1)=>{try{for(let r in t){let i=`[name="${r}"]:not([type="file"])`,o=e.querySelector(i);if(!o)continue;let s=o.type;if(t[r]&&![`checkbox`,`radio`].includes(s)){let e=(0,a.parse)(t[r],`yyyy-MM-dd`,new Date),n=(0,a.parse)(t[r],`yyyy-MM-dd HH:mm:ss`,new Date);o.value=(0,a.isValid)(e)&&t[r].length===10?(0,a.format)(e,`dd/MM/yyyy`):(0,a.isValid)(n)&&t[r].length===19?(0,a.format)(n,`dd/MM/yyyy HH:mm`):t[r],o.dispatchEvent(new Event(`change`,{bubbles:!0}))}else if(s===`checkbox`)o.checked=!!parseInt(t[r]),o.dispatchEvent(new Event(`change`,{bubbles:!0}));else if(s===`radio`){let n=e.querySelectorAll(`input[type="radio"][name="${r}"]`);n.forEach(e=>{e.checked=e.value===String(parseInt(t[r]))}),n.forEach(e=>e.dispatchEvent(new Event(`change`,{bubbles:!0})))}else if(n){let e=o.closest(`.form-group`);e&&e.classList.add(`hidden`)}}return t}catch(e){return Promise.reject(e)}},G=(e,t={})=>new Promise((n,r)=>{try{let r=window.jQuery,i=r(e);if(!i.length)throw Error(`invalid_elfinder`);let a={url:s(`API_URL`)+`/elfinder/connector`,height:500,resizable:!0,baseUrl:`/assets/plugins/elFinder/`,defaultView:`list`,useBrowserHistory:!1,getFileCallback:e=>{n(e)}};i.elfinder(`destroy`).elfinder({...a,...t})}catch(e){r(e)}}),K=e=>new Promise((t,n)=>{try{let n=typeof e==`string`?document.querySelector(e):e;if(!n)throw Error(`invalid_modalEl_btnEl`);n.querySelectorAll(`.btn-md-close`)?.forEach(e=>{e?.addEventListener(`click`,()=>{r.hide()})});let r=i.Modal.getOrCreateInstance(n,{backdrop:`static`,keyboard:!1});t({md:r,modalEl:n})}catch(e){console.log(e),n(e)}}),de=(e,t,n=!1,r=!1)=>{if(!e)throw Error(`invalid_btnEl`);e.addEventListener(`click`,i=>{i.preventDefault(),K(t).then(t=>{let{modalEl:i,md:a}=t;G(`#elfinderStatic`).then(t=>{n&&n({data:t,btnEl:e,md:a})}),i.addEventListener(`hidden.bs.modal`,()=>{r&&r()}),a.show()})})},fe=(e,t,n=!1,r=!1)=>{if(!e)throw Error(`invalid_btnEl`);e.addEventListener(`click`,i=>{i.preventDefault(),K(t).then(t=>{let{modalEl:i,md:a}=t;G(`#elfinderStatic`,{url:s(`API_URL`)+`/elfinder/connectorFiles`}).then(t=>{n&&n({data:t,btnEl:e,md:a})}),i.addEventListener(`hidden.bs.modal`,()=>{r&&r()}),a.show()})})},q=e=>{if(typeof e==`string`&&(e=J(e,[])),!Array.isArray(e))return[];let t=e.map(e=>Number(e));return t=t.filter(e=>!Number.isNaN(e)),[...new Set(t)]};function J(e,t={},n=`ids`){let r=t;if(Array.isArray(e)&&(r=e),typeof e==`object`&&e&&(r=e),typeof e==`number`)return t;if(typeof e==`string`)try{let t=JSON.parse(e);Array.isArray(t)&&(r=t),typeof t==`object`&&t&&(r=t)}catch{return t}return n===`ids`&&(r=q(r)),r}var pe=(e,t={},n=`vi-VN`)=>e==null||Number.isNaN(e)?`0`:e.toLocaleString(n,t),me=e=>{if(!e)return new o.default(0);let t=String(e).replace(/[^\d.]/g,``);return t?new o.default(t):new o.default(0)},he=(e,t)=>[...new Set(e.map(e=>e[t]))],ge=(e,t,n,r,i)=>{let a=e.length,o=[];for(let s=0;s<a;s++){let a=t.find(t=>t[r]===e[s]);a&&o.push({[n]:e[s],[i]:a[i]})}return o},_e=(e,t)=>e.map(e=>{let n={};for(let r in t){let i=t[r];typeof i==`string`?n[r]=e[i]:typeof i==`function`&&(n[r]=i(e))}return n}),Y=(e,t,n=!1)=>{if(t.split(`-`).map(Number).includes(e))return!0;if(n)throw Error(`invalid_status`);return!1};function ve(e,t){return e?.reduce((e,n)=>e+(n[t]??0),0)||0}var ye=e=>{switch(e){case 3:return`tháng `+(new Date().getMonth()+1);case 4:return`năm `+new Date().getFullYear()}return``},be=(e=!1)=>{let t=[{id:1,name:`Tiếng Việt`}];return e===!1?t:t.find(t=>t.id===e)?.name||``},xe=class{routes=[];async addGS(e,t,n,r=!1,i=!1,a=!1,o=!1){let s={path:e,element:t,children:[{index:!0,element:n},{path:`page/:page`,element:n}]};i&&s.children.push({path:`detail/:id`,element:i}),r&&s.children.push({path:`create`,element:r}),r&&s.children.push({path:`edit/:id`,element:r}),a&&s.children.push({path:`import`,element:a}),o&&s.children.push({path:`fields`,element:o}),this.routes.push(s)}addRoute(e=[]){this.routes=[...this.routes,...e]}getRouter(){return this.routes}},X=(e,t,n,r,i,a)=>{if(!a)return!1;if(a===1)return!0;if(!Array.isArray(e))return!1;for(let o of e)if(o){if(o.module===t&&o.controller===n&&o.action===r&&Number(o.code)===Number(i))return o.status!==0&&!!o.isPer;if(Array.isArray(o.subs)&&o.subs.length>0&&X(o.subs,t,n,r,i,a))return!0}return!1},Z=null,Q=()=>{if(Z)return Z;let e=typeof window<`u`?window.jQuery??window.$:void 0;if(typeof e!=`function`)throw Error(`[@materialui-reactjs/admin] Validator cần jQuery. Hãy thêm "jquery" vào dependencies và nạp nó TRƯỚC khi dùng Validator.`);return Z=e,Z},$=new Proxy((()=>{}),{apply:(e,t,n)=>Q()(...n),get:(e,t)=>Q()[t]}),Se=class e{options;validators;$element;$btn;$inputs;static VERSION=`0.11.9`;static INPUT_SELECTOR=`:input:not(.nvali,[type="hidden"], [type="submit"], [type="reset"], button)`;static FOCUS_OFFSET=20;static DEFAULTS={delay:500,html:!1,disable:!0,focus:!0,custom:{},errors:{match:`Does not match`,minlength:`Too short`,maxlength:`Too long`},feedback:{success:`glyphicon-ok`,error:`glyphicon-remove`}};static VALIDATORS={native:function(e){let t=e[0];if(t.checkValidity)return!t.checkValidity()&&!t.validity.valid&&(t.validationMessage||`error!`)},match:function(t){let n=t.attr(`data-match`);return n&&t.val()!==$(n).val()&&e.DEFAULTS.errors.match},minlength:function(t){let n=Number(t.attr(`data-minlength`));return String(t.val()??``).length<n&&e.DEFAULTS.errors.minlength},maxlength:function(t){let n=Number(t.attr(`data-maxlength`));return String(t.val()??``).length>n&&e.DEFAULTS.errors.maxlength},filesize:function(e){let t=Number(e.data(`filesize`)),n=e[0];return n?.files?.length?n.files[0].size>t*1024*1024:!1},accept:function(e){let t=e.attr(`data-accept`);if(!t)return!1;let n=e[0];if(!n?.files?.length)return!1;let r=n.files[0];return!new RegExp(t).test(r.name)},pattern:function(e){let t=e.attr(`data-pattern`);return t?!new RegExp(t).test(String(e.val()??``)):!1}};constructor(t,n=!1){this.options=n||e.DEFAULTS,this.validators=$.extend({},e.VALIDATORS),this.$element=$(t),this.$btn=this.$element.find(`button[type="submit"], input[type="submit"], .submitAjax`),this.$inputs=this.$element.find(e.INPUT_SELECTOR).add(this.$element.find(`[data-validate="true"]`)).not(this.$element.find(`[data-validate="false"]`).each((e,t)=>{this.clearErrors($(t))}))}static getValue(e){return e.is(`[type="checkbox"]`)?!!e.prop(`checked`):e.is(`[type="radio"]`)?$(`[name="${e.attr(`name`)}"]:checked`).length>0:e.is(`select[multiple]`)?(e.val()??[]).length:e.val()??``}update=()=>{let t=this;return this.$inputs=this.$element.find(e.INPUT_SELECTOR).add(this.$element.find(`[data-validate="true"]`)).not(this.$element.find(`[data-validate="false"]`).each((e,n)=>{t.clearErrors($(n))})),this.toggleSubmit(),this};onInput=e=>{let t=this,n=$(e.target),r=e.type!==`focusout`;this.$inputs.is(n)&&this.validateInput(n,r)?.done(function(){t.toggleSubmit()})};validateInput=(e,t)=>{let n=e.data(`bs.validator.errors`);e.is(`[type="radio"]`)&&(e=this.$element.find(`input[name="`+e.attr(`name`)+`"]`));let r=$.Event(`validate.bs.validator`,{relatedTarget:e[0]});if(this.$element.trigger(r),r.isDefaultPrevented())return;let i=this;return this.runValidators(e).done(function(a){e.data(`bs.validator.errors`,a),a.length?t?i.defer(e,i.showErrors):i.showErrors(e):i.clearErrors(e),(!n||a.toString()!==n.toString())&&(r=a.length?$.Event(`invalid.bs.validator`,{relatedTarget:e[0],detail:a}):$.Event(`valid.bs.validator`,{relatedTarget:e[0],detail:n}),i.$element.trigger(r)),i.toggleSubmit(),i.$element.trigger($.Event(`validated.bs.validator`,{relatedTarget:e[0]}))})};runValidators=t=>{let n=[],r=$.Deferred(),i=t.data(`bs.validator.deferred`);i&&i.reject(),t.data(`bs.validator.deferred`,r);function a(e){return t.attr(`data-`+e+`-error`)}function o(){let e=t[0];if(!(e instanceof HTMLInputElement)&&!(e instanceof HTMLSelectElement)&&!(e instanceof HTMLTextAreaElement))return null;let n=e.validity;return n.typeMismatch?t.attr(`data-type-error`)??null:n.patternMismatch?t.attr(`data-pattern-error`)??null:n.stepMismatch?t.attr(`data-step-error`)??null:n.rangeOverflow?t.attr(`data-max-error`)??null:n.rangeUnderflow?t.attr(`data-min-error`)??null:n.valueMissing?t.attr(`data-required-error`)??null:null}function s(){return t.attr(`data-error`)}function c(e){return a(e)||o()||s()}return $.each(this.validators,$.proxy(function(r,i){let a;(e.getValue(t)||t.attr(`required`))&&(t.attr(`data-`+r)!==void 0||r==`native`)&&(a=i.call(this,t))&&(a=c(r)||a,n.indexOf(a)===-1&&n.push(a))},this)),r.resolve(n),r.promise()};validate=()=>{let e=this;return $.when(this.$inputs.map((t,n)=>e.validateInput($(n),!1))).then(function(){e.toggleSubmit(),e.focusError()}),this};focusError=()=>{if(!this.options.focus)return;let t=this.$element.find(`.has-error:first :input`);t.length!==0&&($(`html, body`).animate({scrollTop:t.offset().top-e.FOCUS_OFFSET},250),t.focus())};showErrors=e=>{this.options.html;let t=e.data(`bs.validator.errors`),n=e.closest(`.form-group`),r=n.find(`.form-control-feedback`);t.length&&(t=$(`<ul/>`).addClass(`list-unstyled`).append($.map(t,e=>{let t=$(`<li/>`);return this.options.html?t.html(e):t.text(e)})),n.addClass(`has-error has-danger`),n.find(`.invalid-tooltip, .invalid-feedback`).remove(),n.find(`.select2,.form-control`).removeClass(`is-valid`).addClass(`is-invalid`),n.append(`<div class="invalid-feedback"><ul class="list-unstyled">${t.html()}<ul/></div>`),n.removeClass(`has-success`),n.hasClass(`has-feedback`),r.removeClass(this.options.feedback?.success),r.addClass(this.options.feedback?.error))};clearErrors=e=>{let t=e.closest(`.form-group`),n=t.find(`.form-control-feedback`);t.removeClass(`has-error has-danger has-success`),t.find(`.invalid-tooltip, .invalid-feedback`).remove(),t.find(`.select2,.form-control`).addClass(`is-valid`).removeClass(`is-invalid`),t.addClass(`has-success`),t.hasClass(`has-feedback`),n.removeClass(this.options.feedback?.error),n.removeClass(this.options.feedback?.success),n.addClass(this.options.feedback?.success)};hasErrors=()=>!!this.$inputs.filter(function(){return!!($(this).data(`bs.validator.errors`)||[]).length}).length;isIncomplete=()=>!!this.$inputs.filter(`[required]`).filter((t,n)=>{let r=e.getValue($(n));return!(typeof r==`string`?r.trim():r)}).length;onSubmit=e=>{this.validate(),(this.isIncomplete()||this.hasErrors())&&e.preventDefault()};toggleSubmit=()=>{this.options.disable};defer=(e,t)=>{if(t=t.bind(this,e),!this.options.delay)return t();window.clearTimeout(e.data(`bs.validator.timeout`)),e.data(`bs.validator.timeout`,window.setTimeout(t,this.options.delay))};reset=()=>(this.$element.find(`.form-control-feedback`).removeClass(this.options?.feedback.error).removeClass(this.options.feedback.success),this.$inputs.removeData([`bs.validator.errors`,`bs.validator.deferred`]).each(()=>{let e=$(this),t=e.data(`bs.validator.timeout`);window.clearTimeout(t),e.removeData(`bs.validator.timeout`)}),this.$element.find(`.invalid-tooltip, .invalid-feedback`).each(()=>{let e=$(this),t=e.data(`bs.validator.originalContent`);e.removeData(`bs.validator.originalContent`).html(t)}),this.$btn.removeClass(`disabled`),this.$element.find(`.has-error, .has-danger, .has-success, .is-invalid, .is-valid`).removeClass(`has-error has-danger has-success is-invalid is-valid`),this);destroy=()=>(this.reset(),this.$element.removeAttr(`novalidate`).removeData(`bs.validator`).off(`.bs.validator`),this.$inputs.off(`.bs.validator`),this.options=null,this.validators=null,this.$element=null,this.$btn=null,this.$inputs=null,this);run=()=>{this.update(),this.$element.on(`input.bs.validator change.bs.validator focusout.bs.validator`,this.onInput.bind(this)),this.$element.on(`submit.bs.validator`,this.onSubmit.bind(this)),this.$element.on(`reset.bs.validator`,this.reset.bind(this)),this.$element.find(`[data-match]`).each(function(){let t=$(this),n=t.attr(`data-match`);n&&$(n).on(`input.bs.validator`,function(){e.getValue(t)&&t.trigger(`input.bs.validator`)})}),this.$inputs.filter((t,n)=>e.getValue($(n))&&!$(this).closest(`.has-error`).length).trigger(`focusout`),this.$element.attr(`novalidate`,!0)}};exports.ApiError=d,exports.CusRoute=xe,exports.Validator=Se,exports.buildAcceptRegExp=z,exports.buildFormData=u,exports.callFetchApi=te,exports.callFetchApiToken=f,exports.checkPermission=X,exports.checkUploadFile=B,exports.createModal=K,exports.createQueryString=k,exports.decimalNumber=me,exports.elFinderPopup=G,exports.escapeHtml=V,exports.filterIds=q,exports.formatDate=w,exports.formatDateSql=E,exports.formatDateTime=C,exports.formatNumber=pe,exports.formatYear=T,exports.getActiveStatus=_,exports.getEnv=t.t,exports.getFile=M,exports.getFilterType=ye,exports.getIdParams=A,exports.getImage=j,exports.getLangs=be,exports.getLinkFiles=ae,exports.getName=re,exports.getNames=ie,exports.getParams=D,exports.getPubImage=N,exports.getPublishStatus=v,exports.getStatus=g,exports.getTrueFlaseStatus=y,exports.getUploadFile=F,exports.getUploadImage=P,exports.htmlToText=L,exports.isStsNum=Y,exports.loadEnv=t.n,exports.loadScript=c,exports.loadScripts=l,exports.mapArrData=_e,exports.mapArrFields=he,exports.mapDataForm=ue,exports.mergeArrObject=ge,exports.parseDate=b,exports.randomString=I,exports.reloadEnv=t.r,exports.resetForm=W,exports.setParams=O,exports.showFinderFileModal=fe,exports.showFinderModal=de,exports.showMessage=U,exports.showSweetAlert=p,exports.showSweetAlertError=h,exports.showSweetAlertOk=m,exports.showSweetAlertWarning=ne,exports.spinnerLoader=ee,exports.strToDate=x,exports.stringToJson=J,exports.sumArrCol=ve;
@@ -1,5 +1,6 @@
1
1
  export * from './Common';
2
2
  export * from './CusRoute';
3
- export { loadEnv, getEnv } from './Env';
3
+ export { loadEnv, getEnv, reloadEnv } from './Env';
4
+ export type { EnvType } from './Env';
4
5
  export * from './Group';
5
6
  export * from './Validator';