ui-soxo-bootstrap-core 2.6.5 → 2.6.6
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/.babelrc +8 -8
- package/.github/workflows/npm-publish.yml +33 -33
- package/.husky/pre-commit +11 -11
- package/.prettierrc.json +10 -10
- package/babel.config.js +2 -2
- package/core/components/component-loader/component-loader.js +125 -125
- package/core/components/component-wrapper/component-wrapper.js +121 -121
- package/core/components/external-window/DEVELOPER_GUIDE.md +705 -705
- package/core/components/external-window/external-window.js +236 -236
- package/core/components/external-window/external-window.test.js +80 -80
- package/core/components/extra-info/extra-info-details.js +155 -155
- package/core/components/extra-info/extra-info-details.scss +26 -26
- package/core/components/extra-info/extra-info.js +134 -134
- package/core/components/index.js +20 -20
- package/core/components/landing-api/landing-api.js +492 -492
- package/core/components/landing-api/landing-api.scss +19 -19
- package/core/components/menu-template-api/menu-template-api.js +321 -321
- package/core/components/root-application-api/root-application-api.js +174 -174
- package/core/index.js +13 -13
- package/core/lib/Store.js +365 -365
- package/core/lib/components/application-bootstrap/application-bootstrap.js +115 -115
- package/core/lib/components/approval-form/approval-form.js +280 -280
- package/core/lib/components/approval-form/approval-form.scss +183 -183
- package/core/lib/components/approval-list/approval-list.js +143 -143
- package/core/lib/components/approval-list/approval-list.scss +2 -2
- package/core/lib/components/approval-list/components/request-card/request-card.js +42 -42
- package/core/lib/components/approval-list/components/request-card/request-card.scss +30 -30
- package/core/lib/components/camera/camera.js +230 -230
- package/core/lib/components/camera/camera.scss +86 -86
- package/core/lib/components/comment-block/comment-block.js +138 -138
- package/core/lib/components/comment-block/comment-block.scss +3 -3
- package/core/lib/components/confirm-modal/confirm-modal.js +82 -82
- package/core/lib/components/confirm-modal/confirm-modal.scss +2 -2
- package/core/lib/components/consent/consent.js +67 -67
- package/core/lib/components/consent/pdf-signature.js +299 -299
- package/core/lib/components/consent/signature-pad.js +90 -90
- package/core/lib/components/consent/signature-pad.scss +14 -14
- package/core/lib/components/file-upload/file-upload.js +133 -133
- package/core/lib/components/finger-print-reader/finger-print-reader.js +295 -295
- package/core/lib/components/finger-print-reader/finger-print-reader.scss +47 -47
- package/core/lib/components/finger-print-search/finger-print-search.js +200 -200
- package/core/lib/components/finger-print-search/finger-print-search.scss +47 -47
- package/core/lib/components/global-header/animations.js +18 -18
- package/core/lib/components/global-header/global-header.js +413 -413
- package/core/lib/components/global-header/global-header.scss +369 -369
- package/core/lib/components/header/generic-header.js +76 -76
- package/core/lib/components/header/generic-header.scss +99 -99
- package/core/lib/components/image-preview/image-preview.js +33 -33
- package/core/lib/components/image-wrapper/image-wrapper.js +108 -108
- package/core/lib/components/image-wrapper/image-wrapper.scss +12 -12
- package/core/lib/components/index.js +206 -206
- package/core/lib/components/landing/landing.js +403 -403
- package/core/lib/components/language-switcher/language-switcher.js +49 -49
- package/core/lib/components/menu-context/menu-context.js +69 -69
- package/core/lib/components/menu-template/menu-template.js +249 -249
- package/core/lib/components/menu-template/menu-template.scss +9 -9
- package/core/lib/components/modal-search/modal-search.js +153 -153
- package/core/lib/components/modal-search/modal-search.scss +78 -78
- package/core/lib/components/modal-wrapper/modal-manager.js +15 -15
- package/core/lib/components/modal-wrapper/modal-wrapper.js +108 -108
- package/core/lib/components/modal-wrapper/modal-wrapper.scss +13 -13
- package/core/lib/components/notice-board/notice-board.js +132 -132
- package/core/lib/components/notice-board/notice-board.scss +65 -65
- package/core/lib/components/page-container/page-container.js +55 -55
- package/core/lib/components/page-container/page-container.scss +8 -8
- package/core/lib/components/page-header/page-header.js +23 -23
- package/core/lib/components/page-header/page-header.scss +17 -17
- package/core/lib/components/pdf-viewer/pdf-viewer.js +56 -56
- package/core/lib/components/portlet-table/components/table-actions/table-actions.js +58 -58
- package/core/lib/components/portlet-table/components/table-actions/table-actions.scss +1 -1
- package/core/lib/components/portlet-table/components/table-data/table-data.js +106 -106
- package/core/lib/components/portlet-table/portlet-table.js +63 -63
- package/core/lib/components/portlet-table/portlet-table.scss +90 -90
- package/core/lib/components/progress-bar/progress-bar.js +58 -58
- package/core/lib/components/progress-bar/progress-bar.scss +15 -15
- package/core/lib/components/request-form/request-form.js +110 -110
- package/core/lib/components/root-application/root-application.js +70 -70
- package/core/lib/components/rupee/rupee.js +14 -14
- package/core/lib/components/script-input/script-input.js +169 -169
- package/core/lib/components/script-input/script-input.scss +8 -8
- package/core/lib/components/sidemenu/animations.js +51 -51
- package/core/lib/components/sidemenu/sidemenu.js +578 -578
- package/core/lib/components/sidemenu/sidemenu.scss +277 -277
- package/core/lib/components/spotlight-search/spotlight-search.component.js +635 -635
- package/core/lib/components/spotlight-search/spotlight-search.component.scss +78 -78
- package/core/lib/components/table-wrapper/table-wrapper.js +135 -135
- package/core/lib/components/table-wrapper/table-wrapper.scss +72 -72
- package/core/lib/components/ui_elements/Loader.js +12 -12
- package/core/lib/components/ui_elements/Notify.js +12 -12
- package/core/lib/components/ui_elements/PlaceHolder.js +33 -33
- package/core/lib/components/web-camera/web-camera.js +161 -161
- package/core/lib/components/web-camera/web-camera.scss +28 -28
- package/core/lib/core.md +9 -9
- package/core/lib/elements/Elements.md +2 -2
- package/core/lib/elements/basic/LoggedUserRedirect.js +21 -21
- package/core/lib/elements/basic/PrivateRoute.js +16 -16
- package/core/lib/elements/basic/button/Button.md +43 -43
- package/core/lib/elements/basic/button/button.js +170 -170
- package/core/lib/elements/basic/card/Card.md +15 -15
- package/core/lib/elements/basic/card/card.js +40 -40
- package/core/lib/elements/basic/card/card.scss +13 -13
- package/core/lib/elements/basic/checkbox/checkbox.js +23 -23
- package/core/lib/elements/basic/col/col.js +15 -15
- package/core/lib/elements/basic/copy-to-clipboard/Readme.md +40 -40
- package/core/lib/elements/basic/copy-to-clipboard/copy-to-clipboard.js +61 -61
- package/core/lib/elements/basic/country-phone-input/Readme.md +98 -98
- package/core/lib/elements/basic/country-phone-input/country-phone-input.js +106 -106
- package/core/lib/elements/basic/country-phone-input/phone-input.scss +61 -61
- package/core/lib/elements/basic/datepicker/datepicker.js +33 -33
- package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +136 -136
- package/core/lib/elements/basic/empty/empty.js +14 -14
- package/core/lib/elements/basic/fingerprint-protrected/fingerprint-protected.js +118 -118
- package/core/lib/elements/basic/fingerprint-protrected/fingerprint-protected.scss +10 -10
- package/core/lib/elements/basic/form/form.js +70 -70
- package/core/lib/elements/basic/form/form.scss +3 -3
- package/core/lib/elements/basic/image/image.js +45 -45
- package/core/lib/elements/basic/image/image.scss +17 -17
- package/core/lib/elements/basic/image/readme.md +26 -26
- package/core/lib/elements/basic/image-viewer/image-viewer.js +108 -108
- package/core/lib/elements/basic/image-viewer/image-viewer.scss +7 -7
- package/core/lib/elements/basic/input/input.js +81 -81
- package/core/lib/elements/basic/input/readme.md +77 -77
- package/core/lib/elements/basic/json-input/json-input.js +51 -51
- package/core/lib/elements/basic/menu-dashboard/menu-dashboard.js +216 -216
- package/core/lib/elements/basic/menu-dashboard/menu-dashboard.scss +28 -28
- package/core/lib/elements/basic/menu-tree/menu-tree.js +114 -114
- package/core/lib/elements/basic/modal/modal.js +64 -64
- package/core/lib/elements/basic/modal/readme.md +62 -62
- package/core/lib/elements/basic/popconfirm/popconfirm.js +17 -17
- package/core/lib/elements/basic/popover/popover.js +12 -12
- package/core/lib/elements/basic/radio/radio.js +18 -18
- package/core/lib/elements/basic/rangepicker/rangepicker.js +141 -141
- package/core/lib/elements/basic/rangepicker/rangepicker.scss +24 -24
- package/core/lib/elements/basic/rangepicker/readme.md +81 -81
- package/core/lib/elements/basic/reference-select/readme.md +18 -18
- package/core/lib/elements/basic/reference-select/reference-select.js +337 -337
- package/core/lib/elements/basic/row/row.js +15 -15
- package/core/lib/elements/basic/select/select.js +46 -46
- package/core/lib/elements/basic/select-box/readme.md +52 -52
- package/core/lib/elements/basic/select-box/select-box.js +63 -63
- package/core/lib/elements/basic/skeleton/readme.md +35 -35
- package/core/lib/elements/basic/skeleton/skeleton.js +35 -35
- package/core/lib/elements/basic/skeleton/skeleton.scss +53 -53
- package/core/lib/elements/basic/space/space.js +12 -12
- package/core/lib/elements/basic/switch/readme.md +29 -29
- package/core/lib/elements/basic/switch/switch.js +67 -67
- package/core/lib/elements/basic/tab/tab.js +14 -14
- package/core/lib/elements/basic/table/readme.md +8 -8
- package/core/lib/elements/basic/table/table.js +100 -100
- package/core/lib/elements/basic/tag/tag.js +63 -63
- package/core/lib/elements/basic/tag/tag.scss +2 -2
- package/core/lib/elements/basic/timeline/timeline.js +13 -13
- package/core/lib/elements/basic/title/readme.md +20 -20
- package/core/lib/elements/basic/title/title.js +37 -37
- package/core/lib/elements/basic/user-search/user-search.js +192 -192
- package/core/lib/elements/complex/barcode/barcode.js +27 -27
- package/core/lib/elements/complex/bargraph/bar-graph.js +262 -262
- package/core/lib/elements/complex/basic-table/basic-table.js +110 -110
- package/core/lib/elements/complex/basic-table/basic-table.scss +4 -4
- package/core/lib/elements/complex/date-display/date-display.js +37 -37
- package/core/lib/elements/complex/error-boundary/error-boundary.js +29 -29
- package/core/lib/elements/complex/google-location-input/map-container-library-load.js +92 -92
- package/core/lib/elements/complex/google-map/google-map.js +230 -230
- package/core/lib/elements/complex/google-map/google-map.scss +13 -13
- package/core/lib/elements/complex/line-graph/line-graph.js +108 -108
- package/core/lib/elements/complex/location-search-input/location-search-input.js +100 -100
- package/core/lib/elements/complex/pie-chart/pie-chart.js +202 -202
- package/core/lib/elements/complex/qr-code/qr-code.js +27 -27
- package/core/lib/elements/complex/qrscanner/qrscanner.js +57 -57
- package/core/lib/elements/complex/search-debounce/search-debounce.js +37 -37
- package/core/lib/elements/complex/statistic-card/dashboard-statistic-card.js +75 -75
- package/core/lib/elements/complex/statistic-card/statistic-card.js +28 -28
- package/core/lib/elements/index.js +226 -226
- package/core/lib/hooks/device-detect.js +25 -25
- package/core/lib/hooks/index.js +9 -9
- package/core/lib/hooks/use-location.js +33 -33
- package/core/lib/hooks/use-otp-timer.js +80 -80
- package/core/lib/hooks/use-window-size.js +34 -34
- package/core/lib/i18n.js +69 -69
- package/core/lib/index.js +106 -106
- package/core/lib/introduction.md +73 -73
- package/core/lib/js-styleguide.md +4112 -4112
- package/core/lib/models/actions/actions.js +127 -127
- package/core/lib/models/actions/components/action-detail/action-detail.js +190 -190
- package/core/lib/models/actions/components/custom-actions/custom-actions.js +185 -185
- package/core/lib/models/attachments/attachments.js +231 -231
- package/core/lib/models/base-loader.js +99 -99
- package/core/lib/models/base.js +716 -716
- package/core/lib/models/branches/branches.js +125 -125
- package/core/lib/models/checklists/checklists.js +114 -114
- package/core/lib/models/columns/columns.js +169 -169
- package/core/lib/models/columns/components/columns-add/columns-add.js +171 -171
- package/core/lib/models/comments/comments.js +213 -213
- package/core/lib/models/departments/departments.js +107 -107
- package/core/lib/models/financial-years/financial_years.js +127 -127
- package/core/lib/models/forms/components/form-creator/form-creator.js +624 -624
- package/core/lib/models/forms/components/form-creator/form-creator.scss +30 -29
- package/core/lib/models/forms/components/form-detail/form-detail.js +224 -224
- package/core/lib/models/forms/forms.js +121 -121
- package/core/lib/models/index.js +203 -203
- package/core/lib/models/invoice-numbers/invoice_numbers.js +204 -204
- package/core/lib/models/lookup-types/components/lookup-detail/lookup-detail.js +145 -145
- package/core/lib/models/lookup-types/lookup-types.js +113 -113
- package/core/lib/models/lookup-values/components/lookup-values-add/lookup-values-add.js +126 -126
- package/core/lib/models/lookup-values/lookup-values.js +107 -107
- package/core/lib/models/menu-roles/menu-roles.js +127 -127
- package/core/lib/models/menus/components/menu-add/menu-add.js +228 -228
- package/core/lib/models/menus/components/menu-detail/menu-detail.js +170 -170
- package/core/lib/models/menus/components/menu-list/menu-list.js +593 -593
- package/core/lib/models/menus/components/menu-list/menu-list.scss +5 -5
- package/core/lib/models/menus/components/menu-roles-add/menu-roles-add.js +183 -183
- package/core/lib/models/menus/menus.js +499 -499
- package/core/lib/models/models/components/model-detail/model-detail.js +137 -137
- package/core/lib/models/models/components/models.js +128 -128
- package/core/lib/models/modules/modules.js +204 -204
- package/core/lib/models/outbox/outbox.js +73 -73
- package/core/lib/models/pages/pages.js +107 -107
- package/core/lib/models/permissions/permissions.js +71 -71
- package/core/lib/models/process/components/process-add/process-add.js +181 -181
- package/core/lib/models/process/components/process-dashboard/process-dashboard.js +601 -601
- package/core/lib/models/process/components/process-dashboard/process-dashboard.scss +62 -62
- package/core/lib/models/process/components/process-detail/process-detail.js +140 -140
- package/core/lib/models/process/components/process-timeline/process-timeline.js +139 -139
- package/core/lib/models/process/components/task-detail/task-detail.js +240 -240
- package/core/lib/models/process/components/task-detail/task-detail.scss +27 -27
- package/core/lib/models/process/components/task-form/task-form.js +528 -528
- package/core/lib/models/process/components/task-form/task-form.scss +7 -7
- package/core/lib/models/process/components/task-list/task-list.js +221 -221
- package/core/lib/models/process/components/task-list/task-list.scss +14 -14
- package/core/lib/models/process/components/task-overview/task-overview.js +299 -299
- package/core/lib/models/process/components/task-overview-legacy/task-overview-legacy.js +192 -192
- package/core/lib/models/process/components/task-routes/task-routes.js +45 -45
- package/core/lib/models/process/components/task-status/task-status.js +175 -175
- package/core/lib/models/process/components/task-status/task-status.scss +11 -11
- package/core/lib/models/process/process.js +780 -780
- package/core/lib/models/process-transactions/process-transactions.js +123 -123
- package/core/lib/models/roles/roles.js +106 -106
- package/core/lib/models/scripts/scripts.js +111 -111
- package/core/lib/models/step-transactions/step-transcations.js +147 -147
- package/core/lib/models/steps/components/step-add/step-add.js +261 -261
- package/core/lib/models/steps/components/step-detail/step-detail.js +157 -157
- package/core/lib/models/steps/steps.js +356 -356
- package/core/lib/models/user-preferences/user-preferences.js +83 -83
- package/core/lib/models/users/components/user-add/user-add.js +226 -226
- package/core/lib/models/users/users.js +119 -119
- package/core/lib/modules/business/launch-page/launch-page.js +29 -29
- package/core/lib/modules/business/launch-page/launch-page.scss +5 -5
- package/core/lib/modules/business/slots/slots.js +231 -231
- package/core/lib/modules/business/slots/slots.scss +108 -108
- package/core/lib/modules/forms/components/field-customizer/field-customizer.js +138 -138
- package/core/lib/modules/forms/components/field-selector/field-selector.js +157 -157
- package/core/lib/modules/forms/components/field-selector/field-selector.scss +25 -25
- package/core/lib/modules/forms/components/form-display/form-display.js +203 -203
- package/core/lib/modules/forms/components/form-display/form-display.scss +9 -9
- package/core/lib/modules/forms/components/tab-customizer/tab-customizer.js +124 -124
- package/core/lib/modules/generic/generic-add/generic-add.js +213 -213
- package/core/lib/modules/generic/generic-detail/generic-detail.js +199 -199
- package/core/lib/modules/generic/generic-edit/generic-edit.js +120 -120
- package/core/lib/modules/generic/generic-list/ExportReactCSV.js +62 -62
- package/core/lib/modules/generic/generic-list/generic-list.js +705 -705
- package/core/lib/modules/generic/generic-list/generic-list.scss +34 -34
- package/core/lib/modules/generic/generic-upload/generic-upload.js +483 -483
- package/core/lib/modules/generic/table-settings/table-settings.js +226 -226
- package/core/lib/modules/generic/table-settings/table-settings.scss +37 -37
- package/core/lib/modules/index.js +52 -52
- package/core/lib/modules/modules-routes/module-routes.js +35 -35
- package/core/lib/pages/change-password/change-password.js +201 -201
- package/core/lib/pages/change-password/change-password.scss +73 -73
- package/core/lib/pages/homepage/homepage.js +53 -53
- package/core/lib/pages/index.js +19 -19
- package/core/lib/pages/login/commnication-mode-selection.js +46 -46
- package/core/lib/pages/login/communication-mode-selection.scss +60 -60
- package/core/lib/pages/login/login.js +864 -864
- package/core/lib/pages/login/login.scss +344 -344
- package/core/lib/pages/login/reset-password.js +125 -125
- package/core/lib/pages/login/reset-password.scss +22 -22
- package/core/lib/pages/manage-users/manage-users.js +429 -429
- package/core/lib/pages/manage-users/manage-users.scss +25 -25
- package/core/lib/pages/profile/profile.js +247 -247
- package/core/lib/pages/profile/profile.scss +107 -107
- package/core/lib/pages/profile/theme-config.js +18 -18
- package/core/lib/pages/profile/themes-backup.json +310 -310
- package/core/lib/pages/profile/themes.json +254 -254
- package/core/lib/pages/register/register.js +176 -176
- package/core/lib/pages/register/register.scss +128 -128
- package/core/lib/react-styleguide.md +756 -756
- package/core/lib/utils/api/api.utils.js +211 -211
- package/core/lib/utils/api/readme.md +426 -426
- package/core/lib/utils/async.js +35 -35
- package/core/lib/utils/common/common.utils.js +223 -223
- package/core/lib/utils/common/readme.md +30 -30
- package/core/lib/utils/date/date.utils.js +295 -295
- package/core/lib/utils/date/readme.md +2 -2
- package/core/lib/utils/firebase.support.utils.js +98 -98
- package/core/lib/utils/firebase.utils.js +808 -808
- package/core/lib/utils/form/form.utils.js +255 -255
- package/core/lib/utils/generic/generic.utils.js +69 -69
- package/core/lib/utils/http/auth.helper.js +95 -95
- package/core/lib/utils/http/http.utils.js +158 -158
- package/core/lib/utils/http/readme.md +14 -14
- package/core/lib/utils/index.js +40 -40
- package/core/lib/utils/location/location.utils.js +137 -137
- package/core/lib/utils/location/readme.md +18 -18
- package/core/lib/utils/modal.utils.js +15 -15
- package/core/lib/utils/notification.utils.js +34 -34
- package/core/lib/utils/pwa/pwa.utils.js +88 -88
- package/core/lib/utils/script.utils.js +235 -235
- package/core/lib/utils/setting.utils.js +68 -68
- package/core/lib/utils/upload.utils.js +29 -29
- package/core/models/Preference/Preferences.js +46 -46
- package/core/models/base/base.js +403 -403
- package/core/models/base-clone-loader.js +107 -107
- package/core/models/base-clone.js +187 -187
- package/core/models/base-loader.js +97 -97
- package/core/models/core-scripts/core-scripts.js +150 -150
- package/core/models/dashboard/dashboard.js +201 -201
- package/core/models/detail-loader.js +88 -88
- package/core/models/doctor/components/doctor-add/doctor-add.js +427 -427
- package/core/models/doctor/components/doctor-add/doctor-add.scss +32 -32
- package/core/models/groups.js +82 -82
- package/core/models/index.js +100 -100
- package/core/models/lookup-types/components/lookup-detail/lookup-detail.js +129 -129
- package/core/models/lookup-types/lookup-types.js +96 -96
- package/core/models/lookup-values/components/lookup-values-modal/lookup-values-modal.js +95 -95
- package/core/models/lookup-values/lookup-values.js +92 -92
- package/core/models/menu-roles/components/menu-roles-add/menu-roles-add.js +153 -153
- package/core/models/menu-roles/menu-roles.js +158 -158
- package/core/models/menus/components/menu-add/menu-add.js +288 -288
- package/core/models/menus/components/menu-add/menu-add.scss +31 -31
- package/core/models/menus/components/menu-detail/menu-detail.js +263 -263
- package/core/models/menus/components/menu-list/menu-list.js +392 -392
- package/core/models/menus/components/menu-lists/menu-lists.js +585 -585
- package/core/models/menus/components/menu-lists/menu-lists.scss +46 -46
- package/core/models/menus/menus.js +310 -310
- package/core/models/model-columns.js +121 -121
- package/core/models/models/components/model-detail/model-add.js +120 -120
- package/core/models/models/components/model-detail/model-detail.js +133 -133
- package/core/models/models/models.js +154 -154
- package/core/models/pages/components/page-add/page-add.js +163 -163
- package/core/models/pages/components/page-add/page-add.scss +30 -30
- package/core/models/pages/components/page-details/page-details.js +209 -209
- package/core/models/pages/components/page-list/page-list.js +248 -248
- package/core/models/pages/pages.js +142 -142
- package/core/models/pages.js +142 -142
- package/core/models/roles/components/role-add/role-add.js +312 -312
- package/core/models/roles/components/role-add/role-add.scss +4 -4
- package/core/models/roles/components/role-list/role-list.js +386 -386
- package/core/models/roles/roles.js +196 -196
- package/core/models/staff/components/staff-add/staff-add.js +467 -467
- package/core/models/user-roles/components/user-roles-add/user-roles-add.js +149 -149
- package/core/models/user-roles/user-roles.js +113 -113
- package/core/models/users/components/assign-role/assign-role.js +406 -406
- package/core/models/users/components/assign-role/assign-role.scss +281 -281
- package/core/models/users/components/assign-role/avatar-props.js +45 -45
- package/core/models/users/components/user-add/user-add.js +856 -856
- package/core/models/users/components/user-add/user-edit.js +106 -106
- package/core/models/users/components/user-detail/user-detail.js +236 -236
- package/core/models/users/components/user-list/user-list.js +397 -397
- package/core/models/users/users.js +379 -379
- package/core/modules/Informations/change-info/change-info.js +618 -618
- package/core/modules/Informations/change-info/change-info.scss +134 -134
- package/core/modules/dashboard/components/dashboard-card/animations.js +64 -64
- package/core/modules/dashboard/components/dashboard-card/dashboard-card.js +197 -197
- package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +430 -430
- package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.scss +59 -59
- package/core/modules/dashboard/components/pop-query-dashboard/pop-query-dashboard.js +66 -66
- package/core/modules/generic/components/generic-add/generic-add.js +121 -121
- package/core/modules/generic/components/generic-add/generic-add.scss +13 -13
- package/core/modules/generic/components/generic-add-modal/generic-add-modal.js +125 -125
- package/core/modules/generic/components/generic-add-modal/generic-add-modal.scss +13 -13
- package/core/modules/generic/components/generic-detail/generic-detail.js +184 -184
- package/core/modules/generic/components/generic-detail/generic-detail.scss +25 -25
- package/core/modules/generic/components/generic-edit/generic-edit.js +123 -123
- package/core/modules/generic/components/generic-list/generic-list.js +335 -335
- package/core/modules/generic/components/generic-list/generic-list.scss +35 -35
- package/core/modules/index.js +42 -42
- package/core/modules/module-routes/module-routes.js +37 -37
- package/core/modules/reporting/components/index.js +6 -6
- package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +74 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +252 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +126 -0
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +880 -1206
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +171 -171
- package/core/modules/steps/action-buttons.js +74 -76
- package/core/modules/steps/action-buttons.scss +44 -15
- package/core/modules/steps/steps.js +348 -346
- package/core/modules/steps/steps.scss +357 -159
- package/core/modules/steps/timeline.js +56 -54
- package/core/pages/homepage-api/homepage-api.js +106 -106
- package/core/pages/homepage-api/homepage-api.scss +233 -233
- package/core/pages/homepage-api/menu-dashboard.js +169 -169
- package/core/pages/homepage-api/menu-dashboard.scss +11 -11
- package/core/translation.json +53 -53
- package/core/translations.json +19 -19
- package/core/utils/script.utils.js +129 -129
- package/core/utils/settings.utils.js +25 -25
- package/eslint.config.mjs +79 -79
- package/index.js +35 -35
- package/jest.config.js +7 -7
- package/jest.setup.js +1 -1
- package/package.json +123 -123
- package/tsconfig.json +26 -26
- package/webpack.config.js +173 -173
|
@@ -1,856 +1,856 @@
|
|
|
1
|
-
import React, { useState, useEffect, useContext } from 'react';
|
|
2
|
-
|
|
3
|
-
import { useLocation } from 'react-router-dom';
|
|
4
|
-
|
|
5
|
-
import { Skeleton, Typography, message, Switch, Form, Input, Select, Checkbox, Row, Col } from 'antd';
|
|
6
|
-
|
|
7
|
-
import AsyncSelect from 'react-select/async';
|
|
8
|
-
|
|
9
|
-
import { Table, Card, Button, JSONInput, GlobalContext, safeJSON } from './../../../../lib/';
|
|
10
|
-
|
|
11
|
-
import { ModelsAPI, PagesAPI, RolesAPI } from '../../..';
|
|
12
|
-
|
|
13
|
-
import { UsersAPI } from '../../..';
|
|
14
|
-
import DoctorAdd from '../../../doctor/components/doctor-add/doctor-add';
|
|
15
|
-
import StaffAdd from '../../../staff/components/staff-add/staff-add';
|
|
16
|
-
|
|
17
|
-
const { Title } = Typography;
|
|
18
|
-
|
|
19
|
-
const { Option } = Select;
|
|
20
|
-
|
|
21
|
-
const UserAdd = ({ model, callback, edit, history, formContent, match, additional_queries, props, mode = 'Add', attributes }) => {
|
|
22
|
-
/**Getting user data */
|
|
23
|
-
const { user = {} } = useContext(GlobalContext);
|
|
24
|
-
// let mode = 'Add';
|
|
25
|
-
|
|
26
|
-
const [disabled, setDisabled] = useState(true);
|
|
27
|
-
|
|
28
|
-
const [selectedOption, setSelectedOption] = useState(null);
|
|
29
|
-
// for selected branches
|
|
30
|
-
const [selectedBranches, setSelectedBranches] = useState([]);
|
|
31
|
-
|
|
32
|
-
// for default branch
|
|
33
|
-
// const [defaultBranch, setDefaultBranch] = useState(null);
|
|
34
|
-
//Need to check this condition
|
|
35
|
-
const [authentication, setAuthentication] = useState(false);
|
|
36
|
-
|
|
37
|
-
/**To store user values */
|
|
38
|
-
const [users, setUsers] = useState([]);
|
|
39
|
-
const [doctorID, setDoctorID] = useState(false);
|
|
40
|
-
const [selectedDoctor, setSelectedDoctor] = useState(null);
|
|
41
|
-
const [staffID, setStaffID] = useState(false);
|
|
42
|
-
const [selectedStaff, setSelectedStaff] = useState(null);
|
|
43
|
-
const [staffList, setStaffList] = useState([]);
|
|
44
|
-
/**Converting to JSON */
|
|
45
|
-
const firmDetails = safeJSON(user?.firm?.f_otherdetails1) ?? {};
|
|
46
|
-
|
|
47
|
-
/**Variable for cheaking mandatory condition of mobile*/
|
|
48
|
-
let mobileRequired;
|
|
49
|
-
|
|
50
|
-
/**If mode is mobile and fa is 'MND' or 'USR' then mobile is mandatory */
|
|
51
|
-
if (((firmDetails && firmDetails.FA === 'MND') || (firmDetails && firmDetails.FA === 'USR')) && firmDetails.mode === 'mobile') {
|
|
52
|
-
mobileRequired = true;
|
|
53
|
-
} else {
|
|
54
|
-
mobileRequired = false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (formContent?.id) {
|
|
58
|
-
mode = 'Edit';
|
|
59
|
-
} else if (formContent?.copy) {
|
|
60
|
-
mode = 'Copy';
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (formContent?.attributes) {
|
|
64
|
-
if (typeof formContent.attributes === 'string') {
|
|
65
|
-
if (formContent.attributes !== '') {
|
|
66
|
-
formContent.attributes = JSON.parse(formContent.attributes);
|
|
67
|
-
} else {
|
|
68
|
-
if (formContent) {
|
|
69
|
-
formContent.attributes = {};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
if (formContent) {
|
|
75
|
-
formContent.attributes = {};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const [loading, setLoading] = useState(true);
|
|
80
|
-
// user type state
|
|
81
|
-
const [userType, setUserType] = useState('general');
|
|
82
|
-
// state for branches list
|
|
83
|
-
const [branches, setBranches] = useState([]);
|
|
84
|
-
// designation list state
|
|
85
|
-
const [designations, setDesignations] = useState([]);
|
|
86
|
-
// department list state
|
|
87
|
-
const [departments, setDepartments] = useState([]);
|
|
88
|
-
// doctor list state
|
|
89
|
-
const [doctorList, setDoctorList] = useState([]);
|
|
90
|
-
// for role list
|
|
91
|
-
const [roles, setRoles] = useState([]);
|
|
92
|
-
|
|
93
|
-
const [form] = Form.useForm();
|
|
94
|
-
|
|
95
|
-
const [body, setBody] = useState(formContent);
|
|
96
|
-
|
|
97
|
-
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
98
|
-
const [visible, setVisible] = useState(false);
|
|
99
|
-
|
|
100
|
-
const formData = {
|
|
101
|
-
...body,
|
|
102
|
-
/**If panel is open then takes password in body */
|
|
103
|
-
password: !isPasswordVisible ? '' : body.password,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
let passwordRegex;
|
|
107
|
-
let passwordRegexMessage;
|
|
108
|
-
|
|
109
|
-
if (props && props?.passwordRegex && props?.passwordRegexMessage) {
|
|
110
|
-
passwordRegex = props.passwordRegex;
|
|
111
|
-
passwordRegexMessage = props.passwordRegexMessage;
|
|
112
|
-
} else if (process.env.REACT_APP_PASSWORD_REGEX && process.env.REACT_APP_PASSWORD_REGEX_MESSAGE) {
|
|
113
|
-
passwordRegex = process.env.REACT_APP_PASSWORD_REGEX;
|
|
114
|
-
passwordRegexMessage = process.env.REACT_APP_PASSWORD_REGEX_MESSAGE;
|
|
115
|
-
} else {
|
|
116
|
-
passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>])[A-Za-z\d!@#$%^&*(),.?":{}|<>]{8,}$/;
|
|
117
|
-
passwordRegexMessage =
|
|
118
|
-
'Password must be at least 8 characters long and contain atleast one uppercase letter, one lowercase letter, one digit and one special character';
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
if (!loading && formContent) {
|
|
123
|
-
form.resetFields(); // clear previous values
|
|
124
|
-
form.setFieldsValue(formContent);
|
|
125
|
-
}
|
|
126
|
-
}, [loading, formContent]);
|
|
127
|
-
|
|
128
|
-
useEffect(() => {
|
|
129
|
-
if (formContent?.auth_user) {
|
|
130
|
-
setSelectedOption({
|
|
131
|
-
value: formContent.auth_user,
|
|
132
|
-
label: formContent.auth_user, // Add a helper function to capitalize
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}, [formContent?.auth_user]);
|
|
136
|
-
|
|
137
|
-
useEffect(() => {
|
|
138
|
-
loadUsers();
|
|
139
|
-
|
|
140
|
-
setLoading(false);
|
|
141
|
-
|
|
142
|
-
if (firmDetails) {
|
|
143
|
-
/**if firmmas.otherdetails - 2FA == MND, then, 2FA option will be enabled by default and read-only */
|
|
144
|
-
if (firmDetails.FA == 'MND') {
|
|
145
|
-
setAuthentication(true);
|
|
146
|
-
|
|
147
|
-
setDisabled(true);
|
|
148
|
-
|
|
149
|
-
/**if firmmas.otherdetails - 2FA == OPT, then, 2FA option will be enabled by default and editable */
|
|
150
|
-
} else if (firmDetails.FA == 'USR') {
|
|
151
|
-
setAuthentication(true);
|
|
152
|
-
|
|
153
|
-
setDisabled(true);
|
|
154
|
-
|
|
155
|
-
/**if firmmas.otherdetails - 2FA == NAP, then, 2FA option will be disabled by default and read-only*/
|
|
156
|
-
} else if (firmDetails.FA == 'NAP') {
|
|
157
|
-
setAuthentication(false);
|
|
158
|
-
|
|
159
|
-
setDisabled(true);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}, []);
|
|
163
|
-
|
|
164
|
-
useEffect(() => {
|
|
165
|
-
if (!loading && formContent?.role_id && roles.length > 0) {
|
|
166
|
-
const roleId = Number(formContent.role_id);
|
|
167
|
-
|
|
168
|
-
if (!Number.isNaN(roleId)) {
|
|
169
|
-
form.setFieldsValue({ role_id: roleId });
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}, [loading, formContent, roles]);
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
*Define the options dynamically
|
|
176
|
-
*/
|
|
177
|
-
const getUserTypeOptions = () => [
|
|
178
|
-
{ label: 'General', value: 'GEN' },
|
|
179
|
-
{ label: 'Doctor', value: 'RAD' },
|
|
180
|
-
{ label: 'Radiographer', value: 'TECH' },
|
|
181
|
-
{ label: 'Staff', value: 'STAFF' },
|
|
182
|
-
];
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Get Branch List
|
|
186
|
-
*/
|
|
187
|
-
const getBranches = () => {
|
|
188
|
-
setLoading(true);
|
|
189
|
-
UsersAPI.getBranches().then(async (result) => {
|
|
190
|
-
const details = await result.result.map((ele) => {
|
|
191
|
-
return {
|
|
192
|
-
...ele,
|
|
193
|
-
...(ele.br_otherdet1 ? JSON.parse(ele.br_otherdet1) : {}),
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
setBranches(details);
|
|
197
|
-
setLoading(false);
|
|
198
|
-
});
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
/** Get Designation List */
|
|
202
|
-
const getDesignations = () => {
|
|
203
|
-
setLoading(true);
|
|
204
|
-
UsersAPI.getDesignations()
|
|
205
|
-
.then((result) => {
|
|
206
|
-
if (result?.success && Array.isArray(result.result)) {
|
|
207
|
-
const details = result.result.map((ele) => ({
|
|
208
|
-
label: ele.dg_desc?.trim() || '',
|
|
209
|
-
value: ele.dg_code,
|
|
210
|
-
}));
|
|
211
|
-
setDesignations(details);
|
|
212
|
-
} else {
|
|
213
|
-
setDesignations([]);
|
|
214
|
-
}
|
|
215
|
-
})
|
|
216
|
-
.catch((error) => {
|
|
217
|
-
setDesignations([]);
|
|
218
|
-
})
|
|
219
|
-
.finally(() => setLoading(false));
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* get role lists
|
|
224
|
-
*/
|
|
225
|
-
function getRoles() {
|
|
226
|
-
RolesAPI.getRole()
|
|
227
|
-
.then((res) => {
|
|
228
|
-
const activeRoles = Array.isArray(res.result) ? res.result.filter((r) => r.active === 'Y') : [];
|
|
229
|
-
setRoles(activeRoles);
|
|
230
|
-
})
|
|
231
|
-
.catch(() => setRoles([]));
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/** Get Department List */
|
|
235
|
-
const getDepartments = () => {
|
|
236
|
-
setLoading(true);
|
|
237
|
-
UsersAPI.getDepartments()
|
|
238
|
-
.then((result) => {
|
|
239
|
-
if (result?.success && Array.isArray(result.result)) {
|
|
240
|
-
const details = result.result.map((ele) => ({
|
|
241
|
-
label: ele.dp_desc?.trim() || '',
|
|
242
|
-
value: ele.dp_id,
|
|
243
|
-
}));
|
|
244
|
-
setDepartments(details);
|
|
245
|
-
} else {
|
|
246
|
-
setDepartments([]);
|
|
247
|
-
}
|
|
248
|
-
})
|
|
249
|
-
.catch((error) => {
|
|
250
|
-
setDepartments([]);
|
|
251
|
-
})
|
|
252
|
-
.finally(() => setLoading(false));
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
/** Get Doctor List */
|
|
256
|
-
const getDoctors = () => {
|
|
257
|
-
UsersAPI.getDoctors()
|
|
258
|
-
.then((res) => {
|
|
259
|
-
if (res?.success && Array.isArray(res.result)) {
|
|
260
|
-
const list = res.result.map((doc) => ({
|
|
261
|
-
label: `${doc.do_name} (${doc.do_code})`,
|
|
262
|
-
value: doc.do_code,
|
|
263
|
-
}));
|
|
264
|
-
setDoctorList(list);
|
|
265
|
-
}
|
|
266
|
-
})
|
|
267
|
-
.catch((err) => console.error('Doctor API Error:', err));
|
|
268
|
-
};
|
|
269
|
-
/** Get staff List */
|
|
270
|
-
const getStaff = () => {
|
|
271
|
-
UsersAPI.getAllStaff()
|
|
272
|
-
.then((res) => {
|
|
273
|
-
if (Array.isArray(res)) {
|
|
274
|
-
const list = res.map((staff) => ({
|
|
275
|
-
label: `${staff.shortName || 'No Name'} (${staff.id})`,
|
|
276
|
-
value: staff.id,
|
|
277
|
-
}));
|
|
278
|
-
|
|
279
|
-
setStaffList(list);
|
|
280
|
-
} else {
|
|
281
|
-
console.error('API did not return an array!');
|
|
282
|
-
}
|
|
283
|
-
})
|
|
284
|
-
.catch((err) => console.error('staff API Error:', err));
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
// Function to handle user type change
|
|
288
|
-
const handleUserTypeChange = (value) => {
|
|
289
|
-
setUserType(value);
|
|
290
|
-
|
|
291
|
-
if (value === 'RAD') {
|
|
292
|
-
getDoctors(); // load doctor list
|
|
293
|
-
} else {
|
|
294
|
-
form.setFieldsValue({ default_code: undefined });
|
|
295
|
-
}
|
|
296
|
-
if (value === 'STAFF') {
|
|
297
|
-
getStaff(); // load staff list
|
|
298
|
-
} else {
|
|
299
|
-
form.setFieldsValue({ staff_code: undefined });
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
useEffect(() => {
|
|
304
|
-
getBranches();
|
|
305
|
-
getDesignations();
|
|
306
|
-
getDepartments();
|
|
307
|
-
getRoles();
|
|
308
|
-
getDoctors(); // load doctor list
|
|
309
|
-
getStaff();
|
|
310
|
-
}, []);
|
|
311
|
-
|
|
312
|
-
useEffect(() => {
|
|
313
|
-
if (formContent && formContent.user_type) {
|
|
314
|
-
form.setFieldsValue({ user_type: formContent.user_type });
|
|
315
|
-
setUserType(formContent.user_type);
|
|
316
|
-
|
|
317
|
-
if (formContent.user_type === 'RAD' && formContent.doctor_code) {
|
|
318
|
-
form.setFieldsValue({ default_code: formContent.doctor_code });
|
|
319
|
-
}
|
|
320
|
-
if (formContent.user_type === 'STAFF' && formContent.staff_code) {
|
|
321
|
-
form.setFieldsValue({ staff_code: formContent.staff_code });
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (!formContent) return;
|
|
325
|
-
|
|
326
|
-
const org =
|
|
327
|
-
typeof formContent.organization_details === 'string' ? JSON.parse(formContent.organization_details) : formContent.organization_details;
|
|
328
|
-
|
|
329
|
-
// normalize branch ids to NUMBER
|
|
330
|
-
const branchIds = (org?.branch_ids || []).map(Number);
|
|
331
|
-
|
|
332
|
-
// find default branch pointer
|
|
333
|
-
const defaultBranchObj = org?.branch?.find((br) => br.defaultBranch);
|
|
334
|
-
|
|
335
|
-
// extract dbPtr (branch code)
|
|
336
|
-
const defaultBranchCode = defaultBranchObj?.branch_id ? Number(defaultBranchObj.branch_id) : undefined;
|
|
337
|
-
|
|
338
|
-
// state (for filtering)
|
|
339
|
-
setSelectedBranches(branchIds);
|
|
340
|
-
|
|
341
|
-
// form values
|
|
342
|
-
form.setFieldsValue({
|
|
343
|
-
selectedBranches: branchIds,
|
|
344
|
-
defaultBranch: defaultBranchCode,
|
|
345
|
-
});
|
|
346
|
-
}, [formContent, form]);
|
|
347
|
-
// Generate branch options for Select component
|
|
348
|
-
const branchOptions = branches.map((branch) => ({
|
|
349
|
-
label: branch.br_desc,
|
|
350
|
-
value: branch.br_code,
|
|
351
|
-
}));
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Submit values
|
|
355
|
-
*/
|
|
356
|
-
const onSubmit = (values) => {
|
|
357
|
-
values.defaultBranch = String(values.defaultBranch);
|
|
358
|
-
|
|
359
|
-
/**If PanelOpen is open and edit mode then password will be existing password else new password*/
|
|
360
|
-
if (!isPasswordVisible && mode === 'Edit') {
|
|
361
|
-
values.password = body.password;
|
|
362
|
-
}
|
|
363
|
-
values.user_type = values.user_type;
|
|
364
|
-
|
|
365
|
-
if (values.user_type === 'RAD') {
|
|
366
|
-
values.doctor_code = values.default_code;
|
|
367
|
-
} else {
|
|
368
|
-
values.doctor_code = null;
|
|
369
|
-
}
|
|
370
|
-
if (values.user_type === 'STAFF') {
|
|
371
|
-
values.staff_code = values.staff_code;
|
|
372
|
-
} else {
|
|
373
|
-
values.staff_code = null;
|
|
374
|
-
}
|
|
375
|
-
values = {
|
|
376
|
-
...values,
|
|
377
|
-
auth_type: 'LDAP',
|
|
378
|
-
FA: authentication,
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
setLoading(true);
|
|
382
|
-
|
|
383
|
-
let id = formContent?.id;
|
|
384
|
-
if (props?.ldap && selectedOption && selectedOption.value) {
|
|
385
|
-
values = {
|
|
386
|
-
...values,
|
|
387
|
-
|
|
388
|
-
addAllBranches: props.ldap.addAllBranches,
|
|
389
|
-
auth_user: selectedOption.value,
|
|
390
|
-
auth_type: 'LDAP',
|
|
391
|
-
FA: authentication,
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (values.attributes && typeof values === 'object') {
|
|
396
|
-
values = {
|
|
397
|
-
...values,
|
|
398
|
-
|
|
399
|
-
auth_type: 'LDAP',
|
|
400
|
-
|
|
401
|
-
attributes: JSON.stringify(values.attributes),
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (id) {
|
|
406
|
-
// Update of model
|
|
407
|
-
|
|
408
|
-
UsersAPI.updateUser({ id, formBody: values }).then((result) => {
|
|
409
|
-
if (result.success) message.success(result.message);
|
|
410
|
-
else message.error(result.message);
|
|
411
|
-
|
|
412
|
-
setLoading(false);
|
|
413
|
-
|
|
414
|
-
callback();
|
|
415
|
-
});
|
|
416
|
-
} else {
|
|
417
|
-
// Append the additional queries to the object
|
|
418
|
-
// additional_queries.forEach(({ field, value }) => {
|
|
419
|
-
// values[field] = value;
|
|
420
|
-
// });
|
|
421
|
-
if (Array.isArray(additional_queries)) {
|
|
422
|
-
additional_queries.forEach(({ field, value }) => {
|
|
423
|
-
values[field] = value;
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// add new model
|
|
428
|
-
UsersAPI.create(values).then((result) => {
|
|
429
|
-
setLoading(false);
|
|
430
|
-
|
|
431
|
-
if (result.success) {
|
|
432
|
-
message.success(result.message);
|
|
433
|
-
// close modal
|
|
434
|
-
callback();
|
|
435
|
-
} else {
|
|
436
|
-
message.error(result.message);
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Function on handle change
|
|
444
|
-
* @param {*} selected
|
|
445
|
-
*/
|
|
446
|
-
const handleCheackChange = (e) => {
|
|
447
|
-
setIsPasswordVisible(e.target.checked);
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
function changeView(result) {
|
|
451
|
-
setAuthentication(result);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Function to add load userrs
|
|
456
|
-
*/
|
|
457
|
-
function loadUsers() {
|
|
458
|
-
// UsersAPI.getLdapUsers().then((result) => {
|
|
459
|
-
// setUsers(result.result);
|
|
460
|
-
// });
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Transform array into react-select options
|
|
464
|
-
let options = users.map((item) => ({
|
|
465
|
-
value: item.name,
|
|
466
|
-
label: item.name, // Capitalize the first letter
|
|
467
|
-
}));
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Function on handle change
|
|
471
|
-
* @param {*} selected
|
|
472
|
-
*/
|
|
473
|
-
const handleChange = (selected) => {
|
|
474
|
-
setSelectedOption(selected);
|
|
475
|
-
};
|
|
476
|
-
/**
|
|
477
|
-
*
|
|
478
|
-
* @param {*} inputValue
|
|
479
|
-
* @param {*} callback
|
|
480
|
-
*/
|
|
481
|
-
|
|
482
|
-
const loadOptions = (inputValue, callback) => {
|
|
483
|
-
// Filter options based on input
|
|
484
|
-
const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
|
|
485
|
-
callback(filteredOptions);
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
return (
|
|
489
|
-
<section className="collection-add">
|
|
490
|
-
<Title level={4}>{mode} User</Title>
|
|
491
|
-
|
|
492
|
-
{loading ? (
|
|
493
|
-
<Skeleton />
|
|
494
|
-
) : (
|
|
495
|
-
<Form initialValues={formData} form={form} layout="vertical" onFinish={onSubmit}>
|
|
496
|
-
{/* user type */}
|
|
497
|
-
<Row gutter={16}>
|
|
498
|
-
<Col span={6}>
|
|
499
|
-
<Form.Item
|
|
500
|
-
name="user_type"
|
|
501
|
-
label="User Type"
|
|
502
|
-
allowClear
|
|
503
|
-
showSearch
|
|
504
|
-
initialValue="GEN"
|
|
505
|
-
rules={[{ required: true, message: 'Please select a user type' }]}
|
|
506
|
-
>
|
|
507
|
-
<Select options={getUserTypeOptions()} onChange={handleUserTypeChange} />
|
|
508
|
-
</Form.Item>
|
|
509
|
-
</Col>
|
|
510
|
-
<Col span={12}>
|
|
511
|
-
{/* username */}
|
|
512
|
-
<Form.Item name={'name'} label="Name" rules={[{ required: true, message: 'Please enter your user name' }]}>
|
|
513
|
-
<Input placeholder="Enter Name" autoFocus />
|
|
514
|
-
</Form.Item>
|
|
515
|
-
</Col>
|
|
516
|
-
<Col span={6}>
|
|
517
|
-
{' '}
|
|
518
|
-
{/* Show extra dropdown only if user type is Doctor */}
|
|
519
|
-
{userType === 'RAD' && (
|
|
520
|
-
<Form.Item
|
|
521
|
-
name="default_code"
|
|
522
|
-
preserve={false}
|
|
523
|
-
label="Default Code"
|
|
524
|
-
rules={[{ required: true, message: 'Please select a default code' }]}
|
|
525
|
-
>
|
|
526
|
-
<Select
|
|
527
|
-
placeholder="Select Code"
|
|
528
|
-
options={doctorList}
|
|
529
|
-
showSearch
|
|
530
|
-
optionFilterProp="label"
|
|
531
|
-
onChange={(value) => {
|
|
532
|
-
form.setFieldsValue({ default_code: value });
|
|
533
|
-
}}
|
|
534
|
-
dropdownRender={(menu) => (
|
|
535
|
-
<>
|
|
536
|
-
{menu}
|
|
537
|
-
<div
|
|
538
|
-
style={{
|
|
539
|
-
padding: '8px',
|
|
540
|
-
cursor: 'pointer',
|
|
541
|
-
borderTop: '1px solid #f0f0f0',
|
|
542
|
-
color: '#1890ff',
|
|
543
|
-
}}
|
|
544
|
-
onClick={() => setVisible(true)}
|
|
545
|
-
>
|
|
546
|
-
+ Add New Doctor
|
|
547
|
-
</div>
|
|
548
|
-
</>
|
|
549
|
-
)}
|
|
550
|
-
/>
|
|
551
|
-
{/* Render DoctorAdd OUTSIDE the Select */}
|
|
552
|
-
<DoctorAdd
|
|
553
|
-
visible={visible}
|
|
554
|
-
onCancel={() => setVisible(false)}
|
|
555
|
-
attributes={attributes}
|
|
556
|
-
doctorData={selectedDoctor}
|
|
557
|
-
doctorId={doctorID}
|
|
558
|
-
onSuccess={getDoctors}
|
|
559
|
-
/>
|
|
560
|
-
</Form.Item>
|
|
561
|
-
)}
|
|
562
|
-
{userType === 'STAFF' && (
|
|
563
|
-
<Form.Item
|
|
564
|
-
name="staff_code"
|
|
565
|
-
preserve={false} // THIS FIXES IT
|
|
566
|
-
label="Staff Code"
|
|
567
|
-
rules={[{ required: true, message: 'Please select a staff code' }]}
|
|
568
|
-
>
|
|
569
|
-
<Select
|
|
570
|
-
placeholder="Select Code"
|
|
571
|
-
options={staffList}
|
|
572
|
-
showSearch
|
|
573
|
-
optionFilterProp="label"
|
|
574
|
-
onChange={(value) => {
|
|
575
|
-
form.setFieldsValue({ staff_code: value });
|
|
576
|
-
}}
|
|
577
|
-
dropdownRender={(menu) => (
|
|
578
|
-
<>
|
|
579
|
-
{menu}
|
|
580
|
-
<div
|
|
581
|
-
style={{
|
|
582
|
-
padding: '8px',
|
|
583
|
-
cursor: 'pointer',
|
|
584
|
-
borderTop: '1px solid #f0f0f0',
|
|
585
|
-
color: '#1890ff',
|
|
586
|
-
}}
|
|
587
|
-
onClick={() => setVisible(true)}
|
|
588
|
-
>
|
|
589
|
-
+ Add New Staff
|
|
590
|
-
</div>
|
|
591
|
-
</>
|
|
592
|
-
)}
|
|
593
|
-
/>
|
|
594
|
-
{/* Render DoctorAdd OUTSIDE the Select */}
|
|
595
|
-
|
|
596
|
-
<StaffAdd visible={visible} onCancel={() => setVisible(false)} staffData={selectedStaff} staffId={staffID} onSuccess={getStaff} />
|
|
597
|
-
|
|
598
|
-
<></>
|
|
599
|
-
</Form.Item>
|
|
600
|
-
)}
|
|
601
|
-
</Col>
|
|
602
|
-
</Row>
|
|
603
|
-
<Row gutter={16}>
|
|
604
|
-
<Col span={8}>
|
|
605
|
-
{/* email */}
|
|
606
|
-
<Form.Item name={'email'} label="User Name / Email" rules={[{ required: true, message: 'Please enter your email' }]}>
|
|
607
|
-
<Input placeholder="Enter Email Address" />
|
|
608
|
-
</Form.Item>
|
|
609
|
-
</Col>
|
|
610
|
-
|
|
611
|
-
<Col span={8}>
|
|
612
|
-
{/* Mobile */}
|
|
613
|
-
<Form.Item
|
|
614
|
-
name="mobile"
|
|
615
|
-
label="Mobile"
|
|
616
|
-
rules={[
|
|
617
|
-
{ required: true, message: 'Please enter your mobile number' },
|
|
618
|
-
{
|
|
619
|
-
pattern: /^[0-9]{10}$/,
|
|
620
|
-
message: 'Mobile number must be exactly 10 digits',
|
|
621
|
-
},
|
|
622
|
-
]}
|
|
623
|
-
>
|
|
624
|
-
<Input
|
|
625
|
-
placeholder="Enter Mobile"
|
|
626
|
-
maxLength={10}
|
|
627
|
-
onKeyPress={(e) => {
|
|
628
|
-
if (!/[0-9]/.test(e.key)) {
|
|
629
|
-
e.preventDefault();
|
|
630
|
-
}
|
|
631
|
-
}}
|
|
632
|
-
/>
|
|
633
|
-
</Form.Item>
|
|
634
|
-
</Col>
|
|
635
|
-
<Col span={8}>
|
|
636
|
-
{/* Designation */}
|
|
637
|
-
<Form.Item name="designation" label="Designation">
|
|
638
|
-
<Select placeholder="Select Designation" options={designations} allowClear showSearch optionFilterProp="label" />
|
|
639
|
-
</Form.Item>
|
|
640
|
-
</Col>
|
|
641
|
-
</Row>
|
|
642
|
-
<Row gutter={16}>
|
|
643
|
-
{' '}
|
|
644
|
-
<Col span={8}>
|
|
645
|
-
{/* Department */}
|
|
646
|
-
<Form.Item name="department" label="Department">
|
|
647
|
-
<Select placeholder="Select Department" options={departments} allowClear showSearch optionFilterProp="label" />
|
|
648
|
-
</Form.Item>
|
|
649
|
-
</Col>
|
|
650
|
-
<Col span={8}>
|
|
651
|
-
{/* Branch */}
|
|
652
|
-
<Form.Item label="Branches" name="selectedBranches" rules={[{ required: true, message: 'Please select at least one branch' }]}>
|
|
653
|
-
<Select
|
|
654
|
-
mode="multiple"
|
|
655
|
-
placeholder="Select Branches"
|
|
656
|
-
options={branchOptions}
|
|
657
|
-
allowClear
|
|
658
|
-
showSearch
|
|
659
|
-
optionFilterProp="label"
|
|
660
|
-
onChange={(value) => {
|
|
661
|
-
const normalized = value.map(Number);
|
|
662
|
-
setSelectedBranches(normalized);
|
|
663
|
-
|
|
664
|
-
const currentDefault = form.getFieldValue('defaultBranch');
|
|
665
|
-
if (currentDefault && !normalized.includes(currentDefault)) {
|
|
666
|
-
form.setFieldsValue({ defaultBranch: undefined });
|
|
667
|
-
}
|
|
668
|
-
}}
|
|
669
|
-
/>
|
|
670
|
-
</Form.Item>
|
|
671
|
-
</Col>
|
|
672
|
-
<Col span={8}>
|
|
673
|
-
{/* Default Branch */}
|
|
674
|
-
<Form.Item label="Default Branch" name="defaultBranch" rules={[{ required: true, message: 'Please select default branch' }]}>
|
|
675
|
-
<Select placeholder="Select Default Branch">
|
|
676
|
-
{branchOptions
|
|
677
|
-
.filter((opt) => selectedBranches.includes(Number(opt.value)))
|
|
678
|
-
.map((opt) => (
|
|
679
|
-
<Option key={opt.value} value={Number(opt.value)}>
|
|
680
|
-
{opt.label}
|
|
681
|
-
</Option>
|
|
682
|
-
))}
|
|
683
|
-
</Select>
|
|
684
|
-
</Form.Item>
|
|
685
|
-
</Col>
|
|
686
|
-
</Row>
|
|
687
|
-
<Row gutter={16}>
|
|
688
|
-
<Col span={8}>
|
|
689
|
-
{formContent?.id ? (
|
|
690
|
-
<>
|
|
691
|
-
<Form.Item>
|
|
692
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
693
|
-
<Checkbox onChange={handleCheackChange} />
|
|
694
|
-
<span>Select the option if you want to change the password</span>
|
|
695
|
-
</div>
|
|
696
|
-
</Form.Item>
|
|
697
|
-
|
|
698
|
-
{isPasswordVisible && (
|
|
699
|
-
<Form.Item
|
|
700
|
-
name="password"
|
|
701
|
-
label="Password"
|
|
702
|
-
rules={[
|
|
703
|
-
{ required: true, message: 'Please enter your password' },
|
|
704
|
-
{ pattern: passwordRegex, message: passwordRegexMessage },
|
|
705
|
-
]}
|
|
706
|
-
>
|
|
707
|
-
<Input.Password placeholder="Enter password" autoComplete="new-password" />
|
|
708
|
-
</Form.Item>
|
|
709
|
-
)}
|
|
710
|
-
</>
|
|
711
|
-
) : (
|
|
712
|
-
<Form.Item
|
|
713
|
-
name="password"
|
|
714
|
-
label="Password"
|
|
715
|
-
rules={[
|
|
716
|
-
{
|
|
717
|
-
required: true,
|
|
718
|
-
message: 'Please enter your password',
|
|
719
|
-
},
|
|
720
|
-
{
|
|
721
|
-
pattern: new RegExp(passwordRegex),
|
|
722
|
-
message: passwordRegexMessage,
|
|
723
|
-
},
|
|
724
|
-
]}
|
|
725
|
-
>
|
|
726
|
-
<Input.Password visibilityToggle={false} placeholder="Enter password" autoComplete="new-password" />
|
|
727
|
-
</Form.Item>
|
|
728
|
-
)}
|
|
729
|
-
</Col>
|
|
730
|
-
{/* </Form.Item> */}
|
|
731
|
-
|
|
732
|
-
{/* Path */}
|
|
733
|
-
{/* <Form.Item name="password" label="Password"
|
|
734
|
-
rules={[
|
|
735
|
-
{
|
|
736
|
-
required: true,
|
|
737
|
-
message: 'Please enter your password',
|
|
738
|
-
},
|
|
739
|
-
{
|
|
740
|
-
pattern: new RegExp(passwordRegex),
|
|
741
|
-
message: passwordRegexMessage,
|
|
742
|
-
},
|
|
743
|
-
]}>
|
|
744
|
-
<Input.Password visibilityToggle={false} placeholder="Enter password" autoComplete='new-password' />
|
|
745
|
-
</Form.Item> */}
|
|
746
|
-
{/* Path Ends */}
|
|
747
|
-
|
|
748
|
-
{/* Path */}
|
|
749
|
-
<Col span={8}>
|
|
750
|
-
<Form.Item name="user_group" label="User Group" rules={[{ required: true, message: 'Please enter your user group' }]}>
|
|
751
|
-
<Input placeholder="Enter User Group" />
|
|
752
|
-
</Form.Item>
|
|
753
|
-
</Col>
|
|
754
|
-
{/* <Col span={8}>
|
|
755
|
-
<Form.Item name="role_id" label="Role" rules={[{ required: true, message: 'Please select a Role' }]}>
|
|
756
|
-
<Select placeholder="Select Role">
|
|
757
|
-
{roles.map((role) => (
|
|
758
|
-
<Option key={role.id} value={role.id}>
|
|
759
|
-
{role.name}
|
|
760
|
-
</Option>
|
|
761
|
-
))}
|
|
762
|
-
</Select>
|
|
763
|
-
</Form.Item>
|
|
764
|
-
</Col> */}
|
|
765
|
-
|
|
766
|
-
{/* <Form.Item name="mobile" label="Mobile" required={mobileRequired}>
|
|
767
|
-
<Input placeholder="Enter Mobile" />
|
|
768
|
-
</Form.Item> */}
|
|
769
|
-
|
|
770
|
-
{props?.ldap && (
|
|
771
|
-
<>
|
|
772
|
-
<Form.Item name="auth_type" label="auth_type">
|
|
773
|
-
<Input placeholder="Enter auth_type" value={'LDAP'} disabled />
|
|
774
|
-
|
|
775
|
-
{/* <Select
|
|
776
|
-
|
|
777
|
-
placeholder="Auth Type"
|
|
778
|
-
defaultValue={'LDAP'}
|
|
779
|
-
// value={formContent && formContent.auth_type?formContent.auth_type:'LDAP'}
|
|
780
|
-
allowClear
|
|
781
|
-
// style={{ width: '60%' }}
|
|
782
|
-
>
|
|
783
|
-
<Option value={props.user_type}>
|
|
784
|
-
{props.user_type}
|
|
785
|
-
</Option>
|
|
786
|
-
</Select> */}
|
|
787
|
-
|
|
788
|
-
{/* <div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
789
|
-
|
|
790
|
-
<div style={{ width: '40%' }}>
|
|
791
|
-
|
|
792
|
-
</div>
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
</div> */}
|
|
797
|
-
</Form.Item>
|
|
798
|
-
|
|
799
|
-
{/* Path */}
|
|
800
|
-
<Form.Item name="auth_user" label="User Name" required>
|
|
801
|
-
<Input placeholder="Enter User Name" />
|
|
802
|
-
</Form.Item>
|
|
803
|
-
</>
|
|
804
|
-
)}
|
|
805
|
-
</Row>
|
|
806
|
-
<Row gutter={16}>
|
|
807
|
-
<Col span={8}>
|
|
808
|
-
<Form.Item>
|
|
809
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
810
|
-
<Switch
|
|
811
|
-
disabled={disabled}
|
|
812
|
-
// defaultChecked={view}
|
|
813
|
-
onChange={changeView}
|
|
814
|
-
checked={authentication}
|
|
815
|
-
// disabled={disabled}
|
|
816
|
-
defaultChecked
|
|
817
|
-
// checkedChildren={<OrderedListOutlined />}
|
|
818
|
-
// unCheckedChildren={<PicCenterOutlined />}
|
|
819
|
-
/>
|
|
820
|
-
<span>Enable Two Factor Authentication</span>
|
|
821
|
-
</div>
|
|
822
|
-
</Form.Item>
|
|
823
|
-
</Col>
|
|
824
|
-
<Col span={8}>
|
|
825
|
-
{/* <label>User Status</label> */}
|
|
826
|
-
<Form.Item
|
|
827
|
-
name="active"
|
|
828
|
-
valuePropName="checked"
|
|
829
|
-
getValueFromEvent={(e) => (e.target.checked ? true : false)}
|
|
830
|
-
getValueProps={(value) => ({ checked: value === true })}
|
|
831
|
-
style={{ marginBottom: 0 }}
|
|
832
|
-
>
|
|
833
|
-
<Checkbox>Active</Checkbox>
|
|
834
|
-
</Form.Item>
|
|
835
|
-
</Col>
|
|
836
|
-
</Row>
|
|
837
|
-
{/* Path Ends */}
|
|
838
|
-
|
|
839
|
-
{/* Path */}
|
|
840
|
-
{/* <Form.Item name="active" label="Active" required>
|
|
841
|
-
<Switch />
|
|
842
|
-
</Form.Item> */}
|
|
843
|
-
{/* Path Ends */}
|
|
844
|
-
|
|
845
|
-
<Form.Item>
|
|
846
|
-
<Button loading={loading} htmlType={'submit'} type="primary">
|
|
847
|
-
Submit
|
|
848
|
-
</Button>
|
|
849
|
-
</Form.Item>
|
|
850
|
-
</Form>
|
|
851
|
-
)}
|
|
852
|
-
</section>
|
|
853
|
-
);
|
|
854
|
-
};
|
|
855
|
-
|
|
856
|
-
export default UserAdd;
|
|
1
|
+
import React, { useState, useEffect, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useLocation } from 'react-router-dom';
|
|
4
|
+
|
|
5
|
+
import { Skeleton, Typography, message, Switch, Form, Input, Select, Checkbox, Row, Col } from 'antd';
|
|
6
|
+
|
|
7
|
+
import AsyncSelect from 'react-select/async';
|
|
8
|
+
|
|
9
|
+
import { Table, Card, Button, JSONInput, GlobalContext, safeJSON } from './../../../../lib/';
|
|
10
|
+
|
|
11
|
+
import { ModelsAPI, PagesAPI, RolesAPI } from '../../..';
|
|
12
|
+
|
|
13
|
+
import { UsersAPI } from '../../..';
|
|
14
|
+
import DoctorAdd from '../../../doctor/components/doctor-add/doctor-add';
|
|
15
|
+
import StaffAdd from '../../../staff/components/staff-add/staff-add';
|
|
16
|
+
|
|
17
|
+
const { Title } = Typography;
|
|
18
|
+
|
|
19
|
+
const { Option } = Select;
|
|
20
|
+
|
|
21
|
+
const UserAdd = ({ model, callback, edit, history, formContent, match, additional_queries, props, mode = 'Add', attributes }) => {
|
|
22
|
+
/**Getting user data */
|
|
23
|
+
const { user = {} } = useContext(GlobalContext);
|
|
24
|
+
// let mode = 'Add';
|
|
25
|
+
|
|
26
|
+
const [disabled, setDisabled] = useState(true);
|
|
27
|
+
|
|
28
|
+
const [selectedOption, setSelectedOption] = useState(null);
|
|
29
|
+
// for selected branches
|
|
30
|
+
const [selectedBranches, setSelectedBranches] = useState([]);
|
|
31
|
+
|
|
32
|
+
// for default branch
|
|
33
|
+
// const [defaultBranch, setDefaultBranch] = useState(null);
|
|
34
|
+
//Need to check this condition
|
|
35
|
+
const [authentication, setAuthentication] = useState(false);
|
|
36
|
+
|
|
37
|
+
/**To store user values */
|
|
38
|
+
const [users, setUsers] = useState([]);
|
|
39
|
+
const [doctorID, setDoctorID] = useState(false);
|
|
40
|
+
const [selectedDoctor, setSelectedDoctor] = useState(null);
|
|
41
|
+
const [staffID, setStaffID] = useState(false);
|
|
42
|
+
const [selectedStaff, setSelectedStaff] = useState(null);
|
|
43
|
+
const [staffList, setStaffList] = useState([]);
|
|
44
|
+
/**Converting to JSON */
|
|
45
|
+
const firmDetails = safeJSON(user?.firm?.f_otherdetails1) ?? {};
|
|
46
|
+
|
|
47
|
+
/**Variable for cheaking mandatory condition of mobile*/
|
|
48
|
+
let mobileRequired;
|
|
49
|
+
|
|
50
|
+
/**If mode is mobile and fa is 'MND' or 'USR' then mobile is mandatory */
|
|
51
|
+
if (((firmDetails && firmDetails.FA === 'MND') || (firmDetails && firmDetails.FA === 'USR')) && firmDetails.mode === 'mobile') {
|
|
52
|
+
mobileRequired = true;
|
|
53
|
+
} else {
|
|
54
|
+
mobileRequired = false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (formContent?.id) {
|
|
58
|
+
mode = 'Edit';
|
|
59
|
+
} else if (formContent?.copy) {
|
|
60
|
+
mode = 'Copy';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (formContent?.attributes) {
|
|
64
|
+
if (typeof formContent.attributes === 'string') {
|
|
65
|
+
if (formContent.attributes !== '') {
|
|
66
|
+
formContent.attributes = JSON.parse(formContent.attributes);
|
|
67
|
+
} else {
|
|
68
|
+
if (formContent) {
|
|
69
|
+
formContent.attributes = {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
if (formContent) {
|
|
75
|
+
formContent.attributes = {};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const [loading, setLoading] = useState(true);
|
|
80
|
+
// user type state
|
|
81
|
+
const [userType, setUserType] = useState('general');
|
|
82
|
+
// state for branches list
|
|
83
|
+
const [branches, setBranches] = useState([]);
|
|
84
|
+
// designation list state
|
|
85
|
+
const [designations, setDesignations] = useState([]);
|
|
86
|
+
// department list state
|
|
87
|
+
const [departments, setDepartments] = useState([]);
|
|
88
|
+
// doctor list state
|
|
89
|
+
const [doctorList, setDoctorList] = useState([]);
|
|
90
|
+
// for role list
|
|
91
|
+
const [roles, setRoles] = useState([]);
|
|
92
|
+
|
|
93
|
+
const [form] = Form.useForm();
|
|
94
|
+
|
|
95
|
+
const [body, setBody] = useState(formContent);
|
|
96
|
+
|
|
97
|
+
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
98
|
+
const [visible, setVisible] = useState(false);
|
|
99
|
+
|
|
100
|
+
const formData = {
|
|
101
|
+
...body,
|
|
102
|
+
/**If panel is open then takes password in body */
|
|
103
|
+
password: !isPasswordVisible ? '' : body.password,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
let passwordRegex;
|
|
107
|
+
let passwordRegexMessage;
|
|
108
|
+
|
|
109
|
+
if (props && props?.passwordRegex && props?.passwordRegexMessage) {
|
|
110
|
+
passwordRegex = props.passwordRegex;
|
|
111
|
+
passwordRegexMessage = props.passwordRegexMessage;
|
|
112
|
+
} else if (process.env.REACT_APP_PASSWORD_REGEX && process.env.REACT_APP_PASSWORD_REGEX_MESSAGE) {
|
|
113
|
+
passwordRegex = process.env.REACT_APP_PASSWORD_REGEX;
|
|
114
|
+
passwordRegexMessage = process.env.REACT_APP_PASSWORD_REGEX_MESSAGE;
|
|
115
|
+
} else {
|
|
116
|
+
passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>])[A-Za-z\d!@#$%^&*(),.?":{}|<>]{8,}$/;
|
|
117
|
+
passwordRegexMessage =
|
|
118
|
+
'Password must be at least 8 characters long and contain atleast one uppercase letter, one lowercase letter, one digit and one special character';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (!loading && formContent) {
|
|
123
|
+
form.resetFields(); // clear previous values
|
|
124
|
+
form.setFieldsValue(formContent);
|
|
125
|
+
}
|
|
126
|
+
}, [loading, formContent]);
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (formContent?.auth_user) {
|
|
130
|
+
setSelectedOption({
|
|
131
|
+
value: formContent.auth_user,
|
|
132
|
+
label: formContent.auth_user, // Add a helper function to capitalize
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}, [formContent?.auth_user]);
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
loadUsers();
|
|
139
|
+
|
|
140
|
+
setLoading(false);
|
|
141
|
+
|
|
142
|
+
if (firmDetails) {
|
|
143
|
+
/**if firmmas.otherdetails - 2FA == MND, then, 2FA option will be enabled by default and read-only */
|
|
144
|
+
if (firmDetails.FA == 'MND') {
|
|
145
|
+
setAuthentication(true);
|
|
146
|
+
|
|
147
|
+
setDisabled(true);
|
|
148
|
+
|
|
149
|
+
/**if firmmas.otherdetails - 2FA == OPT, then, 2FA option will be enabled by default and editable */
|
|
150
|
+
} else if (firmDetails.FA == 'USR') {
|
|
151
|
+
setAuthentication(true);
|
|
152
|
+
|
|
153
|
+
setDisabled(true);
|
|
154
|
+
|
|
155
|
+
/**if firmmas.otherdetails - 2FA == NAP, then, 2FA option will be disabled by default and read-only*/
|
|
156
|
+
} else if (firmDetails.FA == 'NAP') {
|
|
157
|
+
setAuthentication(false);
|
|
158
|
+
|
|
159
|
+
setDisabled(true);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}, []);
|
|
163
|
+
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (!loading && formContent?.role_id && roles.length > 0) {
|
|
166
|
+
const roleId = Number(formContent.role_id);
|
|
167
|
+
|
|
168
|
+
if (!Number.isNaN(roleId)) {
|
|
169
|
+
form.setFieldsValue({ role_id: roleId });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}, [loading, formContent, roles]);
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
*Define the options dynamically
|
|
176
|
+
*/
|
|
177
|
+
const getUserTypeOptions = () => [
|
|
178
|
+
{ label: 'General', value: 'GEN' },
|
|
179
|
+
{ label: 'Doctor', value: 'RAD' },
|
|
180
|
+
{ label: 'Radiographer', value: 'TECH' },
|
|
181
|
+
{ label: 'Staff', value: 'STAFF' },
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get Branch List
|
|
186
|
+
*/
|
|
187
|
+
const getBranches = () => {
|
|
188
|
+
setLoading(true);
|
|
189
|
+
UsersAPI.getBranches().then(async (result) => {
|
|
190
|
+
const details = await result.result.map((ele) => {
|
|
191
|
+
return {
|
|
192
|
+
...ele,
|
|
193
|
+
...(ele.br_otherdet1 ? JSON.parse(ele.br_otherdet1) : {}),
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
setBranches(details);
|
|
197
|
+
setLoading(false);
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/** Get Designation List */
|
|
202
|
+
const getDesignations = () => {
|
|
203
|
+
setLoading(true);
|
|
204
|
+
UsersAPI.getDesignations()
|
|
205
|
+
.then((result) => {
|
|
206
|
+
if (result?.success && Array.isArray(result.result)) {
|
|
207
|
+
const details = result.result.map((ele) => ({
|
|
208
|
+
label: ele.dg_desc?.trim() || '',
|
|
209
|
+
value: ele.dg_code,
|
|
210
|
+
}));
|
|
211
|
+
setDesignations(details);
|
|
212
|
+
} else {
|
|
213
|
+
setDesignations([]);
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
.catch((error) => {
|
|
217
|
+
setDesignations([]);
|
|
218
|
+
})
|
|
219
|
+
.finally(() => setLoading(false));
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* get role lists
|
|
224
|
+
*/
|
|
225
|
+
function getRoles() {
|
|
226
|
+
RolesAPI.getRole()
|
|
227
|
+
.then((res) => {
|
|
228
|
+
const activeRoles = Array.isArray(res.result) ? res.result.filter((r) => r.active === 'Y') : [];
|
|
229
|
+
setRoles(activeRoles);
|
|
230
|
+
})
|
|
231
|
+
.catch(() => setRoles([]));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** Get Department List */
|
|
235
|
+
const getDepartments = () => {
|
|
236
|
+
setLoading(true);
|
|
237
|
+
UsersAPI.getDepartments()
|
|
238
|
+
.then((result) => {
|
|
239
|
+
if (result?.success && Array.isArray(result.result)) {
|
|
240
|
+
const details = result.result.map((ele) => ({
|
|
241
|
+
label: ele.dp_desc?.trim() || '',
|
|
242
|
+
value: ele.dp_id,
|
|
243
|
+
}));
|
|
244
|
+
setDepartments(details);
|
|
245
|
+
} else {
|
|
246
|
+
setDepartments([]);
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
.catch((error) => {
|
|
250
|
+
setDepartments([]);
|
|
251
|
+
})
|
|
252
|
+
.finally(() => setLoading(false));
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/** Get Doctor List */
|
|
256
|
+
const getDoctors = () => {
|
|
257
|
+
UsersAPI.getDoctors()
|
|
258
|
+
.then((res) => {
|
|
259
|
+
if (res?.success && Array.isArray(res.result)) {
|
|
260
|
+
const list = res.result.map((doc) => ({
|
|
261
|
+
label: `${doc.do_name} (${doc.do_code})`,
|
|
262
|
+
value: doc.do_code,
|
|
263
|
+
}));
|
|
264
|
+
setDoctorList(list);
|
|
265
|
+
}
|
|
266
|
+
})
|
|
267
|
+
.catch((err) => console.error('Doctor API Error:', err));
|
|
268
|
+
};
|
|
269
|
+
/** Get staff List */
|
|
270
|
+
const getStaff = () => {
|
|
271
|
+
UsersAPI.getAllStaff()
|
|
272
|
+
.then((res) => {
|
|
273
|
+
if (Array.isArray(res)) {
|
|
274
|
+
const list = res.map((staff) => ({
|
|
275
|
+
label: `${staff.shortName || 'No Name'} (${staff.id})`,
|
|
276
|
+
value: staff.id,
|
|
277
|
+
}));
|
|
278
|
+
|
|
279
|
+
setStaffList(list);
|
|
280
|
+
} else {
|
|
281
|
+
console.error('API did not return an array!');
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
.catch((err) => console.error('staff API Error:', err));
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// Function to handle user type change
|
|
288
|
+
const handleUserTypeChange = (value) => {
|
|
289
|
+
setUserType(value);
|
|
290
|
+
|
|
291
|
+
if (value === 'RAD') {
|
|
292
|
+
getDoctors(); // load doctor list
|
|
293
|
+
} else {
|
|
294
|
+
form.setFieldsValue({ default_code: undefined });
|
|
295
|
+
}
|
|
296
|
+
if (value === 'STAFF') {
|
|
297
|
+
getStaff(); // load staff list
|
|
298
|
+
} else {
|
|
299
|
+
form.setFieldsValue({ staff_code: undefined });
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
getBranches();
|
|
305
|
+
getDesignations();
|
|
306
|
+
getDepartments();
|
|
307
|
+
getRoles();
|
|
308
|
+
getDoctors(); // load doctor list
|
|
309
|
+
getStaff();
|
|
310
|
+
}, []);
|
|
311
|
+
|
|
312
|
+
useEffect(() => {
|
|
313
|
+
if (formContent && formContent.user_type) {
|
|
314
|
+
form.setFieldsValue({ user_type: formContent.user_type });
|
|
315
|
+
setUserType(formContent.user_type);
|
|
316
|
+
|
|
317
|
+
if (formContent.user_type === 'RAD' && formContent.doctor_code) {
|
|
318
|
+
form.setFieldsValue({ default_code: formContent.doctor_code });
|
|
319
|
+
}
|
|
320
|
+
if (formContent.user_type === 'STAFF' && formContent.staff_code) {
|
|
321
|
+
form.setFieldsValue({ staff_code: formContent.staff_code });
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (!formContent) return;
|
|
325
|
+
|
|
326
|
+
const org =
|
|
327
|
+
typeof formContent.organization_details === 'string' ? JSON.parse(formContent.organization_details) : formContent.organization_details;
|
|
328
|
+
|
|
329
|
+
// normalize branch ids to NUMBER
|
|
330
|
+
const branchIds = (org?.branch_ids || []).map(Number);
|
|
331
|
+
|
|
332
|
+
// find default branch pointer
|
|
333
|
+
const defaultBranchObj = org?.branch?.find((br) => br.defaultBranch);
|
|
334
|
+
|
|
335
|
+
// extract dbPtr (branch code)
|
|
336
|
+
const defaultBranchCode = defaultBranchObj?.branch_id ? Number(defaultBranchObj.branch_id) : undefined;
|
|
337
|
+
|
|
338
|
+
// state (for filtering)
|
|
339
|
+
setSelectedBranches(branchIds);
|
|
340
|
+
|
|
341
|
+
// form values
|
|
342
|
+
form.setFieldsValue({
|
|
343
|
+
selectedBranches: branchIds,
|
|
344
|
+
defaultBranch: defaultBranchCode,
|
|
345
|
+
});
|
|
346
|
+
}, [formContent, form]);
|
|
347
|
+
// Generate branch options for Select component
|
|
348
|
+
const branchOptions = branches.map((branch) => ({
|
|
349
|
+
label: branch.br_desc,
|
|
350
|
+
value: branch.br_code,
|
|
351
|
+
}));
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Submit values
|
|
355
|
+
*/
|
|
356
|
+
const onSubmit = (values) => {
|
|
357
|
+
values.defaultBranch = String(values.defaultBranch);
|
|
358
|
+
|
|
359
|
+
/**If PanelOpen is open and edit mode then password will be existing password else new password*/
|
|
360
|
+
if (!isPasswordVisible && mode === 'Edit') {
|
|
361
|
+
values.password = body.password;
|
|
362
|
+
}
|
|
363
|
+
values.user_type = values.user_type;
|
|
364
|
+
|
|
365
|
+
if (values.user_type === 'RAD') {
|
|
366
|
+
values.doctor_code = values.default_code;
|
|
367
|
+
} else {
|
|
368
|
+
values.doctor_code = null;
|
|
369
|
+
}
|
|
370
|
+
if (values.user_type === 'STAFF') {
|
|
371
|
+
values.staff_code = values.staff_code;
|
|
372
|
+
} else {
|
|
373
|
+
values.staff_code = null;
|
|
374
|
+
}
|
|
375
|
+
values = {
|
|
376
|
+
...values,
|
|
377
|
+
auth_type: 'LDAP',
|
|
378
|
+
FA: authentication,
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
setLoading(true);
|
|
382
|
+
|
|
383
|
+
let id = formContent?.id;
|
|
384
|
+
if (props?.ldap && selectedOption && selectedOption.value) {
|
|
385
|
+
values = {
|
|
386
|
+
...values,
|
|
387
|
+
|
|
388
|
+
addAllBranches: props.ldap.addAllBranches,
|
|
389
|
+
auth_user: selectedOption.value,
|
|
390
|
+
auth_type: 'LDAP',
|
|
391
|
+
FA: authentication,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (values.attributes && typeof values === 'object') {
|
|
396
|
+
values = {
|
|
397
|
+
...values,
|
|
398
|
+
|
|
399
|
+
auth_type: 'LDAP',
|
|
400
|
+
|
|
401
|
+
attributes: JSON.stringify(values.attributes),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (id) {
|
|
406
|
+
// Update of model
|
|
407
|
+
|
|
408
|
+
UsersAPI.updateUser({ id, formBody: values }).then((result) => {
|
|
409
|
+
if (result.success) message.success(result.message);
|
|
410
|
+
else message.error(result.message);
|
|
411
|
+
|
|
412
|
+
setLoading(false);
|
|
413
|
+
|
|
414
|
+
callback();
|
|
415
|
+
});
|
|
416
|
+
} else {
|
|
417
|
+
// Append the additional queries to the object
|
|
418
|
+
// additional_queries.forEach(({ field, value }) => {
|
|
419
|
+
// values[field] = value;
|
|
420
|
+
// });
|
|
421
|
+
if (Array.isArray(additional_queries)) {
|
|
422
|
+
additional_queries.forEach(({ field, value }) => {
|
|
423
|
+
values[field] = value;
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// add new model
|
|
428
|
+
UsersAPI.create(values).then((result) => {
|
|
429
|
+
setLoading(false);
|
|
430
|
+
|
|
431
|
+
if (result.success) {
|
|
432
|
+
message.success(result.message);
|
|
433
|
+
// close modal
|
|
434
|
+
callback();
|
|
435
|
+
} else {
|
|
436
|
+
message.error(result.message);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Function on handle change
|
|
444
|
+
* @param {*} selected
|
|
445
|
+
*/
|
|
446
|
+
const handleCheackChange = (e) => {
|
|
447
|
+
setIsPasswordVisible(e.target.checked);
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
function changeView(result) {
|
|
451
|
+
setAuthentication(result);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Function to add load userrs
|
|
456
|
+
*/
|
|
457
|
+
function loadUsers() {
|
|
458
|
+
// UsersAPI.getLdapUsers().then((result) => {
|
|
459
|
+
// setUsers(result.result);
|
|
460
|
+
// });
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Transform array into react-select options
|
|
464
|
+
let options = users.map((item) => ({
|
|
465
|
+
value: item.name,
|
|
466
|
+
label: item.name, // Capitalize the first letter
|
|
467
|
+
}));
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Function on handle change
|
|
471
|
+
* @param {*} selected
|
|
472
|
+
*/
|
|
473
|
+
const handleChange = (selected) => {
|
|
474
|
+
setSelectedOption(selected);
|
|
475
|
+
};
|
|
476
|
+
/**
|
|
477
|
+
*
|
|
478
|
+
* @param {*} inputValue
|
|
479
|
+
* @param {*} callback
|
|
480
|
+
*/
|
|
481
|
+
|
|
482
|
+
const loadOptions = (inputValue, callback) => {
|
|
483
|
+
// Filter options based on input
|
|
484
|
+
const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
|
|
485
|
+
callback(filteredOptions);
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
return (
|
|
489
|
+
<section className="collection-add">
|
|
490
|
+
<Title level={4}>{mode} User</Title>
|
|
491
|
+
|
|
492
|
+
{loading ? (
|
|
493
|
+
<Skeleton />
|
|
494
|
+
) : (
|
|
495
|
+
<Form initialValues={formData} form={form} layout="vertical" onFinish={onSubmit}>
|
|
496
|
+
{/* user type */}
|
|
497
|
+
<Row gutter={16}>
|
|
498
|
+
<Col span={6}>
|
|
499
|
+
<Form.Item
|
|
500
|
+
name="user_type"
|
|
501
|
+
label="User Type"
|
|
502
|
+
allowClear
|
|
503
|
+
showSearch
|
|
504
|
+
initialValue="GEN"
|
|
505
|
+
rules={[{ required: true, message: 'Please select a user type' }]}
|
|
506
|
+
>
|
|
507
|
+
<Select options={getUserTypeOptions()} onChange={handleUserTypeChange} />
|
|
508
|
+
</Form.Item>
|
|
509
|
+
</Col>
|
|
510
|
+
<Col span={12}>
|
|
511
|
+
{/* username */}
|
|
512
|
+
<Form.Item name={'name'} label="Name" rules={[{ required: true, message: 'Please enter your user name' }]}>
|
|
513
|
+
<Input placeholder="Enter Name" autoFocus />
|
|
514
|
+
</Form.Item>
|
|
515
|
+
</Col>
|
|
516
|
+
<Col span={6}>
|
|
517
|
+
{' '}
|
|
518
|
+
{/* Show extra dropdown only if user type is Doctor */}
|
|
519
|
+
{userType === 'RAD' && (
|
|
520
|
+
<Form.Item
|
|
521
|
+
name="default_code"
|
|
522
|
+
preserve={false}
|
|
523
|
+
label="Default Code"
|
|
524
|
+
rules={[{ required: true, message: 'Please select a default code' }]}
|
|
525
|
+
>
|
|
526
|
+
<Select
|
|
527
|
+
placeholder="Select Code"
|
|
528
|
+
options={doctorList}
|
|
529
|
+
showSearch
|
|
530
|
+
optionFilterProp="label"
|
|
531
|
+
onChange={(value) => {
|
|
532
|
+
form.setFieldsValue({ default_code: value });
|
|
533
|
+
}}
|
|
534
|
+
dropdownRender={(menu) => (
|
|
535
|
+
<>
|
|
536
|
+
{menu}
|
|
537
|
+
<div
|
|
538
|
+
style={{
|
|
539
|
+
padding: '8px',
|
|
540
|
+
cursor: 'pointer',
|
|
541
|
+
borderTop: '1px solid #f0f0f0',
|
|
542
|
+
color: '#1890ff',
|
|
543
|
+
}}
|
|
544
|
+
onClick={() => setVisible(true)}
|
|
545
|
+
>
|
|
546
|
+
+ Add New Doctor
|
|
547
|
+
</div>
|
|
548
|
+
</>
|
|
549
|
+
)}
|
|
550
|
+
/>
|
|
551
|
+
{/* Render DoctorAdd OUTSIDE the Select */}
|
|
552
|
+
<DoctorAdd
|
|
553
|
+
visible={visible}
|
|
554
|
+
onCancel={() => setVisible(false)}
|
|
555
|
+
attributes={attributes}
|
|
556
|
+
doctorData={selectedDoctor}
|
|
557
|
+
doctorId={doctorID}
|
|
558
|
+
onSuccess={getDoctors}
|
|
559
|
+
/>
|
|
560
|
+
</Form.Item>
|
|
561
|
+
)}
|
|
562
|
+
{userType === 'STAFF' && (
|
|
563
|
+
<Form.Item
|
|
564
|
+
name="staff_code"
|
|
565
|
+
preserve={false} // THIS FIXES IT
|
|
566
|
+
label="Staff Code"
|
|
567
|
+
rules={[{ required: true, message: 'Please select a staff code' }]}
|
|
568
|
+
>
|
|
569
|
+
<Select
|
|
570
|
+
placeholder="Select Code"
|
|
571
|
+
options={staffList}
|
|
572
|
+
showSearch
|
|
573
|
+
optionFilterProp="label"
|
|
574
|
+
onChange={(value) => {
|
|
575
|
+
form.setFieldsValue({ staff_code: value });
|
|
576
|
+
}}
|
|
577
|
+
dropdownRender={(menu) => (
|
|
578
|
+
<>
|
|
579
|
+
{menu}
|
|
580
|
+
<div
|
|
581
|
+
style={{
|
|
582
|
+
padding: '8px',
|
|
583
|
+
cursor: 'pointer',
|
|
584
|
+
borderTop: '1px solid #f0f0f0',
|
|
585
|
+
color: '#1890ff',
|
|
586
|
+
}}
|
|
587
|
+
onClick={() => setVisible(true)}
|
|
588
|
+
>
|
|
589
|
+
+ Add New Staff
|
|
590
|
+
</div>
|
|
591
|
+
</>
|
|
592
|
+
)}
|
|
593
|
+
/>
|
|
594
|
+
{/* Render DoctorAdd OUTSIDE the Select */}
|
|
595
|
+
|
|
596
|
+
<StaffAdd visible={visible} onCancel={() => setVisible(false)} staffData={selectedStaff} staffId={staffID} onSuccess={getStaff} />
|
|
597
|
+
|
|
598
|
+
<></>
|
|
599
|
+
</Form.Item>
|
|
600
|
+
)}
|
|
601
|
+
</Col>
|
|
602
|
+
</Row>
|
|
603
|
+
<Row gutter={16}>
|
|
604
|
+
<Col span={8}>
|
|
605
|
+
{/* email */}
|
|
606
|
+
<Form.Item name={'email'} label="User Name / Email" rules={[{ required: true, message: 'Please enter your email' }]}>
|
|
607
|
+
<Input placeholder="Enter Email Address" />
|
|
608
|
+
</Form.Item>
|
|
609
|
+
</Col>
|
|
610
|
+
|
|
611
|
+
<Col span={8}>
|
|
612
|
+
{/* Mobile */}
|
|
613
|
+
<Form.Item
|
|
614
|
+
name="mobile"
|
|
615
|
+
label="Mobile"
|
|
616
|
+
rules={[
|
|
617
|
+
{ required: true, message: 'Please enter your mobile number' },
|
|
618
|
+
{
|
|
619
|
+
pattern: /^[0-9]{10}$/,
|
|
620
|
+
message: 'Mobile number must be exactly 10 digits',
|
|
621
|
+
},
|
|
622
|
+
]}
|
|
623
|
+
>
|
|
624
|
+
<Input
|
|
625
|
+
placeholder="Enter Mobile"
|
|
626
|
+
maxLength={10}
|
|
627
|
+
onKeyPress={(e) => {
|
|
628
|
+
if (!/[0-9]/.test(e.key)) {
|
|
629
|
+
e.preventDefault();
|
|
630
|
+
}
|
|
631
|
+
}}
|
|
632
|
+
/>
|
|
633
|
+
</Form.Item>
|
|
634
|
+
</Col>
|
|
635
|
+
<Col span={8}>
|
|
636
|
+
{/* Designation */}
|
|
637
|
+
<Form.Item name="designation" label="Designation">
|
|
638
|
+
<Select placeholder="Select Designation" options={designations} allowClear showSearch optionFilterProp="label" />
|
|
639
|
+
</Form.Item>
|
|
640
|
+
</Col>
|
|
641
|
+
</Row>
|
|
642
|
+
<Row gutter={16}>
|
|
643
|
+
{' '}
|
|
644
|
+
<Col span={8}>
|
|
645
|
+
{/* Department */}
|
|
646
|
+
<Form.Item name="department" label="Department">
|
|
647
|
+
<Select placeholder="Select Department" options={departments} allowClear showSearch optionFilterProp="label" />
|
|
648
|
+
</Form.Item>
|
|
649
|
+
</Col>
|
|
650
|
+
<Col span={8}>
|
|
651
|
+
{/* Branch */}
|
|
652
|
+
<Form.Item label="Branches" name="selectedBranches" rules={[{ required: true, message: 'Please select at least one branch' }]}>
|
|
653
|
+
<Select
|
|
654
|
+
mode="multiple"
|
|
655
|
+
placeholder="Select Branches"
|
|
656
|
+
options={branchOptions}
|
|
657
|
+
allowClear
|
|
658
|
+
showSearch
|
|
659
|
+
optionFilterProp="label"
|
|
660
|
+
onChange={(value) => {
|
|
661
|
+
const normalized = value.map(Number);
|
|
662
|
+
setSelectedBranches(normalized);
|
|
663
|
+
|
|
664
|
+
const currentDefault = form.getFieldValue('defaultBranch');
|
|
665
|
+
if (currentDefault && !normalized.includes(currentDefault)) {
|
|
666
|
+
form.setFieldsValue({ defaultBranch: undefined });
|
|
667
|
+
}
|
|
668
|
+
}}
|
|
669
|
+
/>
|
|
670
|
+
</Form.Item>
|
|
671
|
+
</Col>
|
|
672
|
+
<Col span={8}>
|
|
673
|
+
{/* Default Branch */}
|
|
674
|
+
<Form.Item label="Default Branch" name="defaultBranch" rules={[{ required: true, message: 'Please select default branch' }]}>
|
|
675
|
+
<Select placeholder="Select Default Branch">
|
|
676
|
+
{branchOptions
|
|
677
|
+
.filter((opt) => selectedBranches.includes(Number(opt.value)))
|
|
678
|
+
.map((opt) => (
|
|
679
|
+
<Option key={opt.value} value={Number(opt.value)}>
|
|
680
|
+
{opt.label}
|
|
681
|
+
</Option>
|
|
682
|
+
))}
|
|
683
|
+
</Select>
|
|
684
|
+
</Form.Item>
|
|
685
|
+
</Col>
|
|
686
|
+
</Row>
|
|
687
|
+
<Row gutter={16}>
|
|
688
|
+
<Col span={8}>
|
|
689
|
+
{formContent?.id ? (
|
|
690
|
+
<>
|
|
691
|
+
<Form.Item>
|
|
692
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
693
|
+
<Checkbox onChange={handleCheackChange} />
|
|
694
|
+
<span>Select the option if you want to change the password</span>
|
|
695
|
+
</div>
|
|
696
|
+
</Form.Item>
|
|
697
|
+
|
|
698
|
+
{isPasswordVisible && (
|
|
699
|
+
<Form.Item
|
|
700
|
+
name="password"
|
|
701
|
+
label="Password"
|
|
702
|
+
rules={[
|
|
703
|
+
{ required: true, message: 'Please enter your password' },
|
|
704
|
+
{ pattern: passwordRegex, message: passwordRegexMessage },
|
|
705
|
+
]}
|
|
706
|
+
>
|
|
707
|
+
<Input.Password placeholder="Enter password" autoComplete="new-password" />
|
|
708
|
+
</Form.Item>
|
|
709
|
+
)}
|
|
710
|
+
</>
|
|
711
|
+
) : (
|
|
712
|
+
<Form.Item
|
|
713
|
+
name="password"
|
|
714
|
+
label="Password"
|
|
715
|
+
rules={[
|
|
716
|
+
{
|
|
717
|
+
required: true,
|
|
718
|
+
message: 'Please enter your password',
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
pattern: new RegExp(passwordRegex),
|
|
722
|
+
message: passwordRegexMessage,
|
|
723
|
+
},
|
|
724
|
+
]}
|
|
725
|
+
>
|
|
726
|
+
<Input.Password visibilityToggle={false} placeholder="Enter password" autoComplete="new-password" />
|
|
727
|
+
</Form.Item>
|
|
728
|
+
)}
|
|
729
|
+
</Col>
|
|
730
|
+
{/* </Form.Item> */}
|
|
731
|
+
|
|
732
|
+
{/* Path */}
|
|
733
|
+
{/* <Form.Item name="password" label="Password"
|
|
734
|
+
rules={[
|
|
735
|
+
{
|
|
736
|
+
required: true,
|
|
737
|
+
message: 'Please enter your password',
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
pattern: new RegExp(passwordRegex),
|
|
741
|
+
message: passwordRegexMessage,
|
|
742
|
+
},
|
|
743
|
+
]}>
|
|
744
|
+
<Input.Password visibilityToggle={false} placeholder="Enter password" autoComplete='new-password' />
|
|
745
|
+
</Form.Item> */}
|
|
746
|
+
{/* Path Ends */}
|
|
747
|
+
|
|
748
|
+
{/* Path */}
|
|
749
|
+
<Col span={8}>
|
|
750
|
+
<Form.Item name="user_group" label="User Group" rules={[{ required: true, message: 'Please enter your user group' }]}>
|
|
751
|
+
<Input placeholder="Enter User Group" />
|
|
752
|
+
</Form.Item>
|
|
753
|
+
</Col>
|
|
754
|
+
{/* <Col span={8}>
|
|
755
|
+
<Form.Item name="role_id" label="Role" rules={[{ required: true, message: 'Please select a Role' }]}>
|
|
756
|
+
<Select placeholder="Select Role">
|
|
757
|
+
{roles.map((role) => (
|
|
758
|
+
<Option key={role.id} value={role.id}>
|
|
759
|
+
{role.name}
|
|
760
|
+
</Option>
|
|
761
|
+
))}
|
|
762
|
+
</Select>
|
|
763
|
+
</Form.Item>
|
|
764
|
+
</Col> */}
|
|
765
|
+
|
|
766
|
+
{/* <Form.Item name="mobile" label="Mobile" required={mobileRequired}>
|
|
767
|
+
<Input placeholder="Enter Mobile" />
|
|
768
|
+
</Form.Item> */}
|
|
769
|
+
|
|
770
|
+
{props?.ldap && (
|
|
771
|
+
<>
|
|
772
|
+
<Form.Item name="auth_type" label="auth_type">
|
|
773
|
+
<Input placeholder="Enter auth_type" value={'LDAP'} disabled />
|
|
774
|
+
|
|
775
|
+
{/* <Select
|
|
776
|
+
|
|
777
|
+
placeholder="Auth Type"
|
|
778
|
+
defaultValue={'LDAP'}
|
|
779
|
+
// value={formContent && formContent.auth_type?formContent.auth_type:'LDAP'}
|
|
780
|
+
allowClear
|
|
781
|
+
// style={{ width: '60%' }}
|
|
782
|
+
>
|
|
783
|
+
<Option value={props.user_type}>
|
|
784
|
+
{props.user_type}
|
|
785
|
+
</Option>
|
|
786
|
+
</Select> */}
|
|
787
|
+
|
|
788
|
+
{/* <div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
789
|
+
|
|
790
|
+
<div style={{ width: '40%' }}>
|
|
791
|
+
|
|
792
|
+
</div>
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
</div> */}
|
|
797
|
+
</Form.Item>
|
|
798
|
+
|
|
799
|
+
{/* Path */}
|
|
800
|
+
<Form.Item name="auth_user" label="User Name" required>
|
|
801
|
+
<Input placeholder="Enter User Name" />
|
|
802
|
+
</Form.Item>
|
|
803
|
+
</>
|
|
804
|
+
)}
|
|
805
|
+
</Row>
|
|
806
|
+
<Row gutter={16}>
|
|
807
|
+
<Col span={8}>
|
|
808
|
+
<Form.Item>
|
|
809
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
810
|
+
<Switch
|
|
811
|
+
disabled={disabled}
|
|
812
|
+
// defaultChecked={view}
|
|
813
|
+
onChange={changeView}
|
|
814
|
+
checked={authentication}
|
|
815
|
+
// disabled={disabled}
|
|
816
|
+
defaultChecked
|
|
817
|
+
// checkedChildren={<OrderedListOutlined />}
|
|
818
|
+
// unCheckedChildren={<PicCenterOutlined />}
|
|
819
|
+
/>
|
|
820
|
+
<span>Enable Two Factor Authentication</span>
|
|
821
|
+
</div>
|
|
822
|
+
</Form.Item>
|
|
823
|
+
</Col>
|
|
824
|
+
<Col span={8}>
|
|
825
|
+
{/* <label>User Status</label> */}
|
|
826
|
+
<Form.Item
|
|
827
|
+
name="active"
|
|
828
|
+
valuePropName="checked"
|
|
829
|
+
getValueFromEvent={(e) => (e.target.checked ? true : false)}
|
|
830
|
+
getValueProps={(value) => ({ checked: value === true })}
|
|
831
|
+
style={{ marginBottom: 0 }}
|
|
832
|
+
>
|
|
833
|
+
<Checkbox>Active</Checkbox>
|
|
834
|
+
</Form.Item>
|
|
835
|
+
</Col>
|
|
836
|
+
</Row>
|
|
837
|
+
{/* Path Ends */}
|
|
838
|
+
|
|
839
|
+
{/* Path */}
|
|
840
|
+
{/* <Form.Item name="active" label="Active" required>
|
|
841
|
+
<Switch />
|
|
842
|
+
</Form.Item> */}
|
|
843
|
+
{/* Path Ends */}
|
|
844
|
+
|
|
845
|
+
<Form.Item>
|
|
846
|
+
<Button loading={loading} htmlType={'submit'} type="primary">
|
|
847
|
+
Submit
|
|
848
|
+
</Button>
|
|
849
|
+
</Form.Item>
|
|
850
|
+
</Form>
|
|
851
|
+
)}
|
|
852
|
+
</section>
|
|
853
|
+
);
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
export default UserAdd;
|