From 6ce776f218bfa9a9bfd342c5264016babacdd59a Mon Sep 17 00:00:00 2001 From: arfat qureshi Date: Wed, 29 Oct 2025 11:44:13 +0530 Subject: [PATCH] first commit --- .browserslistrc | 15 + .editorconfig | 16 + .gitignore | 46 + .vs/ProjectSettings.json | 3 + .vs/VSWorkspaceState.json | 8 + ...e6c2de4a-47b3-4d86-9723-4f2f8b582011.vsidx | Bin 0 -> 1045994 bytes .vs/extranet_ui_ng/FileContentIndex/read.lock | 0 .vs/extranet_ui_ng/v17/.suo | Bin 0 -> 19968 bytes .vs/slnx.sqlite | Bin 0 -> 237568 bytes Dockerfile | 16 + angular.json | 266 + azure-pipelines-dev.yaml | 114 + azure-pipelines-preprod.yaml | 89 + azure-pipelines-prod.yaml | 89 + azure-pipelines-uat.yaml | 85 + karma.conf.js | 44 + kustomize/base/deployment.yaml | 53 + kustomize/base/hpa.yaml | 12 + kustomize/base/kustomization.yaml | 10 + kustomize/base/service.yaml | 15 + kustomize/manifests/dev.yaml | 82 + kustomize/manifests/preprod/preprod.yaml | 82 + kustomize/manifests/prod/prod.yaml | 82 + kustomize/manifests/uat/uat.yaml | 82 + kustomize/overlays/dev/hpa.yaml | 12 + kustomize/overlays/dev/kustomization.yaml | 11 + .../overlays/pre-prod/kustomization.yaml | 0 kustomize/overlays/prod/kustomization.yaml | 0 kustomize/overlays/uat/kustomization.yaml | 0 nginx.conf | 14 + package-lock.json | 13987 ++++++++++++++++ package.json | 71 + preprod.Dockerfile | 16 + prod.Dockerfile | 16 + readme.md | 20 + src/app/app-routing.module.ts | 22 + src/app/app.component.html | 67 + src/app/app.component.ts | 108 + src/app/app.module.ts | 42 + .../core/common/RouteChangeService.service.ts | 51 + .../core/common/common-function.service.ts | 657 + .../core/common/intercept-loader.service.ts | 264 + src/app/core/common/loader.service.ts | 11 + src/app/core/common/security.ts | 154 + src/app/core/common/static-data.service.ts | 269 + src/app/core/common/validation.service.ts | 156 + src/app/core/guard/auth.guard.ts | 43 + .../experience-manage-lang.model.ts | 27 + .../edit-allocation/edit-allocation.model.ts | 31 + .../edit-cancellation-policy.model.ts | 30 + .../edit-details/edit-deatils.model.ts | 16 + .../edit-rate-confi/edit-rate-confi.model.ts | 80 + .../experience-rate-config.model.ts | 157 + .../experience-service-add.model.ts | 88 + .../season-setting-add.model.ts | 23 + .../slot/add-slots-model.ts | 24 + .../core/models/common-model/Sign-in.model.ts | 58 + .../models/common-model/user-logout.model.ts | 11 + src/app/core/models/common-model/userModel.ts | 66 + .../flight-service/flight-contracts.model.ts | 221 + .../edit-Rate-inventry.model.ts | 44 + .../edit-contract-details.model.ts | 13 + .../edit-flight-details.model.ts | 24 + .../flight-service-search.model.ts | 25 + .../models/hotelService/AddRoom/Room.model.ts | 73 + .../OverViewData/RoomsOverView.model.ts | 34 + .../Tab-Content/tab-4/Tab-4.model.ts | 28 + .../models/optional-ons/optional-ons.model.ts | 43 + .../user-role-management/user-role.model.ts | 61 + .../hotel_booking_management.service.ts | 101 + .../HotelServices/manage-hotel.service.ts | 11 + .../AddRoomService/Add-Room.service.ts | 54 + .../tab-content/tab-3/RoomContract.service.ts | 25 + .../tab-content/tab-4/tab-4.service.ts | 32 + .../core/services/active-sidebar.service.ts | 46 + src/app/core/services/api.service.ts | 123 + src/app/core/services/breakpoints.services.ts | 38 + src/app/core/services/common.service.ts | 58 + src/app/core/services/event-utils.ts | 27 + .../core/services/events.calender.service.ts | 0 .../flight-contract.service.ts | 133 + src/app/core/services/node.service.ts | 21 + src/app/core/services/nodeservice.ts | 787 + src/app/core/services/product.service.ts | 113 + src/app/core/services/product.ts | 12 + src/app/core/services/sso.service.ts | 109 + .../intercept-loader.component.html | 14 + .../intercept-loader.component.ts | 23 + src/app/core/shared/shared.module.ts | 13 + src/app/layouts/base/base.component.html | 19 + src/app/layouts/base/base.component.ts | 34 + .../loader/loader.component.html | 13 + .../loader/loader.component.ts | 22 + src/app/layouts/pages-routing.module.ts | 68 + src/app/layouts/theme.module.ts | 51 + .../unauthorized/unauthorized.component.html | 59 + .../unauthorized/unauthorized.component.ts | 16 + src/app/modules/auth/auth.component.html | 0 src/app/modules/auth/auth.component.ts | 14 + src/app/modules/auth/auth.module.ts | 63 + .../forget-password.component.html | 89 + .../forget-password.component.ts | 88 + .../modules/auth/login/login.component.html | 239 + src/app/modules/auth/login/login.component.ts | 578 + .../single-sign-on.component.html | 1 + .../single-sign-on.component.ts | 26 + .../verify-email/verify-email.component.html | 34 + .../verify-email/verify-email.component.ts | 53 + .../booking-management.component.html | 1 + .../booking-management.component.ts | 11 + .../booking-management.module.ts | 33 + .../experience-booking-search.component.html | 1 + .../experience-booking-search.component.ts | 14 + .../experience-booking.component.html | 1 + .../experience-booking.component.ts | 14 + .../experience-booking.module.ts | 22 + .../hotel-booking-search.component.html | 672 + .../hotel-booking-search.component.ts | 560 + .../hotel-booking-view.component.html | 594 + .../hotel-booking-view.component.ts | 1243 ++ .../hotel-booking.component.html | 1 + .../hotel-booking/hotel-booking.component.ts | 14 + .../hotel-booking/hotel-booking.module.ts | 73 + .../custom-sidebar-item.component.html | 20 + .../custom-sidebar-item.component.ts | 38 + .../custom-sidebar.component.html | 48 + .../custom-sidebar.component.ts | 212 + .../common/footer/footer.component.html | 7 + .../modules/common/footer/footer.component.ts | 24 + .../common/header/header.component.html | 119 + .../modules/common/header/header.component.ts | 127 + .../common/sidebar/sidebar.component.html | 37 + .../common/sidebar/sidebar.component.ts | 193 + .../activity-add-on-add.component.html | 231 + .../activity-add-on-add.component.ts | 244 + .../activity-add-on-edit.component.html | 1 + .../activity-add-on-edit.component.ts | 9 + .../activity-add-on-language.component.html | 124 + .../activity-add-on-language.component.ts | 125 + .../activity-add-on-search.component.html | 128 + .../activity-add-on-search.component.ts | 95 + .../activity-add-on/activity-add-on.module.ts | 66 + .../activity-category-add.component.html | 78 + .../activity-category-add.component.ts | 107 + .../activity-category-edit.component.html | 1 + .../activity-category-edit.component.ts | 9 + .../activity-category-language.component.html | 89 + .../activity-category-language.component.ts | 9 + .../activity-category-search.component.html | 175 + .../activity-category-search.component.ts | 101 + .../activity-category.module.ts | 66 + .../activity-config/activity-config.module.ts | 44 + .../hotel-zone-add.component.html | 230 + .../hotel-zone-add.component.ts | 223 + .../hotel-zone-edit.component.html | 1 + .../hotel-zone-edit.component.ts | 9 + .../hotel-zone-search.component.html | 227 + .../hotel-zone-search.component.ts | 173 + .../hotel-zone/hotel-zone.module.ts | 67 + .../vehicle-master-add.component.html | 268 + .../vehicle-master-add.component.ts | 252 + .../vehicle-master-language.component.html | 109 + .../vehicle-master-language.component.ts | 111 + .../vehicle-master-search.component.html | 234 + .../vehicle-master-search.component.ts | 102 + .../vehicle-master/vehicle-master.module.ts | 66 + .../activity-services.module.ts | 31 + .../exp-manage-translation.component.html | 236 + .../exp-manage-translation.component.ts | 196 + .../exp-services-add.component.html | 802 + .../exp-services-add.component.ts | 971 ++ .../exp-services-manage.component.html | 2 + .../exp-services-manage.component.ts | 11 + .../exp-services-manage.module.ts | 163 + .../Overview/Overview.component.html | 549 + .../Overview/Overview.component.ts | 616 + .../add-optional-add-on.component.html | 145 + .../add-optional-add-on.component.ts | 225 + .../optional-addOns.component.html | 130 + .../optional-addOns.component.ts | 118 + .../add-rate-config.component.html | 1120 ++ .../add-rate-config.component.ts | 1206 ++ .../edit-allocation.component.html | 137 + .../edit-allocation.component.ts | 410 + .../edit-cancelletion-policy.component.html | 161 + .../edit-cancelletion-policy.component.ts | 472 + .../edit-details/edit-details.component.html | 183 + .../edit-details/edit-details.component.ts | 479 + .../edit-modify-rate.component.html | 398 + .../edit-modify-rate.component.ts | 861 + .../modify-details.component.html | 139 + .../modify-details.component.ts | 228 + .../rate-config/rate-config.component.html | 178 + .../rate-config/rate-config.component.ts | 122 + .../add-new-season.component.html | 43 + .../add-new-season.component.ts | 168 + .../season-creation.component.html | 117 + .../season-creation.component.ts | 106 + .../slots/add-slots/add-slots.component.html | 59 + .../slots/add-slots/add-slots.component.ts | 173 + .../tabs-content/slots/slots.component.html | 163 + .../tabs-content/slots/slots.component.ts | 69 + .../tabs/tabs.component.html | 17 + .../tabs/tabs.component.ts | 17 + .../exp-services-search.component.html | 230 + .../exp-services-search.component.ts | 260 + .../exp-services/exp-services.module.ts | 100 + .../hotel-zone-services-add.component.html | 235 + .../hotel-zone-services-add.component.ts | 53 + .../hotel-zone-services-search.component.html | 215 + .../hotel-zone-services-search.component.ts | 107 + .../hotel-zone-services.module.ts | 63 + .../activity-add/activity-add.component.html | 1 + .../activity-add/activity-add.component.ts | 9 + .../activity-language.component.html | 125 + .../activity-language.component.ts | 9 + .../activity-details.component.html | 546 + .../activity-details.component.ts | 9 + .../activity-details.module.ts | 50 + .../activity-manage.component.html | 62 + .../activity-manage.component.ts | 9 + .../activity-manage/activity-manage.module.ts | 106 + ...ty-edit-cancellation-policy.component.html | 309 + ...vity-edit-cancellation-policy.component.ts | 10 + .../activity-edit-option.component.html | 350 + .../activity-edit-option.component.ts | 10 + .../activity-edit-price.component.html | 569 + .../activity-edit-price.component.ts | 10 + .../activity-option-add.component.html | 1226 ++ .../activity-option-add.component.ts | 10 + .../activity-option-policy.component.html | 321 + .../activity-option-policy.component.ts | 10 + .../activity-option-search.component.html | 231 + .../activity-option-search.component.ts | 10 + .../activity-option.component.html | 1 + .../activity-option.component.ts | 10 + .../activity-option/activity-option.module.ts | 78 + .../activity-view-option.component.html | 464 + .../activity-view-option.component.ts | 10 + .../activity-view.module.ts | 29 + .../view-option-policy.component.html | 63 + .../view-option-policy.component.ts | 10 + .../activity-overview.component.html | 2424 +++ .../activity-overview.component.ts | 10 + .../activity-overview.module.ts | 57 + .../allocation-add.component.html | 190 + .../allocation-add.component.ts | 10 + .../allocation-edit.component.html | 412 + .../allocation-edit.component.ts | 10 + .../allocation-search.component.html | 134 + .../allocation-search.component.ts | 10 + .../allocation/allocation.component.html | 1 + .../allocation/allocation.component.ts | 10 + .../allocation/allocation.module.ts | 51 + .../itinerary-language.component.html | 189 + .../itinerary-language.component.ts | 9 + .../itinerary/itinerary.component.html | 522 + .../itinerary/itinerary.component.ts | 9 + .../itinerary/itinerary.module.ts | 54 + .../media/media.component.html | 114 + .../activity-manage/media/media.component.ts | 9 + .../activity-manage/media/media.module.ts | 50 + .../required-info.component.html | 285 + .../required-info/required-info.component.ts | 9 + .../required-info/required-info.module.ts | 50 + .../season-add/season-add.component.html | 123 + .../season/season-add/season-add.component.ts | 9 + .../season-search.component.html | 116 + .../season-search/season-search.component.ts | 9 + .../season/season.component.ts | 9 + .../activity-manage/season/season.module.ts | 44 + .../slots/slots-add/slots-add.component.html | 105 + .../slots/slots-add/slots-add.component.ts | 10 + .../slots-search/slots-search.component.html | 124 + .../slots-search/slots-search.component.ts | 10 + .../slots/slots.component.html | 1 + .../activity-manage/slots/slots.component.ts | 12 + .../activity-manage/slots/slots.module.ts | 46 + .../travel-details.component.html | 565 + .../travel-details.component.ts | 9 + .../travel-details/travel-details.module.ts | 50 + .../activity-search.component.html | 244 + .../activity-search.component.ts | 9 + .../services/activity/activity.component.html | 1 + .../services/activity/activity.component.ts | 9 + .../services/activity/activity.module.ts | 73 + ...ght-inventory-report-search.component.html | 330 + ...light-inventory-report-search.component.ts | 132 + .../flight-inventory-report.module.ts | 57 + .../flight-inventory-add.component.html | 1589 ++ .../flight-inventory-add.component.ts | 1017 ++ .../edit-flight-details.component.html | 600 + .../edit-flight-details.component.ts | 475 + .../edit-rate-inventory.component.html | 1128 ++ .../edit-rate-inventory.component.ts | 664 + .../flight-inventory-manage.module.ts | 48 + .../flight-inventory-search.component.html | 564 + .../flight-inventory-search.component.ts | 333 + .../flight-inventory.module.ts | 67 + .../flight-services-add.component.html | 1125 ++ .../flight-services-add.component.ts | 605 + .../edit-contract/edit-contract-details.html | 56 + .../edit-contract/edit-contract-details.ts | 117 + .../edit-flight-details.component.html | 604 + .../edit-flight-details.component.ts | 546 + .../edit-rate-and-inventory.component.html | 659 + .../edit-rate-and-inventory.component.ts | 380 + .../flight-services-manage.module.ts | 74 + .../flight-services-search.component.html | 436 + .../flight-services-search.component.ts | 349 + .../flight-services/flight-services.module.ts | 77 + .../hotel/hotel-add/hotel-add.component.html | 99 + .../hotel/hotel-add/hotel-add.component.ts | 119 + .../allocation-add.component.html | 259 + .../allocation-add.component.ts | 322 + .../allocation-view.component.html | 153 + .../allocation-view.component.ts | 104 + .../allocation/allocation.component.html | 1 + .../allocation/allocation.component.ts | 14 + .../allocation/allocation.module.ts | 58 + .../hotel-add-block-date.component.html | 85 + .../hotel-add-block-date.component.ts | 109 + .../hotel-block-date.component.html | 163 + .../hotel-block-date.component.ts | 97 + .../hotel-block-date.module.ts | 60 + .../hotel-manage/hotel-manage.component.html | 103 + .../hotel-manage/hotel-manage.component.ts | 19 + .../hotel/hotel-manage/hotel-manage.module.ts | 173 + .../hotel-meal-add.component.html | 236 + .../hotel-meal-add.component.ts | 188 + .../hotel-meal/hotel-meal.component.html | 197 + .../hotel-meal/hotel-meal.component.ts | 113 + .../hotel-meal/hotel-meal.module.ts | 61 + .../hotel-offers/hotel-offers.component.html | 1 + .../hotel-offers/hotel-offers.component.ts | 14 + .../hotel-offers/hotel-offers.module.ts | 58 + .../offers-add/offers-add.component.html | 961 ++ .../offers-add/offers-add.component.ts | 733 + .../offers-view/offers-view.component.html | 253 + .../offers-view/offers-view.component.ts | 143 + .../hotel-room-add.component.html | 976 ++ .../hotel-room-add.component.ts | 764 + .../hotel-room/hotel-room.component.html | 257 + .../hotel-room/hotel-room.component.ts | 120 + .../hotel-room/hotel-room.module.ts | 67 + .../hotel-season-add.component.html | 72 + .../hotel-season-add.component.ts | 173 + .../hotel-season/hotel-season.component.html | 138 + .../hotel-season/hotel-season.component.ts | 89 + .../hotel-season/hotel-season.module.ts | 62 + .../hotel-supplements.component.html | 1 + .../hotel-supplements.component.ts | 14 + .../hotel-supplements.module.ts | 67 + .../supplements-add.component.html | 1139 ++ .../supplements-add.component.ts | 701 + .../supplements-add/tab1/tab1.component.html | 121 + .../supplements-add/tab1/tab1.component.ts | 14 + .../supplements-add/tab2/tab2.component.html | 121 + .../supplements-add/tab2/tab2.component.ts | 14 + .../supplements-view.component.html | 234 + .../supplements-view.component.ts | 153 + .../hotel-update-adult.component.html | 370 + .../hotel-update-adult.component.ts | 307 + .../hotel-update-adult.module.ts | 57 + .../hotel-update-allocation.component.html | 338 + .../hotel-update-allocation.component.ts | 449 + .../hotel-update-allocation.module.ts | 56 + .../hotel-update-cancellation.component.html | 334 + .../hotel-update-cancellation.component.ts | 458 + .../hotel-update-cancellation.module.ts | 54 + .../hotel-update-child.component.html | 330 + .../hotel-update-child.component.ts | 308 + .../hotel-update-child.module.ts | 56 + .../hotel-update-meal-add-on.component.html | 51 + .../hotel-update-meal-add-on.component.ts | 83 + .../hotel-update-meal-add-on.module.ts | 54 + .../hotel-update-nationality.component.html | 186 + .../hotel-update-nationality.component.ts | 139 + .../hotel-update-nationality.module.ts | 54 + .../minimum-stay-add.component.html | 218 + .../minimum-stay-add.component.ts | 328 + .../minimum-stay-view.component.html | 138 + .../minimum-stay-view.component.ts | 92 + .../minimum-stay/minimum-stay.component.html | 1 + .../minimum-stay/minimum-stay.component.ts | 14 + .../minimum-stay/minimum-stay.module.ts | 56 + .../update-minimum-stay.component.html | 208 + .../update-minimum-stay.component.ts | 298 + .../overview/overview.component.html | 1622 ++ .../overview/overview.component.ts | 1203 ++ .../hotel-manage/overview/overview.module.ts | 47 + .../rate-setting-add.component.html | 1245 ++ .../rate-setting-add.component.ts | 783 + .../sub-tab1/sub-tab1.component.html | 244 + .../sub-tab1/sub-tab1.component.ts | 14 + .../sub-tab2/sub-tab2.component.html | 194 + .../sub-tab2/sub-tab2.component.ts | 14 + .../sub-tab3/sub-tab3.component.html | 194 + .../sub-tab3/sub-tab3.component.ts | 14 + .../rate-setting/rate-setting.component.html | 304 + .../rate-setting/rate-setting.component.ts | 175 + .../rate-setting/rate-setting.module.ts | 73 + .../hotel-search/hotel-search.component.html | 312 + .../hotel-search/hotel-search.component.ts | 226 + .../services/hotel/hotel.component.html | 0 .../modules/services/hotel/hotel.component.ts | 14 + .../modules/services/hotel/hotel.module.ts | 70 + src/app/modules/services/services.module.ts | 76 + .../role-add/role-add.component.html | 132 + .../role-add/role-add.component.ts | 605 + .../role-management.component.html | 0 .../role-management.component.scss | 0 .../role-management.component.ts | 15 + .../role-management/role-management.module.ts | 68 + .../role-view/role-view.component.html | 145 + .../role-view/role-view.component.ts | 90 + .../user-configuration.module.ts | 34 + .../user-add/user-add.component.html | 350 + .../user-add/user-add.component.ts | 262 + .../user-management.component.html | 1 + .../user-management.component.scss | 0 .../user-management.component.ts | 14 + .../user-management/user-management.module.ts | 58 + .../user-view/user-view.component.html | 140 + .../user-view/user-view.component.ts | 108 + src/assets/.gitkeep | 0 src/assets/files-lazy.json | 18 + src/assets/files.json | 121 + src/assets/image/Hotel-Image.jpg | Bin 0 -> 44079 bytes src/assets/image/hotel.jpeg | Bin 0 -> 74509 bytes src/assets/image/menu.png | Bin 0 -> 5745 bytes src/assets/products.json | 363 + src/environments/environment.dev.ts | 12 + src/environments/environment.preprod.ts | 10 + src/environments/environment.prod.ts | 12 + src/environments/environment.ts | 25 + src/environments/environment.uat.ts | 10 + src/favicon.ico | Bin 0 -> 948 bytes src/index.html | 19 + src/main.ts | 14 + src/polyfills.ts | 53 + src/scss/_badge.scss | 63 + src/scss/_buttons.scss | 125 + src/scss/_calendar.scss | 238 + src/scss/_checkBox.scss | 47 + src/scss/_comCalender.scss | 92 + src/scss/_common.scss | 1744 ++ src/scss/_dataTable.scss | 379 + src/scss/_dropzone.scss | 368 + src/scss/_input.scss | 111 + src/scss/_login.scss | 340 + src/scss/_rowCol.scss | 749 + src/scss/_select.scss | 148 + src/scss/_sidebar.scss | 274 + src/scss/_table.scss | 93 + src/scss/_tabs.scss | 438 + src/scss/default.scss | 162 + src/styles.scss | 231 + src/test.ts | 26 + tsconfig.app.json | 15 + tsconfig.json | 35 + tsconfig.spec.json | 18 + uat.Dockerfile | 16 + 463 files changed, 95252 insertions(+) create mode 100644 .browserslistrc create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/extranet_ui_ng/FileContentIndex/e6c2de4a-47b3-4d86-9723-4f2f8b582011.vsidx create mode 100644 .vs/extranet_ui_ng/FileContentIndex/read.lock create mode 100644 .vs/extranet_ui_ng/v17/.suo create mode 100644 .vs/slnx.sqlite create mode 100644 Dockerfile create mode 100644 angular.json create mode 100644 azure-pipelines-dev.yaml create mode 100644 azure-pipelines-preprod.yaml create mode 100644 azure-pipelines-prod.yaml create mode 100644 azure-pipelines-uat.yaml create mode 100644 karma.conf.js create mode 100644 kustomize/base/deployment.yaml create mode 100644 kustomize/base/hpa.yaml create mode 100644 kustomize/base/kustomization.yaml create mode 100644 kustomize/base/service.yaml create mode 100644 kustomize/manifests/dev.yaml create mode 100644 kustomize/manifests/preprod/preprod.yaml create mode 100644 kustomize/manifests/prod/prod.yaml create mode 100644 kustomize/manifests/uat/uat.yaml create mode 100644 kustomize/overlays/dev/hpa.yaml create mode 100644 kustomize/overlays/dev/kustomization.yaml create mode 100644 kustomize/overlays/pre-prod/kustomization.yaml create mode 100644 kustomize/overlays/prod/kustomization.yaml create mode 100644 kustomize/overlays/uat/kustomization.yaml create mode 100644 nginx.conf create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 preprod.Dockerfile create mode 100644 prod.Dockerfile create mode 100644 src/app/app-routing.module.ts create mode 100644 src/app/app.component.html create mode 100644 src/app/app.component.ts create mode 100644 src/app/app.module.ts create mode 100644 src/app/core/common/RouteChangeService.service.ts create mode 100644 src/app/core/common/common-function.service.ts create mode 100644 src/app/core/common/intercept-loader.service.ts create mode 100644 src/app/core/common/loader.service.ts create mode 100644 src/app/core/common/security.ts create mode 100644 src/app/core/common/static-data.service.ts create mode 100644 src/app/core/common/validation.service.ts create mode 100644 src/app/core/guard/auth.guard.ts create mode 100644 src/app/core/models/Experience-Service/experience-manage-languag/experience-manage-lang.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model.ts create mode 100644 src/app/core/models/Experience-Service/experience-sevice-add/experience-service-add.model.ts create mode 100644 src/app/core/models/Experience-Service/season-setting/season-setting-add.model.ts create mode 100644 src/app/core/models/Experience-Service/slot/add-slots-model.ts create mode 100644 src/app/core/models/common-model/Sign-in.model.ts create mode 100644 src/app/core/models/common-model/user-logout.model.ts create mode 100644 src/app/core/models/common-model/userModel.ts create mode 100644 src/app/core/models/flight-service/flight-contracts.model.ts create mode 100644 src/app/core/models/flight-service/flight-service-manage/edit-Rate-inventry.model.ts create mode 100644 src/app/core/models/flight-service/flight-service-manage/edit-contract-details.model.ts create mode 100644 src/app/core/models/flight-service/flight-service-manage/edit-flight-details.model.ts create mode 100644 src/app/core/models/flight-service/flight-service-search/flight-service-search.model.ts create mode 100644 src/app/core/models/hotelService/AddRoom/Room.model.ts create mode 100644 src/app/core/models/hotelService/OverViewData/RoomsOverView.model.ts create mode 100644 src/app/core/models/hotelService/Tab-Content/tab-4/Tab-4.model.ts create mode 100644 src/app/core/models/optional-ons/optional-ons.model.ts create mode 100644 src/app/core/models/user-role-management/user-role.model.ts create mode 100644 src/app/core/services/HotelServices/hotel_booking_management.service.ts create mode 100644 src/app/core/services/HotelServices/manage-hotel.service.ts create mode 100644 src/app/core/services/PagesService/hotelService/AddRoomService/Add-Room.service.ts create mode 100644 src/app/core/services/PagesService/hotelService/tab-content/tab-3/RoomContract.service.ts create mode 100644 src/app/core/services/PagesService/hotelService/tab-content/tab-4/tab-4.service.ts create mode 100644 src/app/core/services/active-sidebar.service.ts create mode 100644 src/app/core/services/api.service.ts create mode 100644 src/app/core/services/breakpoints.services.ts create mode 100644 src/app/core/services/common.service.ts create mode 100644 src/app/core/services/event-utils.ts create mode 100644 src/app/core/services/events.calender.service.ts create mode 100644 src/app/core/services/flight-contract.service.ts/flight-contract.service.ts create mode 100644 src/app/core/services/node.service.ts create mode 100644 src/app/core/services/nodeservice.ts create mode 100644 src/app/core/services/product.service.ts create mode 100644 src/app/core/services/product.ts create mode 100644 src/app/core/services/sso.service.ts create mode 100644 src/app/core/shared/intercept-loader/intercept-loader.component.html create mode 100644 src/app/core/shared/intercept-loader/intercept-loader.component.ts create mode 100644 src/app/core/shared/shared.module.ts create mode 100644 src/app/layouts/base/base.component.html create mode 100644 src/app/layouts/base/base.component.ts create mode 100644 src/app/layouts/intercept-loader/loader/loader.component.html create mode 100644 src/app/layouts/intercept-loader/loader/loader.component.ts create mode 100644 src/app/layouts/pages-routing.module.ts create mode 100644 src/app/layouts/theme.module.ts create mode 100644 src/app/layouts/unauthorized/unauthorized.component.html create mode 100644 src/app/layouts/unauthorized/unauthorized.component.ts create mode 100644 src/app/modules/auth/auth.component.html create mode 100644 src/app/modules/auth/auth.component.ts create mode 100644 src/app/modules/auth/auth.module.ts create mode 100644 src/app/modules/auth/forget-password/forget-password.component.html create mode 100644 src/app/modules/auth/forget-password/forget-password.component.ts create mode 100644 src/app/modules/auth/login/login.component.html create mode 100644 src/app/modules/auth/login/login.component.ts create mode 100644 src/app/modules/auth/single-sign-on/single-sign-on.component.html create mode 100644 src/app/modules/auth/single-sign-on/single-sign-on.component.ts create mode 100644 src/app/modules/auth/verify-email/verify-email.component.html create mode 100644 src/app/modules/auth/verify-email/verify-email.component.ts create mode 100644 src/app/modules/booking-management/booking-management.component.html create mode 100644 src/app/modules/booking-management/booking-management.component.ts create mode 100644 src/app/modules/booking-management/booking-management.module.ts create mode 100644 src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.html create mode 100644 src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.ts create mode 100644 src/app/modules/booking-management/experience-booking/experience-booking.component.html create mode 100644 src/app/modules/booking-management/experience-booking/experience-booking.component.ts create mode 100644 src/app/modules/booking-management/experience-booking/experience-booking.module.ts create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.html create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.ts create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.html create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.ts create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking.component.html create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking.component.ts create mode 100644 src/app/modules/booking-management/hotel-booking/hotel-booking.module.ts create mode 100644 src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.html create mode 100644 src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.ts create mode 100644 src/app/modules/common/custom-sidebar/custom-sidebar.component.html create mode 100644 src/app/modules/common/custom-sidebar/custom-sidebar.component.ts create mode 100644 src/app/modules/common/footer/footer.component.html create mode 100644 src/app/modules/common/footer/footer.component.ts create mode 100644 src/app/modules/common/header/header.component.html create mode 100644 src/app/modules/common/header/header.component.ts create mode 100644 src/app/modules/common/sidebar/sidebar.component.html create mode 100644 src/app/modules/common/sidebar/sidebar.component.ts create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.html create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.ts create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.html create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.ts create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.html create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.ts create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.html create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.ts create mode 100644 src/app/modules/services/activity-config/activity-add-on/activity-add-on.module.ts create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.html create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.ts create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.html create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.ts create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.html create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.ts create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.html create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.ts create mode 100644 src/app/modules/services/activity-config/activity-category/activity-category.module.ts create mode 100644 src/app/modules/services/activity-config/activity-config.module.ts create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.html create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.ts create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.html create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.ts create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.html create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.ts create mode 100644 src/app/modules/services/activity-config/hotel-zone/hotel-zone.module.ts create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.html create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.ts create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.html create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.ts create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.html create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.ts create mode 100644 src/app/modules/services/activity-config/vehicle-master/vehicle-master.module.ts create mode 100644 src/app/modules/services/activity-services/activity-services.module.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.module.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.html create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.ts create mode 100644 src/app/modules/services/activity-services/exp-services/exp-services.module.ts create mode 100644 src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.html create mode 100644 src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.ts create mode 100644 src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.html create mode 100644 src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.ts create mode 100644 src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services.module.ts create mode 100644 src/app/modules/services/activity/activity-add/activity-add.component.html create mode 100644 src/app/modules/services/activity/activity-add/activity-add.component.ts create mode 100644 src/app/modules/services/activity/activity-language/activity-language.component.html create mode 100644 src/app/modules/services/activity/activity-language/activity-language.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-details/activity-details.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-manage.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-manage.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-manage.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-option.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.html create mode 100644 src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.html create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.html create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.html create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation.component.html create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/allocation/allocation.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.html create mode 100644 src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.html create mode 100644 src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/itinerary/itinerary.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/media/media.component.html create mode 100644 src/app/modules/services/activity/activity-manage/media/media.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/media/media.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/required-info/required-info.component.html create mode 100644 src/app/modules/services/activity/activity-manage/required-info/required-info.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/required-info/required-info.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.html create mode 100644 src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.html create mode 100644 src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/season/season.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/season/season.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.html create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.html create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots.component.html create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/slots/slots.module.ts create mode 100644 src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.html create mode 100644 src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.ts create mode 100644 src/app/modules/services/activity/activity-manage/travel-details/travel-details.module.ts create mode 100644 src/app/modules/services/activity/activity-search/activity-search.component.html create mode 100644 src/app/modules/services/activity/activity-search/activity-search.component.ts create mode 100644 src/app/modules/services/activity/activity.component.html create mode 100644 src/app/modules/services/activity/activity.component.ts create mode 100644 src/app/modules/services/activity/activity.module.ts create mode 100644 src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.html create mode 100644 src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.ts create mode 100644 src/app/modules/services/flight-inventory-report/flight-inventory-report.module.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.html create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.html create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.html create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-manage/flight-inventory-manage.module.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.html create mode 100644 src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.ts create mode 100644 src/app/modules/services/flight-inventory/flight-inventory.module.ts create mode 100644 src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.html create mode 100644 src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.ts create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.html create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.ts create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.html create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.ts create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.html create mode 100644 src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.ts create mode 100644 src/app/modules/services/flight-services/flight-services-manage/flight-services-manage.module.ts create mode 100644 src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.html create mode 100644 src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.ts create mode 100644 src/app/modules/services/flight-services/flight-services.module.ts create mode 100644 src/app/modules/services/hotel/hotel-add/hotel-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-add/hotel-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/allocation/allocation.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-manage.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-manage.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-manage.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/overview/overview.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/overview/overview.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/overview/overview.module.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.html create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.ts create mode 100644 src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.module.ts create mode 100644 src/app/modules/services/hotel/hotel-search/hotel-search.component.html create mode 100644 src/app/modules/services/hotel/hotel-search/hotel-search.component.ts create mode 100644 src/app/modules/services/hotel/hotel.component.html create mode 100644 src/app/modules/services/hotel/hotel.component.ts create mode 100644 src/app/modules/services/hotel/hotel.module.ts create mode 100644 src/app/modules/services/services.module.ts create mode 100644 src/app/modules/user-configuration/role-management/role-add/role-add.component.html create mode 100644 src/app/modules/user-configuration/role-management/role-add/role-add.component.ts create mode 100644 src/app/modules/user-configuration/role-management/role-management.component.html create mode 100644 src/app/modules/user-configuration/role-management/role-management.component.scss create mode 100644 src/app/modules/user-configuration/role-management/role-management.component.ts create mode 100644 src/app/modules/user-configuration/role-management/role-management.module.ts create mode 100644 src/app/modules/user-configuration/role-management/role-view/role-view.component.html create mode 100644 src/app/modules/user-configuration/role-management/role-view/role-view.component.ts create mode 100644 src/app/modules/user-configuration/user-configuration.module.ts create mode 100644 src/app/modules/user-configuration/user-management/user-add/user-add.component.html create mode 100644 src/app/modules/user-configuration/user-management/user-add/user-add.component.ts create mode 100644 src/app/modules/user-configuration/user-management/user-management.component.html create mode 100644 src/app/modules/user-configuration/user-management/user-management.component.scss create mode 100644 src/app/modules/user-configuration/user-management/user-management.component.ts create mode 100644 src/app/modules/user-configuration/user-management/user-management.module.ts create mode 100644 src/app/modules/user-configuration/user-management/user-view/user-view.component.html create mode 100644 src/app/modules/user-configuration/user-management/user-view/user-view.component.ts create mode 100644 src/assets/.gitkeep create mode 100644 src/assets/files-lazy.json create mode 100644 src/assets/files.json create mode 100644 src/assets/image/Hotel-Image.jpg create mode 100644 src/assets/image/hotel.jpeg create mode 100644 src/assets/image/menu.png create mode 100644 src/assets/products.json create mode 100644 src/environments/environment.dev.ts create mode 100644 src/environments/environment.preprod.ts create mode 100644 src/environments/environment.prod.ts create mode 100644 src/environments/environment.ts create mode 100644 src/environments/environment.uat.ts create mode 100644 src/favicon.ico create mode 100644 src/index.html create mode 100644 src/main.ts create mode 100644 src/polyfills.ts create mode 100644 src/scss/_badge.scss create mode 100644 src/scss/_buttons.scss create mode 100644 src/scss/_calendar.scss create mode 100644 src/scss/_checkBox.scss create mode 100644 src/scss/_comCalender.scss create mode 100644 src/scss/_common.scss create mode 100644 src/scss/_dataTable.scss create mode 100644 src/scss/_dropzone.scss create mode 100644 src/scss/_input.scss create mode 100644 src/scss/_login.scss create mode 100644 src/scss/_rowCol.scss create mode 100644 src/scss/_select.scss create mode 100644 src/scss/_sidebar.scss create mode 100644 src/scss/_table.scss create mode 100644 src/scss/_tabs.scss create mode 100644 src/scss/default.scss create mode 100644 src/styles.scss create mode 100644 src/test.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.spec.json create mode 100644 uat.Dockerfile diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..f69f7c8 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,15 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 iOS major versions +Firefox ESR diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..105c00f --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.angular/cache +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..c7363e3 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,8 @@ +{ + "ExpandedNodes": [ + "", + "\\src", + "\\src\\environments" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/extranet_ui_ng/FileContentIndex/e6c2de4a-47b3-4d86-9723-4f2f8b582011.vsidx b/.vs/extranet_ui_ng/FileContentIndex/e6c2de4a-47b3-4d86-9723-4f2f8b582011.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..a93cc97e84541de24ac67a441681a4e6b1d6e5e4 GIT binary patch literal 1045994 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 g> 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

JaXW%gd4~8IrVwSiivn7iq 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�O>EJIX~!U4eRIj(0@tD{+;VfNhtG! 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

  • 9PsLP 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 T&vRpPf2{>upO-yNVSN7w+i7<$ literal 0 HcmV?d00001 diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..a1829695c3d05fe9a026dd37ad936613f99baa02 GIT binary patch literal 237568 zcmeEv2YejG)%f1+-d@|HlP$@%Y^%A+(y3P$u#jb0mMvM9ry{@|1!fK8geWBr-Q z6x82gLCo?Oh$mV8LbyXnayB|HwqIa--OBPU?4{<<%&W}HVu?u5j~Nfxkfos+k~M9O z+Z1Z)9q{>2Zr#z}J=nL{-_twL8|)n%=pug(Y+TaY=Wplw@ zynHz-Yg2P=O>155*$V}0n%iwU-yQUH_xU4>9{F3O#RhuVO8Cdx>a>ewRNqT9ZHV6fnaZN$A&p70Yv16vp~JIuUw2A0dA8w??u>#9$O(xX4-uqK4ACBM|iWt1gTrAy;OGb03T^mk)Y9 zsC}*)+#b6C3RCT1-$?&JG@t0m4HY`AX_uzekh{Cxfm__34YO9&SRzOb*{S}Htx80gnm}@#y#*wI~Me@23Pzb~@2d&ojriPYw^~s~~sF^h3 zrKHheaQEvn}~ld)OTa&t|)=i@k3gc0%jUv_;A>Jv2)s3d4B zDUQe^k)aw)iWBZ;i^l9_6}@Uv{z+m)r&WFbtHX$+tisjG=yftkL^n5$QJ)fo(Qq|EpHT|E4-Ac84NyZYHh%V6b;!BW}}lyiF*a zKAxiaa2Vm?KFJWP(dMo+^J#f`rgb=S0$X8>=I;vlw~qJ+VAQ7n$?D=JB5}?D1b;r{ z%nj9>tZC`#rZfFmCbf+svra|_rD{TsQjS`rt@iYdKs`o8XFI&Bxf~)uo}0zU@5|5d zHT)!=fgg!~2@fPZknn)&f!%9(3p4*57Ipg#;R%~o@?sY#@^|~Hef~0cNr~6*E-R@j zc6-Ww6>e{LQDs$Sb(y~m$fbV2x2U4T>n<*OF0OW0`8-g%?lP~t+gDcZF0Lr|m2`W1 zDtao4-F{zHaamb)rMtAKyxd(@;VpJo_xOw4Ajj*iE-x)AEiQ8RRF-?ID!Yr^K3_T5 z)KgL9uC4%&dwo5=qKYagR7pvyg<}e3T&FN-N3$5UgChgMlGz-`xJzq?{hpxT*F4-l ziEM^>>$h*99)TU&cjgH zu`M_p<@5{5j0}qvH|p;IO~5bK{6-*ar=1B)F*n|9uF)i6!xHc`26s zqv?A_*f2Vk+N+cR816AsyZV=6ej-W*fiH{;xH7?*7s8tfei24IYy zmSyIcS{EMYkg-sp9So<_41q@fj*bnfCXSh%)(R^y{T@0iTU=0DP%g^nGrYW>k^d>b zA>Sacm!Flls>A-o9|;d6Jdp4}!UG8pBs`GtK*9qF4^|rkm*G0Pg@{yu68#ua;ku&yqLE_sf49qhN{T zga;BHNO&OOfrJMV9!Pi~;emt)5*|o+AmM?82NE8L;em8^zA47;Sw4j=G)3*ev`l2( zrpW!5Tn1ZjFvt&{FDEk1+N$hO9ZW93dHs37&8(BS5{zCq@e44yPZkEgCNz#|n z>(Y;<+oa2-VX0jzm8Oedi?4~#i1&$?iX-BB@dRr!hW{}ulNe*?dZ@8ZjO*7AzwHcP*yjQfiFJ$E;E z2Dg@*!Tz0ng1wqOm2G9+ti$|{`BC$Q=5^*drq4}JnJzS~F->FkGZh0o(_ymn{*#CN z!@X#>#jR}YaQAx#JRAL*O-sRm-}Z;5{bxM*@y4otp6QA=-=<)HpPI9@k7wFrW#I9_nvhrwiRyTnH4d(wOg~)48?U{@ARfMpf2XKAxE$Ln>5-%9rKknPM5MB6Dx8{URtIr{&a$veS1R`8 zu16IaQ39RmDr??4o~av!73o)*bJp@qx$0cKXH=&0HBl``z{MX|YZHP37SLp0q< z%xuV!;f(F^XGEn@Gv>9CqDN~CyR=y`ub`D@8V$|U6-VVST1A4$K)60~)f{tLc;S!FI*K}v4G94<*P zpz;?jCnX=1A60~!Bdw8Vrh&yuCoxYc%JgMClLt;8f`>^UY?_*$)j)a|lCHHzWyx8J zLRJwGWZ_m?`#o?rh%U?)C>m#+KswJT9;7hLRTF~?=~KC~7ZH6ugV1;C_03oH9Zw`h@gRL+ zuH#~GA$=-W>O!7LN7YVtvsNoQQWo&cWT2BWg~{^?nW$FD6X)?v8gSznn61jFCd^Px z{euH4IkSpq3c;n_o`8OIQmSOkt|U%~;6TL-^Hdn}pu(v<)5}Td24QcgKODNV6g{)b zNLP-{j{crN<(p8-GbvC!WRFUmT*5P1D5!_w`vWi9TAr)O%_^o%f+o>6rDd63L`)kP z^!YVgh*c4}h2-hs-v%8*pup?t^TXF^+TF$~>$C#&w1rL^vAW@#2>j)Xnw;q-?k2Th zq-$0_af4>>t-^-Bp;0Bx$wQr^osYQzTIHNN7j=%nsoh;ZM{!SDuD+|8sU%FCL&6B} zM^~w-vq^}OUNMlOaHq~9^ghoH_!1;cpD>fu7TPtgGEbdBEgBjM2ZEZKk;5}?WG|#@ zI~A27E1T4)o&g19m?g`Q#iM1(G-5#^t4f)XL0T;+iVjGXD|I?5x}B$A+(?Q`rcC3R z9H0k+JNlrrM)s*`6Q&Zk=!og*JTntAXunfZbEHloTIh#kDt+=~68ZQm_X1?TnluGI zvqlE=cwn>q;6MQYH7z|2>4InCz_#Au!2$H73tN|xO8N?LmtR9pPT`pekO$nM%9$~d zxM+3jn!({Mfgz9A-x`E(`0zJ$yyA*!6UZ3Ue{yixGvE()jr4X6Y*dpcBtxj#ZM+v9 z-J|5mbV2pqG-`FxFjeI1D)-#SILtm z@=ONgfm6X2uc#~NS6^bL2;eP9fZ}aIuW?#A8BU^zrn&nDy<2n)QyeI>jYqvp7i~9+ z#&kO=!WIu4j0e#^&;wbO#7Q=&TF|-}B>IQpD>~ITQ>?@u&%nl!KKSfGYmbX3kSSLlW!uG#A#;eDp6wh@Zfgn zN&|iHiDKA;sV3-6kUV4=yzFO&+5lz@m;svP_W?39&=~;oBl3M>ooP_MPI^F^ESbd* z#aG22i}y;mieBM*VYP6aFvsyv$4MtIwiY5%)@tv%1q z*q^iCWs{Wu3}@%Kt|CwRDzXbN>l~8p&o-}ZzAeS}Gu!R93#|WRS|g3fJH;!dUhzWV1(=~|mlq2Ygfks~ za6IL>Us?+@5Vy+}QnNVXxXJpW^}E*VoF6-nbLKc5a)ER_m&TsUZedq)cD9sFHGjc= zVSdy6r1>`Xujcd2edZQ!fc-gpt7S9y8TU5#yv4&k%w5BsWm(I$a|^hcmS%I6Im2wT zJZJfVrO@KC+-Nz^5|B!T0eO)-3#@UF>RFS66j@CS5SgZ<2P z`D}+-GwN0bl}0ac%(Vqte2nn;rE`%+;xEp&8DyDART9%vF=v(nvBEf2BbJ z7WC~YY^6Cc(v429ix9SNDm&jO2@CvIj6^K-3XRZGy@i)+@@bQ>(92>ZVxgC6gqG-q z?$zYeCSjqM#7M+KFV+Yx)(gEzlTVw3g^4Zi2Ar7!8~Kp{WLU<3jA8%1_Qe&x0Z^e>@=VwDW^_jk4I8e z^K^bb1Cu>fDO3WuK0M7as9DOh@ATDo6D{<6su=Mj@S|( zD^kBXi>)`38XnU2&R|y4JgvnQUFmWF&jtB(_}7Kx=1hL{yDZ-ZlB`2CcVZ zvZ6w-j+Yr(*N)8B)B}|quJN`Uw$X?|>w{KQX$C^VJV@0l)V)P>QE#-k*x7nFtwbRh z&EJeHRvch7CD(*3Hed)_6AY|C7LUqS#x$2np1FD>Rm2RoVCvH<-_M9sIeX~c2!5D{t&rlqRULn~sUDHy0i zhDA`3`bq;jQeJ_oFJhXh95wqGQ%hy&nTF(-N^F)XJcU$(t2}Djs2GWlm?|p5-EYk4 zp+eLv>ZgPXP*F*#mH8c*-f<%{V@&pL0(5c zIV7>b5AUM+kq=#<vF9`Lm-46bKjgo{9KgHsoAPV&tMYR&8}JkPF_;l} zP`*dLUA|Gi#-1;KOTI)tPu?x>lDErS;Z58xcggGIR(XY7FW1QPVdp@hoNK?weyja@ z`?u|T?K|wl_APdweS>|qz1hChUSpqUFO_rTY0}%Uzu-607@_CqkF7R%j7E68@j?rtn+gMd4?{6EGujpKu$@nCufS7WN3I3EPALp+{hy zUpW8i{LuNX^L6Jd&gY#^IUj?)5_daqc3$JW9A-auJ5O~6oLih;XNR-Z+32iw&UcnN z^I#?;-8sSObh3^wVD{xh$GeW#9j`c^huM$E91q)Hx4&Y4-u@Kqt9aOPx8r8VHIB<2 z7dUpqo{NBEi^J>aaJ0hSi(1EgN2wzZ_F$wtCODk16XOf}KkXmd-?g7>Kf``T#0*B_ zXTk#s4l>l4gJ6#tdtzhL}0^C89mL-7X~|CV{5 z;y+XT|1kayv!CMkD1H~?SDAMxew*SyVf+g77R7H;{6~y`&AdS|TKce_CihoG)4=DaV#t$=( zQv3+T-^2JO=DQR>Oz}e$KS=Qd6yJ~Wjm&)%-%Ig57+=raP4Qh6-%0Tu7+=TSPVsFN z-%9Z%(vhhMN)W>cwyqh8r>L!O)MP55Yz+hTRx?FgyvvE(F(}h~Wkd zI}u#jf#G@#*I~F8!Im``uEww(!R9s$TQOXPVGDxwD=}=wunEHz7%oR}UL%IfFl@kZ zDTeh3E?k0P9fpe$Tu_VQ2^iKOIDZj_$76ULg4GK#T!7(x1ZU5~uo}VADhw+ztUz#9 zIfi8zmLiy2f?+X+MHm)hSb(7$!+Z?$5S%j?!I`-j&OtC`Hiok>oQdHK40ABd#xM)R zObjy+l%``i4a2Dzrein-!^s#DQ zi8sMp@pkC~F-utH{L=Z3^Et?%v+U*XvYccou~_-@_>=f*K1F&$>T%xU?02>}E5*gmZ#&Z+ zUpw~O&#*OEAGcm^-C~<%vsnLZT_Cl~0r5nsUR)`hE_>uYvn@3L;G4Bn^P zA|^-@{xID;-PU!(6PDu3cgU>CjDUb8Azv^s|`@ zW2Iy1XEPVfep+|KMaN`IuRGJKG zOrT$zfYfX|-6#cV*>+kQ*o^XMYakdH*`?&r(vhr@okl50*2t+D-0@hJYOHP%d+RA# zTy4yBBw_0g2bY35%C?@Y{8_qnyYgqr)@{n4#al-d%e9N*!N5>Zu}@1!mJbDtQjp%E z;bd;6-ZKAIMN_~(G?#0KM|14YgVaTH|Dc=e7?oAK#N{6-o91vWW3eHfT^lpG8be09 zG}+Y?lYy*1cKN4q^Nl5dKe~LAxMGvKju#KVcayS5V-M8ANphV;q~>{@-Q z)(P*R!o|2vMlHGr0}E<# z_P(Q02 zcOo&C>SvYVrzz4it2Bwr0vp3$e3Xz7iCVDFEyju>mh5wjNLL?o(LT2j_q_UL``iNT z0OAeJ!hNnAn;m26J~tmX(3p$&xp}yO>Xz^4%+)oEnYp-1$k!Nia5d6J{FK@Fm-6Ms zEbJlty~Ru-RlAg*G9wiRgAwcY@V!P3_FeRHeoD4c0{V_3%OC+&Yf2`LKf^`+lniXD z@}FtQaUL%S>BhX;Q9|Q@Jo}iIL#8jGzrVlF7iuh zIGX8~4XJi+0(OR!f{iv@>gOktIM6Nj^Aj9gnw>89r*Xwhcwt}tPQjJT&DPNIf`2Mk zs3EB<{x)s`gO~gzE`!mm`MbE8jIzd$_XY@9K=i6VX4EbFW99mFf0@f-vVAMcg2^*C&YWi ztHpE0ZK6+HB`y*R#Hpe~_z!#$|Elm);eO#d;e27c;DfK^j}!8QNrJ`s59eFXUpjx_ zybZp4KLfr5SnsTNmN~PW5`5wQzT-EJpE~Y$TKcvLVuQ)C_1PAA0 z;`@{sc;KVt5S*BciTf#W@Xk+@LvT_qCcZ<7>whC9hv1xCOni$H*Y@3%9D;*#G4Tyb z%)0Zbp161!X@$sstt787ry#P#p2PY%J!wU~G_C9e7RiOC^2x)u{} zpv1Ok_aukl$XZOimJ(aKA4?8F#9-o8l(_7-?bG9jHpNuOIkcWo!6ASHcz&HuQz5z-(f{d?9F*9ajEP|`nM{gW$5NPU#_ z;q%wK0)*5{Nk8vsa}5*HCQABQ`X1L-Lh@45Q^RMvh6t&fl76!AJ=Y*1ok&SfY`@es zKu8^w^rO>fyZQ-fJth4xbh@jLkk(Mrqwjt0+CoTel=MjFde>$`YNe#B?)}QuOGr(W zbY;^z*Cs+*K}ltSY}ZCYT1H7FKN)uQ5K;pr6`I$&{DicGlJYOyP5<*u7hJl6 zNW}_iVU-JRRY9aeLb~Mb*I#pW5>gQ*{n2`6El@(ao+^DDa`n_=rV)_a$5ITJCD0q)#bncdBb8C4E9k_2;{qDd|H(+WhVf zt|m%)pOT)w*tLR^_7hU?*;8H1De0XssgaW2qNKvfu4R<;1|`k>m8*f0UL&MUKlqJn zDJ8ueCe>5Yi3+W6`U*J4U~I!vmiq$dff=W*6`0wp~fCe={V z-ITO-p9`+7z+Qcbl4joHf?Fyu=|MvBpLd-LuB5=E`v|Ff=MER#KY>Ym32DJ2AG#J$ z(p`i!Z&QP7J|*2wNYx*iUGpgEHcGnT4OcZK-AqVT-`nV_qNE!rY2y-CB_&-;NsH#Y zDk$kHLaO`+?<%LHeUx;|w_IhEbU7vM{I#o;k}jeoYo4owlFlNe(tUThiYe)QLMr*Z zCaDMorX9Lk9E2qsE^rl6rZZGhQUPH)g;0vW^ForFP=bU~Q*CQWA{R5T$`q?)p3lhG~eh zgi>0ol3-<)y!w}14xAOwDl~1~^wfw{d!z*NAk{R=yH-FvVlVEUVvYU7T zQ9kLq<iVewV@ z2jYwJ?c&end&Qs1H;O-!uMr=Rza>5*Un1Tmp9i-9>=v(=cZpZZ+r`V|t>T697IBa4 z7tfHp#8c#TVo+`s2jmsvCb>rJmgkF|a=Ex#E)-YFIpQ)oS6nQ8EgmON6RYGju|#%> z`La`-C0oQy=`(SP^iOf3^jA@m{v_I@|0kNHUkjg0uL=K@o)`Wioh|H_o)+Ge9v6Nq zJtDj)-7ox1x0yUx>~qTx?H$Tx=^@Y>J|1$rwJEJ+l4*SkZ_vREo_rIgaN5d z=#f?kCrV3%)za}olT;-vk&1=mq`5+clp_>KQ-xVliZET0gjC5YNa8;PUSgd8D}Dx! zOZ-cCAmM?82NE7gcp%|{ga;BHNO)k}djOw<_bGEN#-A|PVEhqtHO3z@S7H1te3V~b z5FN$Vi;wc#gpcy`Zbg)Ce3ajb_$a>)e3ajMe3aiBe3V}sKFY5ZALZACkMdiAkMdiF zkMe84NBJ$mNBPy_qx=@(qx`DyQGVt4D8Dj%lwS!x%C8t7Jqc@ge^jZT(FE7RD#d?gMTY}NEbr?Op7^5d^F?#d_jP9<%=%GazJ$O7u_Z^4P z-h~+5wE&~r=VNr+JdAFx#^{DBjIOQ3=&A~g_QB2YsFuqxx~LSRvq~^JA0PI&s|f!% z1E2PH3O?;Gh)??)#Hamr*Py0I&pZ2#NpZ2!~ zpZ3>=Py1`dr~Rel)Bc+9X@4v5X@AS`X@3p)w7(_zw7*(>+TS94+Funu?XMi4_E&~a z`zyhx{S{9@6;+gsV4(}af+PgWtN#nl5N*I{%K*9qF4g~H2PU#6Jdp4}!UG8pBs`GtK*9qF4<`Q@nm%BjIYiZmFZ-EUQ=D+r z0dr=1$dhJbTLZ)1PPoCblitJGiSI1!jJ|HRGy0O*hegQPZ^8-#xO?9O|A-e8h&z!ADJT7wzC2676i|j^%?d`e-s~AvaATg|vs}Lm^ij z{X&NCB|fa>)QY7=mC_t2=0np)prp%;OBzSrk^7nHW#Dnz9Fd0_G%=MJlyfQ=)NqIf zX$u@zQz15Kvr)6kQgBFw8bdCyYe}SCkOQty?xgohkKQOFc%$#49@BquNT6mHP9$d6 zg+wsBHip^cis-nkrmRtyUB_#4?EH$w6SNjDieWLi$2u;HDQnba+VNT(J3qBpPNq$0 zJGi(?F__-h+==e8Hnvm85plJ4Oyfq+L@e6rA_iG{!JzU;gA7}_n1aRa8rK> zNko0h4p3iqK4tdk z3&dNO+8gUP2dFt24&pX<$O87{AGAG&H{8eRvlw})g~@i}uq@OqxDVPu^6Wd%>Ws=o zjWXGYQ6lOb=IV^vIN}-hjnXrabk9g|Qvv>SjOsIBr#9qRN!1mH>|jKm&WHo)p*-GT z?>4_%8Bc_pdR#q3%-qCEKW|6l#El(bVvb^>;iCjydJpa%8XWKs1Y?Z}g1DbVpeUM`D6D6(!nztzI2|dBa$3+Ih~X!i zLIs(_f~FV>>i6^x7(1M%5J4>_EU38=EJ`;NG&I<^qo=nos!M`*?YT<<cDgS2e7tS+y>+v2I;vO?z8&LlcNyQPA-6%a`XwR(}vp8RIrh$J>O$>EkJy z4~G#R?vo6$8g1@MGoO~1XIh6NC$JU9X#TE%f9r^U07h;4pR6u!A`<5eK=9{7&fHMF z$(oj)ZaUMCWm4NHGV5e?P^u>6DCMX{+G0uPx7&8Xnr*%Q?P#pN(i7Z-pMbsoK;&=g=hY2$YceC#GCcv& zv8JJIDYTo~_EoJ7tLvh9YFg<~4YjXUc*Uq~%Z%<1GHY5hPw)hEWAFxFerBu&jQDFw z+!Ge^1V>p=H=#=oZpvJ;s(D3})^N*(@kn!1_$RS4{2N)mvcSMRJQhLm>SEr=sJP`T?((s#=(-=(257L zp*a(*X&t$y(7K3G#bQs;6Z0)7>>tFIs_#nmi7{muKBkd4)X|1zC~n@6d)CRxcmR7| zUc@sRWeR6Nzf$ylq&`v8Rq7KCuEz|^P)!X#V(9}b99#$Sm_5WdZ)LEoEuHe3qkHNr zjHDQ&&7_R>CKY}Rj6IG&h+z$V*tFHH)lVF?d4@OogGNuG7&A4sg9AbT$?@bsFAgOx zm~|-C%{t)W;VOTRA36iCzf1iK#e*{O7>*4!d19=_qH-9EGHfnt9;hw#Z(;zvFq9;X zW%OeI5G;av27+T4Jz;F44MmMpAciQdx&K23_%+*O|#ws|!* zy5Yw07OTvkD9y&GeHpiVCCAte?SQ8&BmH@Jd!lf04rU5abvF&rux;P$i-^uHG$7oN zsdg_hI*%jR+o&^7`gtij=QKmICKf*$(3*~>Yl&R6i20_LSo}yVejL~ z{Ze{HdO~_sdO*5Jx=Ff5xq=D&By&3|u^oB!S*H~+mxZvK0j-2C?X{sh}``5Ai4SPK63NlUUKu_UF7D!+sVy;w~?FwZYDSX-9T>syS5mY;VN?V-@Zcp z>+%AOE^=dZRz61O1g75ze;`{#w@%?|@`2N2EeE(k`zW=Wm-~YD> z-~Z>u_y2X^`~ObF_y4WO_y4WI_y4uw`~O<;{eMmP{=XIY{=a4T{=Wu%|KAdP|6eV> z|8Eh#|E~()|5uLh|0~1y|CQkT|BCVbe?|EIze0TfUje@VFCX9k=f?N{&Bgcs<>CAP za`63sGw}U?8TkIc>G=M?Dfs@sbn^axHY0y2e=7e&{;T{xy#K!`zb3ybza&2gvj9Jl zACn)EAC&KbS%915>*Oot%jJt<9^fqbbomr{L>_{ffF9W+cgkzzRWK8O1p2rNaQ9)TqY)FH4Kfm#GkK%fSJMF<>^z;OsHL|_2|^AVVbKs5qY2vj0a zfj~I|WeAiaP=Y`)0!0WEB2a*U8-aWT@(`GdKrRAv5SWd?ECgmEFav=c1hNsxLLd`? z31a3PR{fQ*2IfQW#AfD-`+0(Jy! z2v`x|5wIY@A;2PFW?9CL&i|9-hfsvg3!ncdzazgP|5kn(W&oa+pOC*VKV&uWJNXPt zEq5Q+z&4q$GS4u%nVl%x!T$>tq@(jQ+Cvrw&OXU!{l2QQ9$&e~UFP=}yUWU|s@>H- zpU++F^OaTf^i)^&6j#S}B1VkkOb#V4K7b(<#ODmQ&kyy3&G~G3d3R-{x2)J*U0DtW zmzH|L;PM`KxxcEoyr;Olq`ab}0nT~p@r?8ZTZ5kA;K&f{E!^z)22Vv>^|H|iCE4=; z5BmI>1)b!C3H9_reEc9j$gmTi2^2o{s53?hv+?G%>>zASLt=eIbGGQ%btq*IOh!ko zw1?~rla_b*YH9RyOF||1C_khXPFFb^YU6Uz7)GC*h9i1@Xe-#A_YDR}Ogj%TL}JSI zrlPY++P6TA%su27iFM>oC^>~{*>YsGj1~hijaoMmw~zUu)-BB3qh9C4tWMo=Mh92P z1_kVxfc@P8wVHD%wQ6`~P{^E2rFR@&=`m{2*ob<3<{tFv$9FI}N3r%ItvTR2ixjXn z34600>T1TJ)|LM3rJXXB+~XEKg%rA3=`FqIcArOAOkTmzLj{a`Cm zdob80JC#>+$np&8N2@86k59{k+Q_M4rXQW!p!yHU^)yeb6+5O89G!l!j@F)ph6nG% z_#C|UMyB!b2sLndl+I9vg$@nejZFH{@w?WD19HALV-r4XuN{T@l!L7S?a_6c@L75w zujY{D8TehRDU@%fE{9N`a&%ly^&gP8X`a(e4IDp050TlHDC|nDmpaFop6hJ;+|KD$am4SEvf8+iC z@4^=Vzk@FTo`1*jTSndC-^k>-r z|2nMoza;%adP;g6R{9^5?v`$qz60z0m&3OJ=SU&xRB1#SlzQPifDO_bsYPm(>ZIf0 zOMp_zEzOp)q;x4ok|n#uieHJJiXV#~iu=X4#Mi`E#23V8#V5tb#P5msi+74Qi`R+Y z7B3Yq5YHA*7k7vOv0vOMdc+Q~U2GN`#9DEoSSc2ZdE!hlL!2xoi%yXfz7+l?{6%CIngONImefde>wi*c+c^M<5kBm9Zx%c*!4$l6i{a^OK*x$3i0acm!m+(Ns0|^f#Jdp4} z!UO*YJz!?ZU#dlMD7shup zcT#)@#kXU87jqlMw^Doy#cE~R)c#g|}wIdd_^7g2m6#(S9yC_bO!^Dw@M zIhW#dDBgqd`OMiApGEO*jL%}uq&P(J8D!`8=>(ld&@KyWGVR)l;i(v&g5W7TFgzK< z?Fa_9VK{oHu1;QF-~uEB6Mf@|6_Y{Re>!M0TxwqUpt z!PaIBn=o8~VAFC88!=pl;EDzemtt6t;Ibtc)?v69!G>B4Pr$GS!6l0@JRZa25UgE@ z;Q|cjBe-ZDhSeBWAy`$3VFiZe2$q*&Sc+i@f@Q@R7GYS3U`YXnZVdAgEXE%I6wk$f zjOlY(y!<`~QpZ{{JGp|GxiH{SoBkN5xQ zjMM-v6J6_y6bN{r_|E{{Ojn|NmUP|33%s|Ifku|8wyE{~37y{|vnUe+J(F zpMm%PXW;$+8F>HybiDt6I^O?39q<27w<7z~@&5mGy#Id+-v2*Ev;RK{9*>ihD>(uM z!2p@VK&Q%O50RB>a+C^MPCjf4)L6W-_Khd!V2K(LchSRD@aj0`qDCO~=)!{oSPdVw zECX;J9o3~-hCd9ZL|j)gsu2g|&BlUcO0oAe{8??V`-s{x}c92I+HJs6Mehrij=a&`|6Zh?DE-2I*b&qja0 ze;^1WgDBb&iPLB`W2in-)o{Rud^3?Ar5pn-@}E59AMQm* z`@3loIy<9jN3DTHs~*FgquJ;V*tqf25aTrcs5H(4vt=Asa6DcbhmF`B@Oy^6n~WM1 zO&Vv-{D2G|e{pg^=8vDQV$)#I-xq!u=zbox0MTjf?9~0#7;!W!U1vjVla7&!jHeGf zJfc~|YvFil z#_`&FP%(1I@qz9M?S;EGJJk~mG(F*{CLK^i9#zees;N9BX2v2`3p zN5@mDqu^!DYeCp82E-#A^adJrBWA@mjTuM2t`5SeZ@SUMZE`%}caR;}f!Z*RDl#6g zjH5>B_V|2;%>*TAn#!nAd4y{@UK__x6vS)ss9qgUQ9`EijRS?Gjh9$CAWO$l#2k>_ z|4nfdPltJ=JD50}Pt82GA|@W+j>m2WF3^UzB?OOfw*v3~>G2LW=vpSRE6TcY7#Iic z#qk;oZZEnG8?7OuGAX}~aBLh@Tqw51v~--t$(VK@bB`Qtq~O{pCUD$GO|+fILd-;4 zee6d}367YOaUU_!b{-266K(aeA2FpkVoJw-#6;V9EJRGS)&CU{6By}s>z`JUlw%>D zB5j7%j)-z;N^y)tTVx4FEz^H@EW-1hdZSoVkE53PXuY-T+YbDKej;Yg8JFW&k4NKD zjaoa$#Jk>TH3{PfTFVDNLWB4JsUSxEw4O|u1k|N{WzooR=F^a%0;%XQ9JCn{)lG#43jxuVj-#kKd>%duqcO4#HC#LT z-!Opg9~vBhrJuw24Q4E5$|hJPU8DTS*RHe>^$bLW7yjeJEE)^CpCTG zo*GYetXmd7z>Skf<{?j7IP&TkwvD6uAH&kP`gwT&pNW$NN*;H`-z}ybqAfi(qoEx44dvtE%`oaI7H!*jjfQATkJ)IT+quG>bOd3% zMoNU4>W(F)AR4>JaTFauDgNss>>zd^AJvBwH1b&0V{G~{7-z->`L7GLgVBnHG85iWgF4QX2Uadm&9ye++$IE!l z*z{vC)Qk%&lF4lwFjjoYmB=azMe+&)Zpw~uK9qWM_yEsSGSEJe*$Ad?N z3+6W98|<@NgP!5w$k58+!Oebea7k~UKaf2yvxBDAjtmb&fa#ea9qAAqyF}?rrk~l* z$nVR)knfSNluwhl$jx%OJV|<8`muDIbh$JvwM(Vabn$EPHSrnoKJijwm1TSRb%nVBKV0YAxiy;$Prz;CJy| zd^yirUa{O}>9>?|Uva zg{C#8X;8HNOvM1tbeQbC(RXYHhqwA|e`xym@4oN*pQ?VI>54bsreJ@cnzOWzXWC=r z)bAb-27HRT@+~~GF0M=gZ$Oi6bG+G*iK@2zUY@Bp))xMPr%SP|a1+n0h{3J>L`}_5 zypd;G#>{{$QnTdt@Jx-#W>`&RZ)=#c~IfhJhM886Lgk^UAj`SCwD!n$cPf?hB7K^ z-a4MC8-*3=SDACx@=UqvT)k&hrt&pWEl1C(Go(eaxpFnnYyd+v-AT-B$dTcU?eS+s zrBO5HwUMGnYYe-zSuwAmm1i0a&C?Y}UxyoFyf|T5VIb4!pK;kR;g^+wWzOxR_yoq{KGnp3lxnr zP9U9U6c17u=BkOoh4iUh*^7uia!t5S-+Wcy@kCM-57HOrIxYqm(x-BzF65bXRPDV! zf4672TG5fRfM+HHos=m|o=?a`wMw2ik7v?=8^^$GRYo;oh6?W=98k%bRXkG&E=9Mp z>k3$^WX!H4PKe+@#S8OP81kUPsXWumN$3VQ!8Ntv(4D2|nN>!*a%?tyK|2zJdu@`rVR}G`~?Q-xrOBE z;opYdp$fd7KK}p;Km*ok1?XuDoi<{1LmB!4T1}a5;%-t4MgnH#6E}1Z`#oER278f0 zr5n&nnv;h*M?3HF279;p-AV&9Flp*s)Hwp@NN`iZ#u3jjdgq&?xF;=F-_^`i5+=?e zVT5z2)YRD|MCo4K6oor=7NPffc0kPqRQiOOq_(_+!+w=Gbq2L)XeeC4YHCIf&$yAj zkQ(luG%~ZYNsa0mP(Z3Ova$?WJX)4aBNi00s+1WSq}76==zvtYQm3P$+xehBfC5ia zTry=E&*T6-5ZnRpN(IP1HEqIF;uak-J)LJ}LWZHiz8yWieK>N|9H~=?mVQs~fL6=o z$t3c7AtFyMK<2Airc5FR^myP}tigc-0BTx#8qx*N#PD=L*t(Qd(pP}H{F(wKr|`@K z$OGvr5hj+lBzhHAL}FgZfVn4toat!LE_su7Qne z@`PjvHM@=Xdc2#|cbiNX)DHu04S?-Ey&DVgxARD>A~ih;!br=ZP0Wy?rD+pUv}hSz z5|oC4&UV+1AO)a1uo{&D}TX-J)ZF zrSGXTK@sX*x@fxrjr-4d@Z*i?c2a~bp5cBEMEgJwWL3&t&2gTe;6V{_01G3 zvBxv8aiq^PtW)RWNx2HPg#}rNpn{FP!QPDn&=eIF$sEKX*oIORS~^Q?D)9SygM-7w z`%2<8Gjx?;Q$hFe;CAS20)4%KVAzAHCg@F&JZhPeO#~lj&I$QEc3#D}NQ}Gq?0r6t7S6nP+iM;Tk@UrkdVYkpK3@IL)tTi07>@qgnV z=lAf<{1nT6%LA5OmKBx?OB(kv_dItyx0l<&b#ske88?mN**~#AWcRT{>@s#1%b5RQ ze#E@jyxF|OJj3+Arr(>sYuasUGgX_Wn^-7}!M{l%7(!1oLsXG7S<9H`6&Fkj!GKwl zRH{vav9TtpM4JSIU`^r4AVL4eL82(a=^b7aQ zV_}P62uyWpd9XzqE*J$HaAAv7uB;FYgQ-6Ko)qSXVSO+TrjoQgSf7Rq2EqnhSf9$3 z6@qav)u%sellehd9~uM`k863bJ`EQPgAKT_K9wsg1jAsePk-7h^Zl?sGzcd8v^-d! zh6{$l23%O5$~7?r!{8LCVTh z#4TfH!DZHDf^qWLnXn5qnP9|hkjY?niMdg6Oj!uV(e2UZMPb3-tyuQBFRj8~awhhV5bKL#^;9B4RU{2zl88>-=icY%d4B-TfI zILJ>@OwA6#O97h4)N|rCp)$<~!D~TfG!qFMm2GYaUJYuaw8HZ!d`6neoF9Uh1T?`N zp*YNpilnksC2uhTt_wqgy*D0Ns1Sy5WsTBT>tTb!#}`)hGrh)~#~R z48a?dMz?l=0J_f(>xLI7jYKUU)~(@$*QpqsShvdQ4mrqEkk+I6{M6TbNU@BX{Rbh%Yih7c}_LtL7G&aIj4{*Gw5oJgJr9taqbTC z0Eoefq^i6VPKGfW_!4zsVd8d`SQ;j7Q;8*E;)qHtR*9KG)h7X6I1ecnW(U;rYB`Wk z!aT!C!Kx9`-zTyYm+3uyeI@ zfn$#I+s;fU=lCD{`LN%j7lHvZtA!GGE7C25Dcg?{ep`zhLiY_i;N}FT0d2~5j7|0Qg_14APU>8n&O57>O3pr_5#t>*rcrnQ!QkKkwTJnPDC+k3U~-Z0{RijPOwYokZyNLI6t2`{)>7#nt~BP8WG>5W z#>2{j%|rf;%s-faxwtHo8BH7p@DyPx^D#CbQ`~)?Q+81D-!r&{CXyFUTpot$V#uMk z;**%0t)DZzdDBd;o@!9JqFy?ghvslAjJd)?VyL&9mD>pIs z8?i=>aKV5Znfvm&_9z3QSg{E=GWW*CjE%UFxo0X@8R<`Yl=Vr>jdQtnlS#7-u6UeY zX%cq4f6&c!jLNEYseho5>xz>b+3D|(X^8$k74{DG<#X$dMeA9SvwU0PWJX5#Hs^5l zhLXc>=<1!ttuW@%mcMJ$9Ij<7Hl(v_Vg4uYI%uO?y)i+A!x?HYRVNzE4 z4XsuY4BppTsws; zH@1J}+Q|5eS-xPPWlaIMLFdVs%qX^7R>#ebiq+Dd&D9x64+nR1+f1&}kVPBY&8@S! z<}tXC!sb;O-0?VEL!cndgplpXfpTq!)jhC z^ABtuX)p?RR9grJ)}AOXW-R7uT&1C1@JzXmxg9smsLdzAz=GOzcqW*lQjn<&PB2bG zK3PzMB}Q#82?pjb!nvYSki_}N8>bI2~eMC-$->DS7;(x1N~^Gy5p-lpX{AvLvZJ&@#C;OdvBmEnN@f0r<4so& zntDfhR<3h!DMbIQQW1B;dUkctva$pB;rdiLyRw!l-ON}_ctocg%1(yH8!>c4=Ukt} zT#sFaH(tyn;&t0CW~6d%lS#ja0ybIX;5MTtqk2rqHcCJnDzXd`P+g^D;ur)`2Ad}` za=GTHu@{)Fsc)o}xt_UmY)+&NIPY-5sNSUA?Jy}B2K6S*a5*5Q;b^8i8&d7u1ndJT zMUsmdC-oy9WRu8I$7bl{zLS`nNJ!|nF-&l9X?7FdypWvD)kf8ZHtJ4dZkPcBp2!Ld zv!Jq^#C!){|1u+)wCZN>X zg7lT;Yq3P~TW$OT{$|U+Y#&P|@m=v*@jm-p_zoZ_uH&!f_p{Hi%h}mt2Ae8;ZN5=> z%N!D(G<$^ySc|aNTq_KjbA(l9i%?_!myl)JFPKcvINvqh?)lh4#-a%WV&G6Kwm~Pi?!{KU$7w?_@7x1C|o&t=99bgO-`r zR%@kon*DE-hA z_yGE0rE6viVe|lcQc#jD4p_Y(Jt45k5K8HO^aCA?Qo0{~UtpB23^3k@9v5%P5Q_0W z^q3AtG2VwB6&Pj90*v>fN5oq)gkroGeNP9Y81F^j6&Ph}0*v>dhs9emgkro0eMbkQ z81F&f4!J6*ULZ9BJtQ6=Ap$)p9v}?@Js=(+`2pQ89w6lb-6tL((E;5n9w5B|-6NQd ztJZWUx?38eGJ)C|F)v|lpIN!s6#5w1B> zRgn!CrDI{p0gOak zS&;iHUHs!o%3@9K9ibfc+gkJxdP^ukhEU}^g#M_5QRO^@{va@_-)^G^(VOBe8A35W zh<>kwQH&3w-^tNceitnM1@wj-J!L4x`~v!|9h_o+0lh9`x5TUG(QESCGL&L}9{t7+ zPO(3aemxSVEF==jQ3$r6(G7H*X8{nT7oqEQAcF5A^eO)gM5n1NzkWdlEC@TSnd5UK zu-f7fgU9OW%-SJ09hPD%rqL&nDLs`wiR9sN^htaGu!thJX3RIzDG2Z_`)qf7e>a_J zS;|R!_Q!P)(wzMV>BNM*qwQ}FTs#p5v<@3M!EoRRb#A#v#{ug4q^M)R_}OsaBB2L4 zcEkQAxBDx=b+XgQP|^&5_qm-Uk6mD69DPV8Co2*nL>~5+WOA_Cjy@=pleG)v z^046~lY^Z}WitaTul$qtmXHz&VMRrr2%l}rwj0?_*-L+GTM_Z0FvLv7>`ia5mQ z9_@4$)O?Z>lop*i#x);85c`x!GA^RvMayh}grP-eP}(ARC6_8!wbO3e1SBV|-SJi1 z==z5SMo_M5Q{v%*RgsS%)<9T)Q=`~|7TP512W$k(f)$j8-3LMqbnRJ)43=c-qQg+9 zgJCk)g%+%gR-+H{Qn>{SS^%&w1;7XcXgvd^u4PPZ2+GzWI}=z3%*<#IPhkV*bbqA% zhWI8R03|P__9RgHsDrT&T?ahfog6m7)2$A(BcX#Hf%@C(vV@XUsJ`&R;kmb$-U#<6P^U<&1bg<9!>xJ$T0ZsP|sq67N@iYn>l< zUg%us+Gl*<_@aBa>mROPxt?^lx$boRr|Sy$Mpvur6j!x-t#h7pywm4?!hNrMj(e#4 zbM6njgqHA2hcU@-EvEd_+9U*qrI^ z3c7K&u{E>Gw7dAvjH?rGLZ2RMEV8U^C4&sQWs+OXWCe=;vr~*!RvhZ`A%wWwHQcI|#2VvmQ;oIh(b4AL+GjP&+*c}%S`9XI(@Dm3 zON_gq%2=rGdL=Dx^EhLP1(uXTcl^8w#xh$l;bT*^u~x0XH`}C6w>!RNnz6pGTBPyk zM~#V6$_Dz&aAPKWP9|)iKZlL6PO)!-{zPm*xVu6WeR;gGL&^6Q8oUWoQ>wPuG*39Y>9`@R?pc-Fy{K6T=CM{aEA`$w zNhSuO|0QACk`{>mMVggLdb!W2U_0wX5bEyPFk@!Q=2_4fYicegI5>r$13uZ)($?|6TNQ4|OP<_CUACdKObIv?Pl*oQHIkk}3 z#3W5Ih;3qOF;Ue7UYt6s9#0^ARdif*Hd-bvtdE7~MnY^%vT8o<9RwA&KHH8ud1t5_BQ{2FTRKG3li*@75K zbYK?KO$nl9v&7t!fN93QDskmokCs;sk3}CdZjIhwa7}Qgf1PJxFz9|g@Q(XOfuF}i6+n=DFAE$A&})*OBM1a6vIa->EBoB5v8F&a7N^P8$kCaMlbOk^WLbYFYn&MS4#LQKY}H0aBztmylXkxnGvvlR*^eOEy4?^k))Mc{Lhj`cvsW z8AOr3Xal53e?mGupL&v43TJ+3BW0}CI-JU{EPc~Z8 z)S#UGm>alkBhb{RxE;&Iw3$EB04Sm#k})1{qF@I-$+64E0@$D6NaSLQ{RbKV#r}Pc zNH!2a^f<3C7gI!!X#f<_qa2ZJ6oBXvUSBSzh`y%*P(d}4tR~@>S|EfjzaCYKSCk5=>&8f=8l%2aY z0LspPli@rBP;;{keTx%`qdUm}+_F}`l5}^hEZIGF$6Ls3&st0ftRR5YjhF8DnWK&Q z8UW#TnI1&Yok8Z^9Ni)^K&3Pn5JoLK!;NHkNTI1+a040hCO1dwXq!@wM5_%MW6f>r z>4dO31cT9{JOm?SX2SRwGTu;zU}O}aA2W?I8nuZW4hP}J90z4TU?P(@GGGcD-d>D9<|?lT}4M=t{CEpQZ|J@`oi!)}aqbUB0XhXzq1VuP%eAME}DE zNJ)HBBGG_8B$1Fc10=4Mu*e`v;uAJNO5)=ZiF(K*K+eDOhRfOk5+6gzh-yHT#7Av_ zl*BbMP!W`@Iv{a1RCI6>GKiA+hz*dExJm{>z5sH*BZt!PZ$a}Ay==RU@Xyfcsr?C| zy9_|nQbC0382}22Zo?)N0VkcBfYTk{29UKH2tnKiuzCSo1rJlj!}Q1$R7uzx13x0k znX9GiiF_8FEP5jTDttjv3&lf~jzrfL!_4|_Yo7~UF%;iyEhfCK0Kfl>i_CF%<`U=Hgt-6*k}w#hLID|2}~TFBY;&H&I%)^pDRc32s!H5Q>bAtqI9EKCY zh@`D22#E@n7)}Qp3l&6inn`UU-Unxz0jHpQ%RJ^G@%CiA7o?F|hfXl0S{G_-(V2!> zYa-rb(zEPFJ(#4o+r%W-q4cC$o!VNIo>{9J?^2FJl<~pb=>{5X3c8cq0pAMG=TQ=N!r^LjB-6nTdLV^Ta(f@YgXfJ3T=4_31~l;q}`@qlnv}L#vl_<~+VU(LXdh3~-mGAh z>rvWL>$)Qrc$CYP?CIEl!~|D(~PDEigt_Gne)wn$6()$l2ydqR_gIPi90rT+$KG(o#2d zdB0EjWq^URJ!d#$dl?P`+e>ZOW*Md#am}lyiJY^Sn^+OnM?l?I6F^6E-F`w)FZ@ ztB4&fTW;*Cb2f%Y7#lRM)#l8G*jUSwo#bnrtw@-$MdSb6ezT?Ql4Zz~|f`6hJs9RRdHZ*c5ZC)iv+V_&3uKkGd{q?R)gKZ&#Zp) zqs>0gkTIKgIfp0tnZPEJuu#))23g-{Ce3HaTFP6TDTj|S6(+%9hQbv6P9RNWU~nnt zK0Pa%>YRtkUZ%QQ><1=hDokV(p=>@5NY9o@!1is%WrxR4#)&&O1B;Udi`uS4O*6Np zZmq`1Y;{vIZLL6NN}pu<8gCLBW*tVL%S8zs=l}xa`y!BWPXvTg>oS7N4N7p?5+FE^ z5KIvoO~KR3i9lI#K1?Rlre|7Ev-yLyJuYGn8chA9naq z>?$ed= zZ*F5Gqc7Eb!1gRl6zOouixr}tf}aq{eu+V#(xKOtr6F=C-2=#a! z2w_*52tjs)f&^=gJ>a<$s3`Dqx?I=ZhbXeqy%|c)@o;vHN_}6L@OY-ZTD%;zw^`3} z>Y95@IUpdDNYEz^1!L06GHPdkk#ixmj-x{89hD%n?=Aflg33`MNUh9`A}_X=iakwhQ!DFO;qtGlVy3tjlO>RIa*==k>@k&FP1AA@ds&iU z(joKz0Gfs14!;q>&--8X?e%=#^%EoH_!Jac{t~-tL6T0?%SP_#M!hISha)#KU6}|i z83;EW8XY--S`v*wp);6_;-)~Lqo*s&k_T?I2j?VMWIz$h#`eduU1d`QPqA6Gn~krKKGwRGnxNXC&)Y>U0G4%Ewrg2xK0zM=-XTH-S$3}YJlB2Z0N z0@dY(6?$DUdzLyPbUE3*$bE-~z7YD!%+Qx5$d1;<1(bOaBa+^=i`q5lSztn^`~T=X z6b(lvgolSt3Owicdmr;$?LN;n)%h>S?EvcMUt-Ov%!fu{lA(+q=|i7vRnwg0sgLxa zd1AO`Tc{Oh2% zD$qm+T^U4o=SQH0FiL9r%HW_NVoN2%B~`nSNvac*bUSo=PLj%Y13A6U2{yF`xn;Lt zvdVxQm)YC}LS`hJ8+|h;nUPy=^KDobsSy%cu0o6GX;FaXk;T@u)VRo+<};CX;VvSw zZwv^LWxb`8tJGwITyTr$F~J?h|N1JMJN`3Kh}o`HCqbW)qmURx^-SEmUW6c8L*#{)|vd|5K0RuBrZO6BE!95VH5L) zI2(E1)`u$7+fk8wD}KgiKD+lmyDUzVNe^Gv$fQ?;my%fWhZ@i5d&LCjHGPRi$R_6J@-t$!!1sCKUNvcuOc8IOIF- zo$bETc-?tAx~ZQN|2)3dJ8=b7$QACy9HNjnvQvmE4E+?pQS@`>Ru%7AnsSL?IZ_rZ zD8VV8T>_m>SeH}Mh(gN{v!LFI%M~5HRzw{&mP|*ctmLCw@;iXdPDeHj2_2oO=;+lV z>L|Np2Gwz_@hdx#GzizuC4Zp^3<(`AQ*`u75p|SZmO?&7VopGE**Yx(LqbPqC^~w% zh&sw{UYJjjX%Tf)@bz;u%3DV(HhCAN8#CB2#C0_MbgHA?uEb0- zu6w!|I?CHzB+G%MP*s@>=CtfEwItRoVQS%9c25;TEd^Ht3~P%%C`+L!1iDxe=o9%D zXu*e94P;ZO$Rj8XO(D?J6oEdTe}NW!ER=JmSU6*te1~Fq9mPhW?fV z1LQ2$EVh*WtOuGv2+_b%(3PSmV6GImJ-}ujTZIXVa4zTCp3! z*{8FNj_varc5H8Kt7+)ysI6&em^Z&>{&q+ws@=Z5p=rmC`OQ0O=i4l3t4H|S9A}!# zyHr}Zo8B|fx)ARLo@W`2joX@=+Z$?Y<~KJ2!}ay;z;NS^n#PWKwT(M!8|xaI>RP~w zcC__e*uB2H?O=D${==t`=IsOY`T=^8L5#L9 zdFpY@riGJcQMBDh_EWUm8Rbdgz_DD~9v?-HT5ZLCgeqs|PfO{~EyZ>8D1Sl~PFF1k z*^ETg2h$f-LU?k3fgAw7XO_@FZ28R5L~QZ4k0580w(bENnUS-N*d4ixPpaTl_7sLn zIvcQMYSVD)9}DsNJ!nSJb6!cBvZrlElZ&W5D>qr|%!**+5Gu`9(AAV&b!DD4M-_ERlw)qqBjz+p zQmNx5^Z*aVW$|bQFMuy|V1sSw~OV z2c@-ipz+03S}IHZQC=#RH32H&C7{G{{Z*oTF!(M%$G0SBd>Z}8l<+KiT0UrF@)9(z zINIR!vl2ajXT6sS2ClHLtm?0zQ;s@6NYBATV2dPHnDKv4Dn-2|YR-vlm$X#Y4 zE8)v8uAztRw-Qqy-CqsJN7wJ7XXyjJB{}2M$X%v{XF0jZ!PG|=N93G-R?_D0Tx-^3V$;6_0X{3ZGlGu)&Bc^5Ba>_ zk9)r8LGEi^ce^GT4?3T7);b(%F1BU$YOUb74;FYp@w{jI^DHQc*0yx>_|b0Y1~|vKw1`e%;9?8 zdIU9;LeDnb^;_RI_}XVvRggJ%T`qc8SI@|TYfn2l%AU>APO9Nl_7sMSji%ExwP_Yt zG0eH^il}1iLR?Z*5+TU{F7}{yOU;cYDWu8Eh{Zsne3d-wcUOc z)s}&_llq&&&C)1|lAgF&%{?y;ct!TJ`UVqaHWa0LT8KU3UDeccd%#fU=Fd=ccl+TnQ#h%f0+PzeAhhhYPv+s_{2ny7ghpUt zE=SElfMRZo)WD>_|b0Wu$K#7I%*2DsMZ2YD%c`6!vn|dJ4V+ zV_4ts2F(|KJKUWAk3h#z^v1}yBE!O834JB_r{G0_i~QgAukfAW{h&AEndCm^9^#r| zTxCpjyyFN#<$V3&Pz!7DLTK>nTuhxUw8vv~q7)N%W3aP#_QJhfnj+19)OK>(0Bm$G zL~wn4N%^sHm%KDHF_V0-51Z79YG~=|B07{{pQ}lul$fSWQB>A0CusK9GIpIw<0Bbm zt<0Z=Qf@5AkKi%OIH{fjlFG=kwCuH?!NV|&vR0PRYAnpS){EaWKaIQCh?7rimP33w9GmaPeSq2xn$BeKCHF zoG43d<}mQSw3If(In~KHSBtS1LeGMvy)4e7z3k}f>IQpZ|LE+6oUkhFr8tB$vzNXY zKSoYC751{Yl=i|o)yX(ld$AWnXEPls9ER{RFBfwWyQ$mS;vF&aKaGuyYvQyH7m}8Z zS!BXsMs#h?0|Ub4d)#08$p zlg9N9ZD8SfHG+Fn%Y!i+Kh1B$6Q`cb!h2#qUX9KxqECxNWxTkRT6AJESoDU1TC{YivoPz_BF(LrVpUFa?l%oZiL=h3HULe4 zn{o$S8~W=fsj`#L5m$v~4^fPPinF(3J#(qvp&-!>W#&?vR@*l&W)D)@oqzY!u$fwv zovq_B?_+%r`KaQY(tE096*A#k$GV`+2yR6wEB*@VVOBAmbvEyimgCLnoB`=Q$tIP^ zF_H}6@oSmUw}H{GF9V~8B^`AwHW66E?7j`*wz6Zfu%@3XjQ6eP*1sCJq4fjP`sG%Y z$^m2^u>UOP1C8JVYYOTEV$_h_08P3gTQ}UYidlOj!i^8O$U|4?*3iaZ)V9$pmuUf>h{U-(}1jq-lh^I7-n?k?E(uW?@MI0vd^ z|A)IfnU$?VcvWR*{!E^yOOo#!_IDiY?AX`d0fVrEhu|X!ZCTR#GcvezsB|Qg=-EW( zlwI8Rn(->sSwh=08=~V{8C8p#$)@CJhXSFNvPNx5!nkrLi<9dhPVOq9(a6D@Ma_$M zFneBy@Vc^LtuQ8?()h&b9o(uH;dN-&z_Mz&HN`e;nRd^1X4+(%u)P4LExa!2P0Vnc z+L__fZNlOZ&dx0D7(cd+86DjwY%dF=OJy}*7L|(mqBdqP!@yp)71Ca0BV{IY$_311 zh9Nwxc(nUzH7V>TjIG>oj^SZwTX`9d%x&InM@Eiow@~{@kc`qT`LmzY5v95`tv-qM zF=ZK@7b@#_Z1gnye5yI%IpH1vOlM@V1r^xg7&G-m9Avhogr=@(rD_S5y%S*=Y9*az z=mE1nT6-&;9i?cxjhTja`6+(eS{zl&s&tKj5xgEy!&LfVe0NB@Gujeq6 zf3J}khAu9l{KW`LJGa#q*6<5@>DA}rZj_kvr1*S}dNLW*Oo4S%Wx*aC85uXZlOGi3 z@X3c*Kq6m>b>}Z2<-#=;rNSla=EwA~Fcn8QUcS6$6ub%{o*mshq_yKX>K?c*#av0z ze+gYE)fjP8oDGqq;4)pMcNtAw;4vT>w3!3VJ4h`g5k-mUK;gWg?v%0UdL0M2a~%We zbq!4C%A~a=^0Z7?!}IquzpDVh+gH|pC(o#v>z&%gT(1HpDh3eqrSiTM0rqk*? zgm!cf@AVER{OH1g<#eQ_8QDj%-7QlU;NiR3)Qp^JSr%L2)RV~kKa6&v$iop&C=qN4 zeB2-M9`}xd6aO|EH#vR|puGGg4q#UhIUTKuG ziULzg6kQcND&$FvxCz5)ro?N=hB3OL9G!-Ejv{N;LpNgw^Y<`Hga-=iMRsYu=z5(P zF|SQrM)ZEgiQ}~?4K5qMOyLYST_$lvjb)?U#(|O*dvf~X5&Wq}Jc9QFL9+Um< z@)N}G>gW=zYAI#ncN$IL#!J|Ql=OJV%Fpd;iQCm`+^*>;o08K0ZeTE8RIjrWT(9F| zJ}o7^-LVtI>1wIdsdiE(PNz`>o_B;f9mzAhxcr<>KLKL{%~LL7em4vyh7BCvi|Tr5 z#7E};LB}ituy zF1VSP%Pj@yLD&~e=Dxc6Xh{~vZFmfgK)?=eE-63R#cQ=y{F5xvW=kUz({U9Gvx&(> z?6;Ifn6WBS<0iC zrZzP(2an{IIvs=jZyo@asft|kp@xJJt;r_nsYc7xTdPf|>Q%(cn&80d}y zxP&^3vdrPcfKaVuKNg&bXHrWCcJbk|<~KV7R@g(3AZbGyXV7;ac69<+ye(CtO{Ao3NJg?T7aM8{xwRa2zcAD)4yG9Mv#fuh^W&qw0>JKAUO zjx$FYkE@xZ^dQ_*&g>S|TNDxP!c(}*v}4feZ6}7y@Ftdt-*9g5P&}DA&r;$%UoO1! zKy0Zw*wwW+CVnW+Onn6J#gmwiEJb)}8E}=8D~NWcX>g(mPvjO~i$M`zE=!9y8=`MX zfehQEDt;*Tf=A#9%zjrB`~6aB?N^Rsa4_z8X2kT)urgt-V3sU5J+T;% zxEhvDAa;_`&?9B(Ou81TRzRK#`NgBkfpyZ5sa1me%#+;b;qq`F&6i=qeVS$WDPMLA z?mo66+KroJ_jz~#yH6p%UF?VZXhe?3Vz>gBtXGjs^w8a-ch?Cd}VlA%cezA%u>+XT&7X>`MG(%5Fl`Ect>zMI(66617X^dZGpAN^8$z`n9 z7=~+^4|F2jS)PpM-4!wrOAOED9w<0$fp za98Nz;QGK^f5JE1^B2!j*Go>6*p0HBK|20M^CKF_ zh27WPv9H@KDD?L=YTVU@Tskr_`J&wNFMiBI@dc3nQy{zyFQ<_@F_T2CvFtwO%WlEl$5uqU@oBRAJTZXXr;xev{TN|tL=NtAs^mV8mxue* zlfkiiJdW5&StPqp`LbJZ_puexZhVUDK93Jz_kp95QtY6Fy^luZWd0vQ_n^ov;TJ=* z1J49JzL@7dPlM}9qsF-n0A>0Iv;1?Im9Sa~5zi(- zWfd>S>)9+H7Go;WtK|`(O=hjFNc)Y_Cj35Xbg-_Jm@{D8Qt;5;FX4hmuaiCc)f3aB z3w@wwKSovAstY{&Y{{cvDRYlDKaA6j$2Q@$vPTclwv^7J(+L+mdX4PSubh}3UFh>L z^Xbtx>H?2mEqV0IW$w{7r}nWK)+T(G?9l_XEv575bixIXUL||<%O|Es7y3BMe0sEv zy1=7XN*?{wGWTekL-&M7x5yqnK-*F}k4`6CGXEcfX3F#b>%Bdm$K9J;O~!|uUvRn| zpGMz-3JAeBT-*I5>9P|+HrKoTwWyALhdK{-?b{2R+3}e40ADU@L?l(P)~3dR&&BQ3 z&fyCXNTzzXH~~rF%F>9ersfJF=>deX3vZ*+j+0sQ-|{Z){Rg|Yi;qQd6>j6S;svCY zjd~UKF2EOX9d7_>{H@eF=Dg)c(Ht2pV{fHxB;Q_CqPP01@3#H>W8&(?{cSrt;xTbp zq9ujH@~HowrkN~XHfuLgx6qKxH&M%%U5(8ZNkqHx`E01fHc{Uyj@6RJnFf%0_oij! zp)~?EuZLOyUB*`JAS>%HxX8hMVv_s3Ssw1wM1OQI+l+b-NB8S<+Ch9&UVX_jvQ6BDNyDr%zwj5NMirK6;EvZX z;lliX1M^C@>-NR~_R8eenz;pJnw6Pls~T7doi#?$KuR)V)LD(XFya z574%h&ZE-_m(2ei(N81zZ}4wW0)rA5l)#__1|={kfk6ojN?=d|gAy2&z@P*MB`_#~ VqD!D1cktbISdlHnZaZCE`9F$=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1801.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1801.4.tgz", + "integrity": "sha512-Ch1ZwRh1N/vcCKHm4ErLcgZly3tlwdLUDGBaAIlhE3YFGq543Swv6a5IcDw0veD6iGFceJAmbrp+z5hmzI8p5A==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "18.1.4", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.1.4.tgz", + "integrity": "sha512-CCoPT2fFw1DD3j9eSP3GKbp9KfvxQQfY6kV2aec0pqL/c6byz4/ku+rsV4lwE0N/dcaglwhttq4Xf+u+pkEpiw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1801.4", + "@angular-devkit/build-webpack": "0.1801.4", + "@angular-devkit/core": "18.1.4", + "@angular/build": "18.1.4", + "@babel/core": "7.24.7", + "@babel/generator": "7.24.7", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.24.7", + "@babel/plugin-transform-async-to-generator": "7.24.7", + "@babel/plugin-transform-runtime": "7.24.7", + "@babel/preset-env": "7.24.7", + "@babel/runtime": "7.24.7", + "@discoveryjs/json-ext": "0.5.7", + "@ngtools/webpack": "18.1.4", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.19", + "babel-loader": "9.1.3", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "critters": "0.0.24", + "css-loader": "7.1.2", + "esbuild-wasm": "0.21.5", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.0", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.2", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "magic-string": "0.30.10", + "mini-css-extract-plugin": "2.9.0", + "mrmime": "2.0.0", + "open": "10.1.0", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "postcss": "8.4.38", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.77.6", + "sass-loader": "14.2.1", + "semver": "7.6.2", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.29.2", + "tree-kill": "1.2.2", + "tslib": "2.6.3", + "undici": "6.19.2", + "vite": "5.3.2", + "watchpack": "2.4.1", + "webpack": "5.92.1", + "webpack-dev-middleware": "7.2.1", + "webpack-dev-server": "5.0.4", + "webpack-merge": "5.10.0", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.21.5" + }, + "peerDependencies": { + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "@web/test-runner": "^0.18.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^18.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack": { + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1801.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1801.4.tgz", + "integrity": "sha512-Srhs/PcnuUaMiO9FLQLi1QiGZqtnG5NTpkufjJuWxolSLGNRmb/h/ZeCYgRnxeH/4jd8GCD31RD78qy+pviiLQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1801.4", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/core": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.1.4.tgz", + "integrity": "sha512-lKBsvbqW2QFL8terzNuSDSmKBo8//QNRO4qU5mVJ1fFf4xBJanXKoiAMuADhx+/owVIptnYT59IZ8jUAna+Srg==", + "dev": true, + "dependencies": { + "ajv": "8.16.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.1.4.tgz", + "integrity": "sha512-0ekArCeYqJngCKWZ9I+RtNObP/33zGkzWdJOmCB6nj9/ZevALZ6F4RDkHp0TqDYhOt+A2muI29ZK/cILmKA+sA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "18.1.4", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.10", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/animations": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.1.4.tgz", + "integrity": "sha512-m0yusB7BI3wrotx9F9rf7YUD5bvhF+lT2fLNF1QCzCU819rtLnDoj0b4/z+D0i5qe7gQjtAJ42e/Hv7eGuq0VQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.1.4" + } + }, + "node_modules/@angular/build": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.1.4.tgz", + "integrity": "sha512-jkqccHpGhxUOe0zIHpA1nPdeuPUxnBK7Wvazc2rA+ccI30BPrROkEDbrHP8yD8JeviUCFwwLE+hM+rRg+NneVw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1801.4", + "@babel/core": "7.24.7", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.24.7", + "@inquirer/confirm": "3.1.11", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "browserslist": "^4.23.0", + "critters": "0.0.24", + "esbuild": "0.21.5", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "lmdb": "3.0.12", + "magic-string": "0.30.10", + "mrmime": "2.0.0", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "rollup": "4.18.0", + "sass": "1.77.6", + "semver": "7.6.2", + "undici": "6.19.2", + "vite": "5.3.2", + "watchpack": "2.4.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/cdk": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.1.4.tgz", + "integrity": "sha512-xFOg2wT2iLyJXqgeNRK1uF4Lxn0B1wzBjaEQoOwFm1EHOdu5D4mNOTwfuB3DkH4KWM+mI3Qtxd7vOhOXNwB3Dg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.1.4.tgz", + "integrity": "sha512-ppX4iilA6k+sKD6iRMRYnt2bH9Jpik+hJlndRBCjWo2EmEUQ04CBRKYONh8BLbnmwBxPG+/osUpcFrbkPCjQUw==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1801.4", + "@angular-devkit/core": "18.1.4", + "@angular-devkit/schematics": "18.1.4", + "@inquirer/prompts": "5.0.7", + "@listr2/prompt-adapter-inquirer": "2.0.13", + "@schematics/angular": "18.1.4", + "@yarnpkg/lockfile": "1.1.0", + "ini": "4.1.3", + "jsonc-parser": "3.3.1", + "listr2": "8.2.3", + "npm-package-arg": "11.0.2", + "npm-pick-manifest": "9.0.1", + "pacote": "18.0.6", + "resolve": "1.22.8", + "semver": "7.6.2", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.1.4.tgz", + "integrity": "sha512-No4lCrL80WlAGg0DAyuPW+jsfA6EIQ06CFrRgt3R6YFrKbIuU0NKUt+D8IB7UNgTLNYXmurxapNf8jef8rq1wg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.1.4.tgz", + "integrity": "sha512-Xdvm9trEmrWZaxCk3a7bt5kN/jdXBPukVsibFpu5lKl9ZL7j2sn4JUd7j/dVNRUIVsPahQMATAOgl8xdUJzh4Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.1.4" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.1.4.tgz", + "integrity": "sha512-wOOLzxPLsDYsD+f6Bqr31ol8K7I4cm4k5uuaQl+wkLBpX9AD1rMi/7CPJrXAWBdgOW67uPzAdLBsK+axKfg91w==", + "dev": true, + "dependencies": { + "@babel/core": "7.24.9", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "18.1.4", + "typescript": ">=5.4 <5.6" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@angular/core": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.1.4.tgz", + "integrity": "sha512-+N3oWYFubT3GdCkBfD/CmH4DGjr/fGFQZChWbph2ZuPpK7JYNgfyvXS4SjLtdL4WTjjBevBTgR70GyLH/5EbKA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.14.0" + } + }, + "node_modules/@angular/forms": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.1.4.tgz", + "integrity": "sha512-PYaQ7/2toAwgJWIznVWgJAd3l8mjAreilGOVIMbBIaotL/EHRQjhlikitJEFDGXeVUarY/rm3IlLWBYnLyliyg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.1.4", + "@angular/core": "18.1.4", + "@angular/platform-browser": "18.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/material": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.1.4.tgz", + "integrity": "sha512-xmKIVOKZA8yFXrw4PsBvShFSYFQCnuVNGGuJlc8S8xvURh/f9P6hAo1Ua9pSBkOKz2W2dHE+726zOqL+o4kNxg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/animations": "^18.0.0 || ^19.0.0", + "@angular/cdk": "18.1.4", + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "@angular/forms": "^18.0.0 || ^19.0.0", + "@angular/platform-browser": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.1.4.tgz", + "integrity": "sha512-zGx33St0JVYT8EZOaf0s8Twr0RgfU2cqEAc9Wwx9HVJ0pF5y4VnftK3pewwiHWDHkPfiJy0jBKbtrkVUSbgZfg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "18.1.4", + "@angular/common": "18.1.4", + "@angular/core": "18.1.4" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.1.4.tgz", + "integrity": "sha512-ZQQcKXGIriOzILTZxIbmDpGnwuiwfJ0xh2EmmnfC0zh/NB+li6whgplOLEciaHgsUKtDn7kNZFn2vKrx+B/cDQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.1.4", + "@angular/compiler": "18.1.4", + "@angular/core": "18.1.4", + "@angular/platform-browser": "18.1.4" + } + }, + "node_modules/@angular/router": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.1.4.tgz", + "integrity": "sha512-982+bnO3uGFYjRFcQDoKmnWvUcZUvFxEpX/I2Yu+WmPJrY7fPJ693mBaWgwVFa0xIBNfjvJjNXdikGBz5UrMsw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.1.4", + "@angular/core": "18.1.4", + "@angular/platform-browser": "18.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.0.tgz", + "integrity": "sha512-P4fwKI2mjEb3ZU5cnMJzvRsRKGBUcs8jvxIoRmr6ufAY9Xk2Bz7JubRTTivkw55c7WQJfTECeqYVa+HZ0FzREg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.0.tgz", + "integrity": "sha512-q0T+dknZS+L5LDazIP+02gEZITG5unzvb6yIjcmj5i0eFrs5ToBV2m2JGH4EsE/gtP8ygEGLGApBgRIZkTm7zg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.0.tgz", + "integrity": "sha512-bIkOa2ZJYn7FHnepzr5iX9Kmz8FjIz4UKzJ9zhX3dnYuVW0xul9RuR3skBfoLu+FPTQw90EHW9rJsSZhyLQ3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.0.tgz", + "integrity": "sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.0.tgz", + "integrity": "sha512-dG0aApncVQwAUJa8tP1VHTnmU67BeIQvKafd3raEx315H54FfkZSz3B/TT+33ZQAjatGJA79gZqTtqL5QZUKXw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.0.tgz", + "integrity": "sha512-CQmfSnK14eYu82fu6GlCwRciHB7mp7oLN+DeyGDDwUr9cMwuSVviJKPXw/YcRYZdB1TdlLJWHHwXwnwD1WnCmQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.0.tgz", + "integrity": "sha512-ubALThHQy4GCf6mbb+5ZRNmLLCI7bJ3f8Q6LHBSRlSKSWj5a7dSUzJBLv3VuIhFrFPgjF4IzPF567YG/HSCdZA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.0.tgz", + "integrity": "sha512-LcnxQSsd9aXOIgmmSpvZ/1yo46ra2ESYyqLcryaBZOghxy5qqOBjvCWP5JfkI8yl9rlxRgdLTTMCQQRcN2hdCg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@fullcalendar/angular": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/angular/-/angular-6.1.15.tgz", + "integrity": "sha512-4QUwYt5X/BQIz+Y6EnRIC9el4MyLPFQ/Yq6ZDPdStH9EGOu+8mDMMCvQFj0RApIgs+uOLe9Vz92Jd4ajTBrymA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "12 - 18", + "@angular/core": "12 - 18", + "@fullcalendar/core": "~6.1.15" + } + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", + "integrity": "sha512-BuX7o6ALpLb84cMw1FCB9/cSgF4JbVO894cjJZ6kP74jzbUZNjtwffwRdA+Id8rrLjT30d/7TrkW90k4zbXB5Q==", + "peer": true, + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.15.tgz", + "integrity": "sha512-j8tL0HhfiVsdtOCLfzK2J0RtSkiad3BYYemwQKq512cx6btz6ZZ2RNc/hVnIxluuWFyvx5sXZwoeTJsFSFTEFA==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.15" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.4.2.tgz", + "integrity": "sha512-iZRNbTlSB9xXt/+jdMFViBdxw1ILWu3365rzfM5OLwAyOScbDFFGSH7LEUwoq1uOIo48ymOEwYSqP5y8hQMlmA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/checkbox/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.11.tgz", + "integrity": "sha512-3wWw10VPxQP279FO4bzWsf8YjIAq7NdwATJ4xS2h1uwsXZu/RmtOVV95rZ7yllS1h/dzu+uLewjMAzNDEj8h2w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^8.2.4", + "@inquirer/type": "^1.3.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-8.2.4.tgz", + "integrity": "sha512-7vsXSfxtrrbwMTirfaKwPcjqJy7pzeuF/bP62yo1NQrRJ5HjmMlrhZml/Ljm9ODc1RnbhJlTeSnCkjtFddKjwA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.3.3", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "picocolors": "^1.0.1", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/core/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/editor": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.1.17.tgz", + "integrity": "sha512-hwx3VpFQzOY2hFWnY+XPsUGCIUVQ5kYxH6+CExv/RbMiAoN3zXtzj8DyrWBOHami0vBrrnPS8CTq3uQWc7N2BA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/type": "^1.5.1", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/editor/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/expand": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.1.17.tgz", + "integrity": "sha512-s4V/dC+GeE5s97xoTtZSmC440uNKePKqZgzqEf0XM63ciilnXAtKGvoAWOePFdlK+oGTz0d8bhbPKwpKGvRYfg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/type": "^1.5.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/expand/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/figures": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.5.tgz", + "integrity": "sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.2.4.tgz", + "integrity": "sha512-wvYnDITPQn+ltktj/O9kQjPxOvpmwcpxLWh8brAyD+jlEbihxtrx9cZdZcxqaCVQj3caw4eZa2Uq5xELo4yXkA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/type": "^1.5.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/input/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/password": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.1.17.tgz", + "integrity": "sha512-/u6DM/fDHXoBWyA+9aRhghkeo5smE7wO9k4E2UoJbgiRCkt3JjBEuBqLOJNrz8E16M0ez4UM1vd5cXrmICHW+A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/type": "^1.5.1", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/password/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/prompts": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.0.7.tgz", + "integrity": "sha512-GFcigCxJTKCH3aECzMIu4FhgLJWnFvMXzpI4CCSoELWFtkOOU2P+goYA61+OKpGrB8fPE7q6n8zAXBSlZRrHjQ==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^2.3.7", + "@inquirer/confirm": "^3.1.11", + "@inquirer/editor": "^2.1.11", + "@inquirer/expand": "^2.1.11", + "@inquirer/input": "^2.1.11", + "@inquirer/password": "^2.1.11", + "@inquirer/rawlist": "^2.1.11", + "@inquirer/select": "^2.3.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.1.17.tgz", + "integrity": "sha512-RFrw34xU5aVlMA3ZJCaeKGxYjhu3j4i46O2GMmaRRGeLObCRM1yOKQOsRclSTzjd4A7+M5QleR2iuW/68J9Kwg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/type": "^1.5.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/rawlist/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/select": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.4.2.tgz", + "integrity": "sha512-r78JlgShqRxyAtBDeBHSDtfrOhSQwm2ecWGGaxe7kD9JwgL3UN563G1ncVRYdsWD7/tigflcskfipVeoDLhLJg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.5", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select/node_modules/@inquirer/core": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", + "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.1", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.11", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/select/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/@inquirer/type": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.1.tgz", + "integrity": "sha512-m3YgGQlKNS0BM+8AFiJkCsTqHEFCWn6s/Rqye3mYwvqY6LdfUv12eSwbsgNzrYyrLXiy7IrrjDLPysaSBwEfhw==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", + "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", + "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.13.tgz", + "integrity": "sha512-nAl6teTt7EWSjttNavAnv3uFR3w3vPP3OTYmHyPNHzKhAj2NoBDHmbS3MGpvvO8KXXPASnHjEGrrKrdKTMKPnQ==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.3.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 6" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.12.tgz", + "integrity": "sha512-vgTwzNUD3Hy4aqtGhX2+nV/usI0mwy3hDRuTjs8VcK0BLiMVEpNQXgzwlWEgPmA8AAPloUgyOs2nK5clJF5oIg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.12.tgz", + "integrity": "sha512-qOt0hAhj2ZLY6aEWu85rzt5zcyCAQITMhCMEPNlo1tuYekpVAdkQNiwXxEkCjBYvwTskvXuwXOOUpjuSc+aJnA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.12.tgz", + "integrity": "sha512-Ggd/UXpE+alMncbELCXA3OKpDj9bDBR3qVO7WRTxstloDglRAHfZmUJgTkeaNKjFO1JHqS7AKy0jba9XebZB1w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.12.tgz", + "integrity": "sha512-Qy4cFXFe9h1wAWMsojex8x1ifvw2kqiZv686YiRTdQEzAfc3vJASHFcD/QejHUCx7YHMYdnUoCS45rG2AiGDTQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.12.tgz", + "integrity": "sha512-c+noT9IofktxktFllKHFmci8ka2SYGSLN17pj/KSl1hg7mmfAiGp4xxFxEwMLTb+SX95vP1DFiR++1I3WLVxvA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.12.tgz", + "integrity": "sha512-CO3MFV8gUx16NU/CyyuumAKblESwvoGVA2XhQKZ976OTOxaTbb8F8D3f0iiZ4MYqsN74jIrFuCmXpPnpjbhfOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mattlewis92/dom-autoscroller": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@mattlewis92/dom-autoscroller/-/dom-autoscroller-2.4.2.tgz", + "integrity": "sha512-YbrUWREPGEjE/FU6foXcAT1YbVwqD/jkYnY1dFb0o4AxtP3s4xKBthlELjndZih8uwsDWgQZx1eNskRNe2BgZQ==" + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ng-select/ng-option-highlight": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-option-highlight/-/ng-option-highlight-13.7.0.tgz", + "integrity": "sha512-sh4f9DeZ24IZb4YZOW2XNw/F43W0/Nf/62DE6akQx9/NNaf5Q2lDiYbPmOraHnoaBgovN5Y0Lf6Yl1lBHZbUDQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^18.0.0", + "@angular/core": "^18.0.0" + } + }, + "node_modules/@ng-select/ng-select": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-13.7.0.tgz", + "integrity": "sha512-GMNu3bLYxWAbgy9pXZ4RgnWp/cxRcrWRQdxLLyg8p9gMCLpim1p4TXR8laXJKK25MKG/LEaWgs+90yCVOoWgZA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8" + }, + "peerDependencies": { + "@angular/common": "^18.0.0", + "@angular/core": "^18.0.0", + "@angular/forms": "^18.0.0" + } + }, + "node_modules/@ngtools/webpack": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.1.4.tgz", + "integrity": "sha512-suoeZjd+7qd3ivzbNGGSzHtY/WMxTKU6ZD1gIIya0Un8Ve1eVxfq6Si6ReKqhygO8zN3paJMATn8sMmAV7qVrw==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^18.0.0", + "typescript": ">=5.4 <5.6", + "webpack": "^5.54.0" + } + }, + "node_modules/@ngx-translate/core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz", + "integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==", + "engines": { + "node": "^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0", + "rxjs": "^6.5.5 || ^7.4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", + "dev": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", + "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", + "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@scarf/scarf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.3.0.tgz", + "integrity": "sha512-lHKK8M5CTcpFj2hZDB3wIjb0KAbEOgDmiJGDv1WBRfQgRm/a8/XMEkG/N1iM01xgbUDsPQwi42D+dFo1XPAKew==", + "hasInstallScript": true + }, + "node_modules/@schematics/angular": { + "version": "18.1.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.1.4.tgz", + "integrity": "sha512-M3edVYKiAGWAAKs7XDLpz1OKUy4STVMT+46Y44ydYz06hI8m/dJfS8ZHTvXPl7JhkrIrSDEMed+WidZtGPIxMg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "18.1.4", + "@angular-devkit/schematics": "18.1.4", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", + "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", + "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", + "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", + "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", + "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", + "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", + "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "dev": true, + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "node_modules/@types/raf": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz", + "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==", + "optional": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ag-charts-types": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-10.0.2.tgz", + "integrity": "sha512-Nxo5slHOXlaeg0gRIsVnovAosQzzlYfWJtdDy0Aq/VvpJru/PJ+5i2c9aCyEhgRxhBjImsoegwkgRj7gNOWV6Q==" + }, + "node_modules/ag-grid-angular": { + "version": "32.0.2", + "resolved": "https://registry.npmjs.org/ag-grid-angular/-/ag-grid-angular-32.0.2.tgz", + "integrity": "sha512-GU9m0hCgBK6DqrXJ2R8r1Vm+CutCUbgrEXtsQPWlQh9AipW9khvbMF0NzuAYpZrGnk8KI9E9+jhzWhT4ZWLOTw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">= 16.0.0", + "@angular/core": ">= 16.0.0", + "ag-grid-community": "32.0.2" + } + }, + "node_modules/ag-grid-community": { + "version": "32.0.2", + "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-32.0.2.tgz", + "integrity": "sha512-vLJJUjnsG9hNK41GNuW2EHu1W264kxA/poOpcX4kmyrjU5Uzvelsbj3HdKAO9POV28iqyRdKGYfAWdn8QzA7KA==", + "dependencies": { + "ag-charts-types": "10.0.2" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/angular-calendar": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/angular-calendar/-/angular-calendar-0.31.1.tgz", + "integrity": "sha512-pjSIpoAaUzS/gx+14eOr4hPZhlQ8HxpiZypCSGqJNptq5PD+vOdVQ3h/Aaqnk86GraVcAQPXqfu64MtdKwTVNw==", + "dependencies": { + "@scarf/scarf": "^1.1.1", + "angular-draggable-droppable": "^8.0.0", + "angular-resizable-element": "^7.0.0", + "calendar-utils": "^0.10.4", + "positioning": "^2.0.1", + "tslib": "^2.4.1" + }, + "funding": { + "url": "https://github.com/sponsors/mattlewis92" + }, + "peerDependencies": { + "@angular/core": ">=15.0.0" + } + }, + "node_modules/angular-draggable-droppable": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/angular-draggable-droppable/-/angular-draggable-droppable-8.0.0.tgz", + "integrity": "sha512-+gpSNBbygjV1pxTxsM3UPJKcXHXJabYoTtKcgQe74rGnb1umKc07XCBD1qDzvlG/kocthvhQ12qfYOYzHnE3ZA==", + "dependencies": { + "@mattlewis92/dom-autoscroller": "^2.4.2", + "tslib": "^2.4.1" + }, + "peerDependencies": { + "@angular/core": ">=15.0.0" + } + }, + "node_modules/angular-resizable-element": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/angular-resizable-element/-/angular-resizable-element-7.0.2.tgz", + "integrity": "sha512-/BGuNiA38n9klexHO1xgnsA3VYigj9v+jUGjKtBRgfB26bCxZKsNWParSu2k3EqbATrfAJC4Nl8f7cORpJFf4w==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=15.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "optional": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/calendar-utils": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/calendar-utils/-/calendar-utils-0.10.4.tgz", + "integrity": "sha512-gBK4xCJ42yjaUKwuUha6cZOfxAmGzvSgbdAaX3xLRioeKbYoOK1x1qeD6dch72rsMZlTgATPbBBx42bnkStqgQ==" + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/canvg": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz", + "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@types/raf": "^3.4.0", + "core-js": "^3.8.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^6.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/canvg/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "optional": true + }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "hasInstallScript": true, + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/critters": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", + "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "css-select": "^5.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.2", + "htmlparser2": "^8.0.2", + "postcss": "^8.4.23", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/critters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/critters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/critters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/critters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/critters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/critters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "optional": true, + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.6.tgz", + "integrity": "sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ==", + "optional": true + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.2.tgz", + "integrity": "sha512-kc4r3U3V3WLaaZqThjYz/Y6z8tJe+7K0bbjUVo3i+LWIypVdMx5nXCkwRe6SWbY6ILqLdc1rKcKmr3HoH7wjSQ==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "devOptional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.21.5.tgz", + "integrity": "sha512-L/FlOPMMFtw+6qPAbuPvJXdrOYOp9yx/PEwSrIZW0qghY4vgV003evdYDwqQ/9ENMQI0B6RMod9xT4FHtto6OQ==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "optional": true, + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz", + "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.10", + "debug": "^4.3.4", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.2.0.tgz", + "integrity": "sha512-tSAtdrvWybZkQmmaIoDgnvHG8ORUNw5kEVlO5CvrXj02Jjr9TZrmjFq7FUiOUzJiOP2wLGYT6PgrQgQF4R1xiw==", + "dev": true + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsencrypt": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz", + "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jspdf": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz", + "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==", + "dependencies": { + "@babel/runtime": "^7.14.0", + "atob": "^2.1.2", + "btoa": "^1.2.1", + "fflate": "^0.4.8" + }, + "optionalDependencies": { + "canvg": "^3.0.6", + "core-js": "^3.6.0", + "dompurify": "^2.2.0", + "html2canvas": "^1.0.0-rc.5" + } + }, + "node_modules/jspdf-autotable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-3.8.2.tgz", + "integrity": "sha512-zW1ix99/mtR4MbIni7IqvrpfHmuTaICl6iv6wqjRN86Nxtwaw/QtOeDbpXqYSzHIJK9JvgtLM283sc5x+ipkJg==", + "peerDependencies": { + "jspdf": "^2.5.1" + } + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/karma/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", + "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/listr2": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", + "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.12.tgz", + "integrity": "sha512-JnoEulTgveoC64vlYJ9sufGLuNkk6TcxSYpKxSC9aM42I61jIv3pQH0fgb6qW7HV0+FNqA3g1WCQQYfhfawGoQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "msgpackr": "^1.10.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.0.12", + "@lmdb/lmdb-darwin-x64": "3.0.12", + "@lmdb/lmdb-linux-arm": "3.0.12", + "@lmdb/lmdb-linux-arm64": "3.0.12", + "@lmdb/lmdb-linux-x64": "3.0.12", + "@lmdb/lmdb-win32-x64": "3.0.12" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz", + "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/msgpackr": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", + "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", + "dev": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/ng-otp-input": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/ng-otp-input/-/ng-otp-input-1.9.3.tgz", + "integrity": "sha512-QiAvOeTVPk8DiY2dnVstyCikWnsY70TXgsVl2iBgz7nFnNM5sdrgbVj8tP0usGznJowVRygCQZJ+hzvYLEhIOQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=6.0.0", + "@angular/core": ">=6.0.0" + } + }, + "node_modules/ngx-cookie-service": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-18.0.0.tgz", + "integrity": "sha512-hkkUckzZTXXWtFgvVkT2hg6mwYMLXioXDZWBsVCOy9gYkADjsj0N5VViO7eo2izQ0VcMPd/Etog1trf/T4oZMQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@angular/common": "^18.0.0-rc.0", + "@angular/core": "^18.0.0-rc.0" + } + }, + "node_modules/nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "!win32" + ], + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node_modules/nice-napi/node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "optional": true + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", + "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "dev": true, + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", + "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", + "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.1.tgz", + "integrity": "sha512-Udm1f0l2nXb3wxDpKjfohwgdFUSV50UVwzEIpDXVsbDMXVIEF81a/i0UhuQbhrPMMmdiq3+YMFLFIRVLs3hxQw==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.1.tgz", + "integrity": "sha512-5VyHfHY3cd0iza71JepYG50My+YUbrFtGoUz2ooEydPyPM7Aai/JW098juLr+RG6+rDJuzNNTsEQu2DZa1A41A==", + "dev": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/pacote": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", + "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/parchment": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz", + "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "devOptional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz", + "integrity": "sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==", + "dev": true, + "optionalDependencies": { + "nice-napi": "^1.0.2" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/positioning": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/positioning/-/positioning-2.0.1.tgz", + "integrity": "sha512-DsAgM42kV/ObuwlRpAzDTjH9E8fGKkMDJHWFX+kfNXSxh7UCCQxEmdjv/Ws5Ft1XDnt3JT8fIDYeKNSE2TbttA==" + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/primeicons": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/primeicons/-/primeicons-7.0.0.tgz", + "integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==" + }, + "node_modules/primeng": { + "version": "17.18.7", + "resolved": "https://registry.npmjs.org/primeng/-/primeng-17.18.7.tgz", + "integrity": "sha512-RKbUL69uTzDrVLOKxC8Qn7tyzoAUXetBsMOnNJJaomXTirC001vNTw/wzcuLxkTQpNXAOztxcKMpMTmZQMhe5Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^17.0.0 || ^18.0.0", + "@angular/core": "^17.0.0 || ^18.0.0", + "@angular/forms": "^17.0.0 || ^18.0.0", + "rxjs": "^6.0.0 || ^7.8.1", + "zone.js": "~0.14.0" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quill": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.2.tgz", + "integrity": "sha512-QfazNrhMakEdRG57IoYFwffUIr04LWJxbS/ZkidRFXYCQt63c1gK6Z7IHUXMx/Vh25WgPBU42oBaNzQ0K1R/xw==", + "dependencies": { + "eventemitter3": "^5.0.1", + "lodash-es": "^4.17.21", + "parchment": "^3.0.0", + "quill-delta": "^5.1.0" + }, + "engines": { + "npm": ">=8.2.3" + } + }, + "node_modules/quill-delta": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", + "dependencies": { + "fast-diff": "^1.3.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/quill/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "optional": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "dev": true + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "optional": true, + "engines": { + "node": ">= 0.8.15" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.2.1.tgz", + "integrity": "sha512-G0VcnMYU18a4N7VoNDegg2OuMjYtxnqzQWARVWCIVSZwJeiL9kg8QMsuIZOplsJgTzZLF6jGxI3AClj8I9nRdQ==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", + "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stackblur-canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", + "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==", + "optional": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "optional": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/terser": { + "version": "5.29.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz", + "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "optional": true, + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tuf-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", + "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", + "dev": true, + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/undici": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", + "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", + "dev": true, + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "optional": true, + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz", + "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webpack-dev-server/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", + "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9e1bbda --- /dev/null +++ b/package.json @@ -0,0 +1,71 @@ +{ + "name": "extra-net", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "build-dev": "ng build --configuration=dev", + "build-uat": "ng build --configuration=uat", + "build-preprod": "ng build --configuration=preprod", + "build-prod": "ng build --configuration=prod", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e", + "post-build": "node ./build/post-build.js", + "serve": "node --max_old_space_size=8192 ./node_modules/@angular/cli/bin/ng serve" + }, + "private": true, + "dependencies": { + "@angular/animations": "^18.1.4", + "@angular/cdk": "^18.1.4", + "@angular/common": "^18.1.4", + "@angular/compiler": "^18.1.4", + "@angular/core": "^18.1.4", + "@angular/forms": "^18.1.4", + "@angular/material": "^18.1.4", + "@angular/platform-browser": "^18.1.4", + "@angular/platform-browser-dynamic": "^18.1.4", + "@angular/router": "^18.1.4", + "@fullcalendar/angular": "^6.1.15", + "@fullcalendar/daygrid": "^6.1.15", + "@ng-select/ng-option-highlight": "^13.7.0", + "@ng-select/ng-select": "^13.7.0", + "@ngx-translate/core": "^15.0.0", + "ag-grid-angular": "^32.0.2", + "ag-grid-community": "^32.0.2", + "angular-calendar": "^0.31.1", + "crypto-js": "^4.2.0", + "date-fns": "^3.6.0", + "file-saver": "^2.0.5", + "jsencrypt": "^3.3.2", + "jspdf": "^2.5.1", + "jspdf-autotable": "^3.8.2", + "moment": "^2.30.1", + "ng-otp-input": "^1.9.3", + "ngx-cookie-service": "^18.0.0", + "primeicons": "^7.0.0", + "primeng": "^17.18.7", + "quill": "^2.0.2", + "rxjs": "^7.8.1", + "tslib": "^2.6.3", + "xlsx": "^0.18.5", + "zone.js": "^0.14.10" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^18.1.4", + "@angular/cli": "^18.1.4", + "@angular/compiler-cli": "^18.1.4", + "@types/file-saver": "^2.0.7", + "@types/jasmine": "^5.1.4", + "@types/node": "^22.1.0", + "jasmine-core": "^5.2.0", + "karma": "^6.4.4", + "karma-chrome-launcher": "^3.2.0", + "karma-coverage": "^2.2.1", + "karma-jasmine": "^5.1.0", + "karma-jasmine-html-reporter": "^2.1.0", + "typescript": "^5.5.4", + "webpack": "^5.93.0" + } +} \ No newline at end of file diff --git a/preprod.Dockerfile b/preprod.Dockerfile new file mode 100644 index 0000000..2b3fdc7 --- /dev/null +++ b/preprod.Dockerfile @@ -0,0 +1,16 @@ +FROM node:20.11.1 as builder + +WORKDIR /usr/src/app +COPY . /usr/src/app + +RUN npm install && npm run build-preprod + +FROM nginx:1.14.2-alpine + +COPY nginx.conf /etc/nginx/nginx.conf +COPY --from=builder /usr/src/app/dist/ExtraNet /usr/share/nginx/html + +EXPOSE 80 +EXPOSE 443 + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/prod.Dockerfile b/prod.Dockerfile new file mode 100644 index 0000000..88693fd --- /dev/null +++ b/prod.Dockerfile @@ -0,0 +1,16 @@ +FROM node:16 as builder + +WORKDIR /usr/src/app +COPY . /usr/src/app + +RUN npm install && npm run build-prod + +FROM nginx:1.14.2-alpine + +COPY nginx.conf /etc/nginx/nginx.conf +COPY --from=builder /usr/src/app/dist/ExtraNet /usr/share/nginx/html + +EXPOSE 80 +EXPOSE 443 + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/readme.md b/readme.md index e69de29..e37e4b1 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,20 @@ +# Introduction +TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project. + +# Getting Started +TODO: Guide users through getting your code up and running on their own system. In this section you can talk about: +1. Installation process +2. Software dependencies +3. Latest releases +4. API references + +# Build and Test +TODO: Describe and show how to build your code and run the tests. + +# Contribute +TODO: Explain how other users and developers can contribute to make your code better. + +If you want to learn more about creating good readme files then refer the following [guidelines](https://docs.microsoft.com/en-us/azure/devops/repos/git/create-a-readme?view=azure-devops). You can also seek inspiration from the below readme files: +- [ASP.NET Core](https://github.com/aspnet/Home) +- [Visual Studio Code](https://github.com/Microsoft/vscode) +- [Chakra Core](https://github.com/Microsoft/ChakraCore) \ No newline at end of file diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 0000000..1135639 --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = [ + { + path: 'Auth', + loadChildren: () => + import('./modules/auth/auth.module').then((m) => m.AuthModule), + }, + { + path: '', + loadChildren: () => + import('./layouts/theme.module').then((m) => m.ThemeModule), + }, + { path: '**', redirectTo: 'Error/404', pathMatch: 'full' }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })], + exports: [RouterModule], +}) +export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000..761542b --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,67 @@ + + + +
    + +
    + + + +
    Session Expire Warning
    +
    Your session will expire in {{commonService.remainingTime}} seconds.
    +
    Do you want to extend the session?
    + + + +
    +
    +
    \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..5f69ae6 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,108 @@ +import { Component, Renderer2 } from '@angular/core'; +import * as moment from 'moment'; +import { Subscription, interval } from 'rxjs'; +import { CommonFunctionService } from './core/common/common-function.service'; +import { API } from './core/services/api.service'; +import { RouteChangeService } from './core/common/RouteChangeService.service'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', +}) +export class AppComponent { + // displayPosition = false; + // position: string; + title = "AngularStructure"; + constructor(private renderer: Renderer2, public commonService: CommonFunctionService, private ApiSer: API, private routeChangeService: RouteChangeService) { + // Check if userId exists in sessionStorage + if (sessionStorage.getItem('LoginUserData')) { + // Set up an interval that runs every second + this.commonService.StartTimer(); + } else { + // If userId doesn't exist in sessionStorage + // Set displayPosition to false, remove 'excd' from sessionStorage, and unsubscribe from the subscription + this.commonService.displayPosition = false; + sessionStorage.removeItem('excd'); + this.commonService.subscription?.unsubscribe(); + } + + } + stopTimer() { + if (this.commonService.subscription) { + this.commonService.subscription.unsubscribe(); + this.commonService.subscription = undefined; + } + }; + + ngOnInit(): void { + //sessionStorage.getItem("userId") + // ? "" + // : (window.location.href = "/Login/Login"); + // const links = this.renderer.createElement("link"); + // links.setAttribute("rel", "stylesheet"); + // links.setAttribute("type", "text/css"); + // links.setAttribute( + // "href", + // isTheme ? "../assets/css/empire/e-default.css" : "../assets/css/retina/r-default.css" + // ); + // this.renderer.appendChild(document.head, links); + // const link = this.renderer.createElement("link"); + // link.setAttribute("rel", "stylesheet"); + // link.setAttribute("type", "text/css"); + // link.setAttribute( + // "href", + // isTheme ? "../assets/css/empire.css" : "../assets/css/retina.css" + // ); + // this.renderer.appendChild(document.head, link); + // this.commonService.GetOrgDetails(); + // this.route.queryParams.subscribe(obj => { + // console.log(obj) + // // if(obj.key) CommonFunctions.DecryptReq("UfCP%2FE7upxltDZyVLfTj%2F8fMMbudOAFfwLCR1RVqPXNvD%203jblAZ3pQ0i9LtrXpE0DFYbSnyHNj353T2bJx9Zg%3D%3D"); + + // }) + // sessionStorage.getItem('userId') ? '' : window.location.href = '/Login/Login' + } + + showPositionDialog(position: string) { + this.commonService.position = position; + this.commonService.displayPosition = true; + }; + + ngOnDestroy() { + // Unsubscribe from the observable to prevent memory leaks + this.commonService.subscription.unsubscribe(); + } + extendJWTTime() { + this.stopTimer(); + let postdata = { + "JwtToken": sessionStorage.getItem('JwtToken'), + "RefreshToken": sessionStorage.getItem('RefreshToken') + }; + this.ApiSer.AdminPost('/JWT/RefreshToken', postdata).subscribe(res => { + if (!res.Status) { + this.commonService.loginOut(); + } else { + sessionStorage.setItem('JwtToken', res.JwtToken); + sessionStorage.setItem('RefreshToken', res.RefreshToken); + sessionStorage.setItem('JwtTokenExpiry', res.JwtTokenExpiry); + this.Close(true) + this.commonService.StartTimer(); + } + }) + }; + // remainingTime: number; + exit() { + this.commonService.displayPosition = false; + sessionStorage.removeItem('excd'); + this.commonService.loginOut(); + }; + Close(check) { + this.commonService.displayPosition = false; + sessionStorage.setItem('excd', 'OK') + if (check) { + setTimeout(function () { + sessionStorage.removeItem('excd'); + }, 10000); // 10000 milliseconds = 10 second + } + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..bd2e986 --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,42 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { TranslateService } from '@ngx-translate/core'; +import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { InterceptLoader } from './core/common/intercept-loader.service'; +import { MessageService } from 'primeng/api'; +import { ToastModule } from 'primeng/toast'; +import { AuthGuard } from './core/guard/auth.guard'; +import { DialogModule } from 'primeng/dialog'; +import { ButtonModule } from 'primeng/button'; +import { LoaderComponent } from './core/shared/intercept-loader/intercept-loader.component'; + + +@NgModule({ + declarations: [ + AppComponent, + LoaderComponent, + ], + imports: [ + BrowserModule, + HttpClientModule, + BrowserAnimationsModule, + AppRoutingModule, + FormsModule, + ReactiveFormsModule, + ToastModule, + ButtonModule, + DialogModule + ], + providers: [ + TranslateService, MessageService, + AuthGuard, + { provide: HTTP_INTERCEPTORS, useClass: InterceptLoader, multi: true } + ], + bootstrap: [AppComponent] +}) +export class AppModule { } + diff --git a/src/app/core/common/RouteChangeService.service.ts b/src/app/core/common/RouteChangeService.service.ts new file mode 100644 index 0000000..bd749cc --- /dev/null +++ b/src/app/core/common/RouteChangeService.service.ts @@ -0,0 +1,51 @@ +import { Injectable } from '@angular/core'; +import { Router, NavigationEnd } from '@angular/router'; +import { filter } from 'rxjs/operators'; +import { MessageService } from 'primeng/api'; +import { API } from '../services/api.service'; +import { securityFunctions } from './security'; + +@Injectable({ + providedIn: 'root' +}) +export class RouteChangeService { + constructor(private router: Router, private apiService: API) { + this.setupRouteChangeSubscription(); + // this.checkSessionMsg() + } + + private setupRouteChangeSubscription() { + this.router.events + .pipe(filter(event => event instanceof NavigationEnd)) + .subscribe(() => { + const currentUrl = this.router.url; + // Check the current route's URL + + if (currentUrl.includes('Unauthorized') || currentUrl == '/' || currentUrl.includes('/404') || currentUrl.includes('/error') || currentUrl.includes('/Auth') || currentUrl.includes('/Home') || currentUrl.includes('/Login')) { + // console.log('Not making API call for 404 or error route:', currentUrl); + } else { + let LoginUserData = JSON.parse(securityFunctions.getSessionStorage('LoginUserData')); + // Call your API function here + let url = currentUrl + if (currentUrl.includes('?')) { + url = currentUrl.split('?')[0] + } + let obj = { + "page_url": url, + "user_id": LoginUserData.user_id, + "project_id": '2405170833594899108' + } + this.apiService.AdminPost('/MenuMasterNew/IsAuthorizedPage', obj).subscribe( + (response) => { + if (!response.resp) { + this.router.navigate(['/Unauthorized']); + } + }, + (error) => { + this.router.navigate(['/']) + } + ); + } + }); + } +} \ No newline at end of file diff --git a/src/app/core/common/common-function.service.ts b/src/app/core/common/common-function.service.ts new file mode 100644 index 0000000..c0cfa12 --- /dev/null +++ b/src/app/core/common/common-function.service.ts @@ -0,0 +1,657 @@ +import { MessageService } from "primeng/api"; +import { API } from "../services/api.service"; +import { Injectable } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { ValidationService } from "./validation.service"; +import * as moment from "moment"; +import { FileUpload } from "primeng/fileupload"; +import jsPDF from "jspdf"; +import * as FileSaver from "file-saver"; +import autoTable from 'jspdf-autotable'; +import { UserLoginData } from "../models/common-model/userModel"; +import { securityFunctions } from "./security"; +import { UserLog } from "../models/common-model/user-logout.model"; +import { Subscription, interval } from "rxjs"; +import { environment } from "src/environments/environment"; +import { Router, NavigationEnd } from '@angular/router'; +import { filter } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class CommonFunctionService { + LoginUserData: UserLoginData + constructor( + public MsgService: MessageService, + public ApiServ: API, + public validationService: ValidationService, + public titleService: Title, + public router:Router + ) { + this.LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + this.clientId = environment.client_id + } + clientId = '' + logo; + AllMenu; + ChangeStatusAllowed = false; + DownloadFilesAllowed = false; + environmentObj = environment; + ddLoader = { + country: false, + city: false, + Currency: false, + vendor: false, + }; + MenuTabList = { + Overview: { val:false, link:'Services/Hotel/HotelManage/OverView', IsActive: false, Download: false}, + MealAddOn: { val:false, link:'Services/Hotel/HotelManage/HotelMealAdd', IsActive: false, Download: false}, + Rooms: { val:false, link:'Services/Hotel/HotelManage/HotelAddRoom', IsActive: false, Download: false}, + HotelSeason: { val:false, link:'Services/Hotel/HotelManage/AddSeason', IsActive: false, Download: false}, + RoomContract: { val:false, link:'Services/Hotel/HotelManage/RoomContractAdd', IsActive: false, Download: false}, + MinStay: { val:false, link:'Services/Hotel/HotelManage/AddMinStay', IsActive: false, Download: false}, + RoomAllocation: { val:false, link:'Services/Hotel/HotelManage/AddAllocation', IsActive: false, Download: false}, + HotelBlockDates: { val:false, link:'Services/Hotel/HotelManage/HotelAddBlockDate', IsActive: false, Download: false}, + HotelOffers: { val:false, link:'Services/Hotel/HotelManage/AddOffer', IsActive: false, Download: false}, + HotelSupplements: { val:false, link:'Services/Hotel/HotelManage/AddSuppliment', IsActive: false, Download: false}, + } + CurrencyList = []; + CountryList = []; + CityList = []; + agencyData = []; + timer; + AllVendor = [] + // =============================== normal function ========================== + + /** + * this function for show message + * @param check boolean + * @param message text + */ + public showMessage(check, message, type?) { + this.MsgService.add({ + severity: type ? type : check ? "success" : "error", + detail: message, + }); + }; + + /** + * @author Ayaan kazi + * last updated by Abdul Razzak on 03-06-2024 + * @param otpInp + * @param otpBox + */ + focusEmptyOtpInp(otpInp, otpBox) { + let targetOtpInput = otpInp.target; + const otpInputWrapper = targetOtpInput.closest('.ng-otp-input-wrapper'); + const inputList = [...otpInputWrapper.querySelectorAll('input')]; + let ind = inputList.findIndex(z => z.getAttribute('id') == targetOtpInput.id); + if (ind == -1 || inputList[ind].value == '') { + for (let i = 0; i <= inputList.length; i++) { + let inp = inputList[i]; + if (inp?.value == '') { + let id = inp.getAttribute('id'); + otpBox.focusTo(id); + break; + } + } + } + }; + + // check Token expire time + /** + * @param check pass boolean for check time expire or not + */ + CheckTokenExpireTime(check) { + const currentISOString = moment.utc(this.ApiServ.getAdjustedLocalTime()).format('YYYY-MM-DD HH:mm:ss'); + const time1 = moment.utc(sessionStorage.getItem('JwtTokenExpiry')).subtract(3, 'seconds').format('YYYY-MM-DD HH:mm:ss'); + const isTime1AfterTime2 = this.isTime1AfterTime2(time1, currentISOString); + if (isTime1AfterTime2) { + let postdata = { + "JwtToken": sessionStorage.getItem('JwtToken'), + "RefreshToken": sessionStorage.getItem('RefreshToken') + } + this.ApiServ.AdminPost('/JWT/RefreshToken', postdata).subscribe(res => { + if (!res.Status) { + this.loginOut(); + } else { + sessionStorage.setItem('JwtToken', res.JwtToken); + sessionStorage.setItem('RefreshToken', res.RefreshToken); + sessionStorage.setItem('JwtTokenExpiry', res.JwtTokenExpiry); + check ? window.location.href = "/Home/Dashboard" : ''; + } + }) + } else { + check ? window.location.href = "/Home/Dashboard" : ''; + } + }; + isTime1AfterTime2(time1, time2) { + const date1 = new Date(time1); // Create a Date object for time1 + const date2 = new Date(time2); // Create a Date object for time2 + return date1 < date2 ? true : false; // Compare the two Date objects + }; + // ---------------------------------------------- Export file ---------------------------------------------- + /** + * this function for download excel + * @param GetallData all data + * @param title_list header and property list + * @param file_name file name + */ + public exportExcel(GetallData, title_list, file_name) { + let bookResultResp = GetallData.map(el => { + let obj = {} + title_list.forEach(title => obj[title.header] = el[title.field]) + return obj; + }); + import("xlsx").then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(bookResultResp); + const workbook = { Sheets: { data: worksheet }, SheetNames: ["data"] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: "xlsx", + type: "array", + }); + this.saveAsExcelFile(excelBuffer, file_name); + }); + } + /** + * @param buffer + * @param fileName + */ + saveAsExcelFile(buffer: any, fileName: string): void { + import("file-saver").then((abc) => { + let EXCEL_TYPE = + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"; + let EXCEL_EXTENSION = ".xlsx"; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + "_export_" + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } + /** + * this function for download PDF + * @param GetallData all data + * @param title_list header and property list + * @param file_name file name + */ + public exportPdf(GetallData, title_list, file_name) { + let bookResultResp = GetallData.map(el => { + let data_Array = []; + title_list.forEach(title => data_Array.push(el[title.field])) + return data_Array + }); + let key_Array = []; + title_list.forEach(title => key_Array.push(title.header)) + const head = [key_Array] + const doc = new jsPDF("l", "ex", [100, 280]); + autoTable(doc, { + head: head, + body: bookResultResp, + didDrawCell: (bookResultResp) => { }, + }); + doc.save(file_name); + } + // ---------------------------------------------- amount Formater ---------------------------------------------- + /** + * + * @param amount + * @param amountFormat + * @param amountFormatDecimalSpliter + * @returns + */ + public amountFormater(amount, amountFormat, amountFormatDecimalSpliter) { + amountFormat = amountFormat != null && amountFormat != '' ? amountFormat : '#,###,###,###.##'; + amountFormatDecimalSpliter = amountFormatDecimalSpliter != null && amountFormatDecimalSpliter != '' ? amountFormatDecimalSpliter : '.'; + let outputAmount = amount; + let splitAmount = amount.toString().split('.'); + let splitAmountFormat = amountFormat + .toString() + .split(amountFormatDecimalSpliter); + let amountSplitList = + splitAmount != null && splitAmount.length > 0 + ? splitAmount[0].split('').reverse() + : []; + let decimalAmountSplitList = + splitAmount != null && splitAmount.length > 1 + ? splitAmount[1].split('') + : []; + let amountFormatSplitList = + splitAmountFormat != null && splitAmountFormat.length > 0 + ? splitAmountFormat[0].split('').reverse() + : []; + let decimalAmountFormatSplitList = + splitAmountFormat != null && splitAmountFormat.length > 1 + ? splitAmountFormat[1].split('') + : []; + + decimalAmountFormatSplitList.forEach((x, index) => { + decimalAmountFormatSplitList[index] = decimalAmountSplitList[index] + ? decimalAmountSplitList[index] + : '0'; + }); + let amountSplitListTemp = []; + let amountIndex = 0; + amountFormatSplitList.forEach((x, index) => { + if (amountFormatSplitList[index] == '#' && amountSplitList[amountIndex]) { + amountSplitListTemp.push(amountSplitList[amountIndex]); + amountIndex += 1; + } else if (amountSplitList[amountIndex]) { + amountSplitListTemp.push(amountFormatSplitList[index]); + } + }); + + if (decimalAmountFormatSplitList && decimalAmountFormatSplitList.length > 0) { + outputAmount = + amountSplitListTemp.reverse().join('') + + amountFormatDecimalSpliter + + decimalAmountFormatSplitList.join(''); + } else { + outputAmount = + amountSplitListTemp.reverse().join('') + } + return outputAmount; + } + // ---------------------------------------------- passsword update functions --------------------------------------------------------- + + // This function for password criteria + password_criteria(password_Value) { + password_Value.length >= 8 ? this.password_criteria_obj.is_length = true : this.password_criteria_obj.is_length = false; + password_Value.match(this.validationService.regExps.lower_case) ? this.password_criteria_obj.is_lowerCase = true : this.password_criteria_obj.is_lowerCase = false; + password_Value.match(this.validationService.regExps.Capital_case) ? this.password_criteria_obj.is_Uppercase = true : this.password_criteria_obj.is_Uppercase = false; + password_Value.match(this.validationService.regExps.numbers) ? this.password_criteria_obj.is_numbers = true : this.password_criteria_obj.is_numbers = false; + password_Value.match(this.validationService.regExps.special_characters) ? this.password_criteria_obj.is_special_characters = true : this.password_criteria_obj.is_special_characters = false; + }; + password_criteria_obj = { + is_lowerCase: false, + is_Uppercase: false, + is_Capital_case: false, + is_numbers: false, + is_special_characters: false, + is_length: false + }; + + public isFormControlHasError(e, validationType) { + let result = e.hasError(validationType) && (e.dirty || e.touched); + return result; + }; + + // for create priority update array of object + // createPriorityObj(data, rule) { + // return data.map(e => ({ priority: e.priority, [rule]: e[rule] })); + // }; + // /** + // * Updates the priority and sets the 'is_change' flag for an element in the given list + // * based on a specified rule identifier property. + // * + // * @param listToUpdate - The array of objects + // * @param targetRuleId - The value of the rule identifier to find the target element. + // * @param newPriority - The new priority value to set. + // * @param ruleIdProperty - The property name representing the rule identifier in each object. + // */ + // updatePriorityByRuleId(listToUpdate, targetRuleId, newPriority, ruleIdProperty) { + // if (newPriority !== "") { + // const targetElement = listToUpdate.find(item => item[ruleIdProperty] === targetRuleId); + // if (targetElement) { + // targetElement.is_change = true; + // targetElement.priority = parseInt(newPriority); + // }; + // }; + // }; + + // -------------------------------------------------------------Date Formmat function -------------------------------------------------- + /** + * Converts a UTC date to a formatted local time string. + * @author Abdul Razzak + * @param date + * @param format + */ + UtcToLocaleTime(date, format = 'DD MMM YYYY, HH:mm:ss') { + let localeTime = moment.utc(date).local(); + let formattedTime = localeTime.format(format); + return formattedTime; + } + GetTimeZoneGMT() { + let _date = new Date().getTimezoneOffset(); + return `${((_date / 60) > 0 ? "-" : "+")}${Math.floor(Math.abs(_date / 60))} hours ${Math.abs(_date % 60)} minutes` + }; + + convertDateToSave(date: Date) { + return moment(date).format('YYYY-MM-DD') + 'T00:00:00Z' + }; + convertDateToSaveWithoutTime(date: Date) { + return moment(date).format('YYYY-MM-DD') + }; + convertDateWithTimeToShow(date: Date) { + return moment(date).format('DD MMM YYYY, HH:mm:ss') + }; + convertDateToShow(date: Date) { + return moment(date).format('DD MMM YYYY') + }; + + // ----------------------------------------------------------- image update function ------------------------------------------------------------ + /** + * for check image file + * @param file + * @param controls + * @param filedata + * @author Abdul Razzak + */ + checkImageFile(file, controls, filedata: FileUpload) { + const reader = new FileReader(); + reader.readAsText(file); // Read as binary data + reader.onload = (e) => { + const binaryString = e.target.result as string; + const hasScriptTag = this.hasScriptTagInBinary(binaryString); + if (hasScriptTag) { + filedata.clear(); + this.showMessage(false, 'Invalid file (contains script tag)'); + } else { + controls.setValue(file); + } + }; + }; + + /** + * Image script validation + * @author Abdul Razzak + */ + hasScriptTagInBinary(binaryData: string) { + // This is a simplified and potentially unreliable approach + const scriptTagRegex = /)<[^<]*)*<\/script>/g; + return scriptTagRegex.test(binaryData); + }; + + // ------------------------------------------------------------ api calls function--------------------------------------------------------- + GetCurrencyList(val) { + if (val.length >= 2 || val == 'ALL') { + this.ddLoader.Currency = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + let request = { + "langcode": "en", + "query": val == 'ALL' ? '' : val + } + this.ApiServ.AdminGoPost(`/MasterSearch/GetAllCurrency`, request).subscribe(res => { + if (res) { + this.CurrencyList = res?.Result; + this.ddLoader.Currency = false; + } + }); + }, 500); + }; + if (!val) { + this.CurrencyList = []; + } + }; + + /** + * this function for get standalone feature by code + * @param pageId page id + */ + getFeatures(pageId) { + return this.ApiServ.Get("/MenuMasterNew/GetAllFeatureCode/2110180851430030870/" + pageId) + } + + getCountryBySearch(val) { + if (val.length >= 2) { + this.ddLoader.country = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.AdminGet(`/MasterSearch/GetAllCountry/en/` + val).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader.country = false; + } + }); + }, 500); + } + if (!val) { + this.CountryList = []; + } + }; + // This function is used for country search by name. + + checkCountryExist = false; + getCitySearchByCountryCode(val, country_code) { + if (country_code) { + this.checkCountryExist = false; + if (val.length >= 2) { + this.ddLoader.city = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.AdminGet(`/MasterSearch/GetCitySearch/en/${country_code}/` + val).subscribe(res => { + if (res) { + this.CityList = res; + this.ddLoader.city = false; + } + }); + }, 500); + } + if (!val) { + this.CityList = []; + } + } else this.checkCountryExist = true; + }; + ExtranetVendorMaster(val, check) { + if (val.length >= 2) { + this.ddLoader.vendor = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.FetchExtranetVendorMaster(val, check) + }, 500); + } + if (!val) { + this.AllVendor = []; + } + }; + + FetchExtranetVendorMaster(val, check) { + let searchObj = { + vendor_name: check ? val : '', + extranet_vendor_id: !check ? val : '', + }; + return this.ApiServ.AdminGoPost('/ExtranetVendorMaster/GetAll', searchObj) + }; + loginOut() { + let loginData = sessionStorage.getItem('IP'); + this.LoginUserData = JSON.parse(securityFunctions.getSessionStorage('LoginUserData')); + try { + let userLogModel = new UserLog(); + userLogModel.ip = loginData['iP']; + userLogModel.ip_city = loginData['city']; + userLogModel.ip_country_code = loginData['countryCode']; + userLogModel.ip_lat = loginData['lat']; + userLogModel.ip_lon = loginData['lon']; + userLogModel.ip_proxy = loginData['proxy']; + userLogModel.user_id = this.LoginUserData.user_id; + userLogModel.user_type = this.LoginUserData.user_type; + this.ApiServ.AdminPost("/Log/SaveLogoutLog", userLogModel).subscribe(d => { + securityFunctions.resetSessionStoage('lastLogin') + securityFunctions.resetSessionStoage('LoginUserData') + securityFunctions.resetSessionStoage('IP') + securityFunctions.resetSessionStoage('userName') + securityFunctions.resetSessionStoage('JwtToken') + securityFunctions.resetSessionStoage('RefreshToken') + securityFunctions.resetSessionStoage('JwtTokenExpiry') + sessionStorage.removeItem('selMenu'); + window.location.href = '/Auth/Login'; + }); + } catch (error) { + window.location.href = '/Auth/Login'; + } + }; + + // + displayPosition = false; + position: string; + public subscription: Subscription; + remainingTime: number; + StartTimer() { + const source = interval(1000); + // Subscribe to the interval observable + this.subscription = source.subscribe(() => { + // Get the current time in milliseconds + const currentTime = moment.utc(this.ApiServ.getAdjustedLocalTime()).valueOf(); + const LastEndpointCallTime = moment.utc(sessionStorage.getItem('LastEndpointCallTime')).valueOf(); + // Get the token expiry time from sessionStorage + const tokenExpiry = moment.utc(sessionStorage.getItem('JwtTokenExpiry')); + // Calculate the time difference between token expiry and current time in milliseconds + const timeDifference = tokenExpiry.valueOf() - currentTime; + // Calculate the diffence between current time and the last endpoint call time. + const diff_between_endpoint_call = currentTime - LastEndpointCallTime + + // Check if time difference is less than or equal to 2 minutes (120000 milliseconds) + if (timeDifference <= 120000) { + if (this.displayPosition && this.remainingTime <= 0) { + this.exit(); + } else { + if (diff_between_endpoint_call >= 780000) { + // If excd is not set and displayPosition is not already true, set displayPosition to true + if (!sessionStorage.getItem('excd') && !this.displayPosition) { + this.displayPosition = true; + } + + // Calculate remaining time in seconds + const remainingTimeSeconds = tokenExpiry.diff(moment.utc(this.ApiServ.getAdjustedLocalTime()), 'seconds'); + // Update remainingTime property + this.remainingTime = remainingTimeSeconds; + // If remaining time is less than or equal to 0, call exit function + if (this.remainingTime <= 0) { + this.exit(); + } + } else { + this.extendJWTTime(); + } + } + } + }); + }; + exit() { + this.displayPosition = false; + sessionStorage.removeItem('excd'); + this.loginOut(); + }; + extendJWTTime() { + this.stopTimer(); + let postdata = { + "JwtToken": sessionStorage.getItem('JwtToken'), + "RefreshToken": sessionStorage.getItem('RefreshToken') + }; + this.ApiServ.AdminPost('/JWT/RefreshToken', postdata).subscribe(res => { + if (!res.Status) { + this.loginOut(); + } else { + sessionStorage.setItem('JwtToken', res.JwtToken); + sessionStorage.setItem('RefreshToken', res.RefreshToken); + sessionStorage.setItem('JwtTokenExpiry', res.JwtTokenExpiry); + sessionStorage.setItem('RefreshTokenExpireAt', res.RefreshTokenExpireAt); + this.Close(true); + this.StartTimer(); + } + }) + }; + stopTimer() { + if (this.subscription) { + this.subscription.unsubscribe(); + this.subscription = undefined; + } + }; + Close(check) { + this.displayPosition = false; + sessionStorage.setItem('excd', 'OK') + if (check) { + setTimeout(function () { + sessionStorage.removeItem('excd'); + }, 10000); // 10000 milliseconds = 10 second + } + } + AffiliateDetails(value, target, check, agencytype?, is_active?, is_cug?) { + let obj = { + AgencyId: check ? value : null, + AgencyName: !check ? value : '' + } + if (value.length >= 3) { + this.ddLoader[target] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.PostGo(`/AgencyDetail/GetAllAffiliateDetail`, obj).subscribe(res => { + if (res) { + this.agencyData = res.result; + if (agencytype) { + if (agencytype == '211526104324609556' || agencytype == '211526104324609557') { + if (agencytype == '211526104324609556') this.agencyData = this.agencyData.filter(z => z.AgencyType == 'B2C'); + if (agencytype == '211526104324609557') this.agencyData = this.agencyData.filter(z => z.AgencyType == 'B2B'); + } + else this.agencyData = this.agencyData.filter(z => z.AgencyType == agencytype); + }; + if(is_active) this.agencyData = res.result.filter(z => z.AgencyType == 'B2B' && z.IsActive); + if(is_cug) this.agencyData = res.result.filter(z => (z.AgencyType === "B2B" || z.is_cug) && z.IsActive); + if(!is_active && is_cug) this.agencyData = res.result.filter(z => (z.AgencyType === "B2B" || z.is_cug)); + this.ddLoader[target] = false; + } + }); + }, 500); + } else { + this.agencyData = []; + } + } + public amountDefiner(amount, definer) { + let outputAmount = amount; + let splitAmount = amount.toString().split("."); + if (splitAmount.length > 1 && splitAmount[1].length > 0) { + let decimals = splitAmount[1].substr(0, definer); + outputAmount = parseFloat(decimals.length > 0 ? `${splitAmount[0]}.${decimals}` : amount).toFixed(definer); + } else { + outputAmount = parseFloat(`${splitAmount[0]}.0}`).toFixed(definer) + } + return outputAmount; + } + + getHeaderSize(logoElem) { + const logo = logoElem.nativeElement; + let header_height = 0; + if (logo) { + header_height = logo.clientHeight; + } + return header_height; + } + + CheckActiveTabMenus(menulist){ + this.AllMenu = menulist; + Object.keys(this.MenuTabList).forEach(e=>{ + const Menu = menulist.find(d=>d.page_data.includes(this.MenuTabList[e].link)); + if(Menu){ + this.MenuTabList[e].val = true; + this.MenuTabList[e].Download = Menu.permission.Download; + this.MenuTabList[e].IsActive = Menu.permission.Status; + } + }); + this.onRouteChange(); + this.router.events + .pipe(filter(event => event instanceof NavigationEnd)) // Filter to get NavigationEnd event + .subscribe(() => { + this.onRouteChange(); // Trigger your function + }); + + } + onRouteChange(): void { + const currentUrl = this.router.url; + const currentUrlMenu = this.AllMenu.find(d=>{ + if(d.page_data){ + const page_data = JSON.parse(d.page_data); + return page_data.some(e=>currentUrl.includes(e.page_url.replaceAll('/$',''))) + }else { + return false; + } + }); + if(currentUrlMenu){ + this.DownloadFilesAllowed = currentUrlMenu.permission.Download; + this.ChangeStatusAllowed = currentUrlMenu.permission.Status; + } + } +} \ No newline at end of file diff --git a/src/app/core/common/intercept-loader.service.ts b/src/app/core/common/intercept-loader.service.ts new file mode 100644 index 0000000..ba1c0a0 --- /dev/null +++ b/src/app/core/common/intercept-loader.service.ts @@ -0,0 +1,264 @@ +import { HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, Subject, throwError } from 'rxjs'; +import { catchError, exhaustMap, finalize, take } from 'rxjs/operators'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { LoaderService } from './loader.service'; +import { API } from '../services/api.service'; +import { securityFunctions } from './security'; +import { UserLog } from '../models/common-model/user-logout.model'; +import { UserLoginData } from '../models/common-model/userModel'; +import { CommonFunctionService } from './common-function.service'; + +@Injectable({ + providedIn: 'root' +}) +export class InterceptLoader { + private readonly requests: HttpRequest[] = []; + LoginUserData: UserLoginData + constructor( + private readonly loaderService: LoaderService, + private readonly apiServ: API, + public MsgService: MessageService, + private readonly commonService: CommonFunctionService) { + } + + removeRequest(req: HttpRequest) { + const i = this.requests.indexOf(req); + if (i >= 0) { + this.requests.splice(i, 1); + } + if (!req.url.includes('RetryInvoice') && !req.url.includes('invoice/GetCustomer') && !req.url.includes('UserMachine/CheckUserVerified')) { + this.loaderService.isLoading.next(this.requests.length > 0); + } + } + private readonly refreshToken$ = new Subject(); + private refreshInProgress = false; + intercept(req: HttpRequest, next: HttpHandler) { + const modifiedRequest = this.headerSetup(req); + const adjustedTime = this.apiServ.getAdjustedLocalTime(); // Get adjusted local time + const currentISOString = moment.utc(adjustedTime).format('YYYY-MM-DD HH:mm:ss'); + const time1 = moment.utc(sessionStorage.getItem('JwtTokenExpiry')).subtract(3, 'seconds').format('YYYY-MM-DD HH:mm:ss'); + const isTime1AfterTime2 = this.isTime1AfterTime2(time1, currentISOString); + const isRefreshTokenUrl = req.url.toLowerCase().includes('/jwt/refreshtoken'); + const isLogoutLogUrl = req.url.toLowerCase().includes('/log/savelogoutlog'); + let UGT = sessionStorage.getItem('UGT'); + const isServerUTCTimeUrl = req.url.includes('/Server/GetServerUTCTime'); + if (((isTime1AfterTime2) && !isRefreshTokenUrl && !isLogoutLogUrl) || (!UGT && !isServerUTCTimeUrl)) { + // If a token refresh is in progress, wait for it to complete before proceeding + if (this.refreshInProgress) { + return this.refreshToken$.pipe( + take(1), + exhaustMap(() => { + const modifiedRequest = this.headerSetup(req); + this.requests.push(modifiedRequest); + if (!req.url.includes('RetryInvoice') && !req.url.includes('invoice/GetCustomer') && !req.url.includes('UserMachine/CheckUserVerified')) { + this.loaderService.isLoading.next(true); + } + return this.ObservableReturn(modifiedRequest, next) + }) + ); + } + // Trigger token refresh and queue other requests + this.refreshInProgress = true; + this.refreshToken$.next(); + if (!UGT && !isServerUTCTimeUrl) { + return this.GetServerTime(req, next); + } else { + return this.GetJWTToKen(req, next); + } + } else { + this.requests.push(modifiedRequest); + if (!req.url.includes('RetryInvoice') && !req.url.includes('invoice/GetCustomer') && !req.url.includes('UserMachine/CheckUserVerified')) { + this.loaderService.isLoading.next(true); + } + return this.ObservableReturn(modifiedRequest, next); + } + } + + isTime1AfterTime2(time1, time2) { + const date1 = new Date(time1); // Create a Date object for time1 + const date2 = new Date(time2); // Create a Date object for time2 + return date1 < date2 ? true : false; // Compare the two Date objects + } + + ObservableReturn(req, next) { + return Observable.create(observer => { + const subscription = next.handle(req).subscribe( + event => { + if (event instanceof HttpResponse) { + + this.removeRequest(req); + observer.next(event); + + } + }, + err => { + if (err.status === 401) { + // Response status is 401, so you can run your function here + const customResponse = err; // Pass the response to your function + // updated by Abdul Razzak on 23 mar 2024 + if (err.url.toLowerCase().includes('/log/savelogoutlog')) { + window.location.href = '/Auth/Login'; + } else { + this.handleUnauthorizedResponse(customResponse.error); // Replace this with your actual function + } + this.removeRequest(req); + } else if (err.status === 429) { + this.MsgService.add({ + severity: "error", + detail: err.error["metadata"]?.message ? err.error["metadata"]?.message : 'Service is currently unavailable', + }); + this.removeRequest(req); + } else { + this.removeRequest(req); + console.log('error' + err); + observer.error(err); + } + }, + () => { + this.removeRequest(req); + observer.complete(); + }); + // remove request from queue when cancelled + return () => { + this.removeRequest(req); + subscription.unsubscribe(); + }; + }); + } + + handleUnauthorizedResponse(Response) { + if (Response.AuthResponseType == 2 || Response.AuthResponseType == 1 || Response.AuthResponseType == 4 || Response.AuthResponseType == 5 || Response.AuthResponseType == 6 || Response.AuthResponseType == 7 || Response.AuthResponseType == 8) { + this.loginOut(); + } + if (Response.AuthResponseType == 3) { + this.MsgService.add({ + severity: "error", + detail: Response["message"], + }); + } + } + + loginOut() { + let loginData = sessionStorage.getItem('IP'); + let LoginUserData = JSON.parse(securityFunctions.getSessionStorage('LoginUserData')); + try { + let userLogModel = new UserLog(); + userLogModel.ip = loginData['iP']; + userLogModel.ip_city = loginData['city']; + userLogModel.ip_country_code = loginData['countryCode']; + userLogModel.ip_lat = loginData['lat']; + userLogModel.ip_lon = loginData['lon']; + userLogModel.ip_proxy = loginData['proxy']; + userLogModel.user_id = LoginUserData.user_id; + userLogModel.user_type = LoginUserData.user_type; + this.apiServ.AdminPost("/Log/SaveLogoutLog", userLogModel).subscribe(d => { + securityFunctions.resetSessionStoage('lastLogin') + securityFunctions.resetSessionStoage('LoginUserData') + securityFunctions.resetSessionStoage('IP') + securityFunctions.resetSessionStoage('userName') + securityFunctions.resetSessionStoage('userType') + securityFunctions.resetSessionStoage('JwtToken') + securityFunctions.resetSessionStoage('RefreshToken') + securityFunctions.resetSessionStoage('JwtTokenExpiry') + sessionStorage.removeItem('selMenu'); + window.location.href = '/Auth/Login'; + }); + } catch (error) { + window.location.href = '/Auth/Login'; + } + } + GetJWTToKen(req,next) { + let postdata = { + "JwtToken": sessionStorage.getItem('JwtToken'), + "RefreshToken": sessionStorage.getItem('RefreshToken') + }; + return this.apiServ.AdminPost('/JWT/RefreshToken', postdata).pipe( + catchError((error) => { + // return throwError(error); + if (error.status === 401) { + // Response status is 401, so you can run your function here + const customResponse = error; // Pass the response to your function + // updated by Abdul Razzak on 04 apr 2024 + this.handleUnauthorizedResponse(customResponse.error); // Replace this with your actual function + this.removeRequest(req); + return throwError(error); + } else { + console.log('Error:', error); + this.removeRequest(req); + return throwError(error); + } + }), + finalize(() => { + this.refreshInProgress = false; + this.refreshToken$.next(); // Signal completion of token refresh + }), + exhaustMap((res: any) => { + if (!res.Status) { + this.loginOut(); + const modifiedRequest = this.headerSetup(req); + this.requests.push(modifiedRequest); + } else { + sessionStorage.setItem('JwtToken', res.JwtToken); + sessionStorage.setItem('RefreshToken', res.RefreshToken); + sessionStorage.setItem('JwtTokenExpiry', res.JwtTokenExpiry); + const modifiedRequest = this.headerSetup(req); + if (!req.url.includes('RetryInvoice') && !req.url.includes('invoice/GetCustomer') && !req.url.includes('UserMachine/CheckUserVerified') && !req.url.toLowerCase().includes('/jwt/refreshtoken')) { + this.loaderService.isLoading.next(true); + } + this.commonService.StartTimer(); + return this.ObservableReturn(modifiedRequest, next); + } + }) + ); + } + + GetServerTime(req, next) { + return this.apiServ.GetGo('/Server/GetServerUTCTime').pipe( + catchError((error) => { + console.log('Error:', error); + this.removeRequest(req); + return throwError(error); + }), + finalize(() => { + this.refreshInProgress = false; + this.refreshToken$.next(); // Signal completion of token refresh + }), + exhaustMap((res) => { + this.SetuserLocalGapTime(res) + this.loaderService.isLoading.next(true); + let modifiedRequest = this.headerSetup(req); + return this.ObservableReturn(modifiedRequest, next); + }) + ); + }; + SetuserLocalGapTime(data) { + let gaptime = data.server_utc_time - new Date().getTime(); + sessionStorage.setItem('UGT', gaptime.toString()); + } + + headerSetup(req) { + this.LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : ''; + // let domain = document.location.host + let domain = 'extranet.dev.futuretravelplatform.com' + let domainName = domain.replace(/^(https?:\/\/)?/, ''); + const adjustedTime = this.apiServ.getAdjustedLocalTime(); // Get adjusted local time + // Handle vendor id in token + // Don't remove '~' as there was a length undefined in the API to get vendor id + let domain_time = domainName + '~' + adjustedTime + '~' + '' + '~' + '' + '~' + '' + '~' + (this.LoginUserData ? this.LoginUserData.extranet_vendor_id : ''); + let key = securityFunctions.rsa_public_key; + let encrypted_string = securityFunctions.encryptRSA(key, domain_time).toString(); + if (!req.url.toLowerCase().includes('/jwt/refreshtoken')) { + sessionStorage.setItem('LastEndpointCallTime', moment.utc(adjustedTime).format('YYYY-MM-DD HH:mm:ss')); + } + return req.clone({ + setHeaders: { + 'Authorization': 'Bearer ' + sessionStorage.getItem('JwtToken'), + 'token': encrypted_string + } + }); + } + +} diff --git a/src/app/core/common/loader.service.ts b/src/app/core/common/loader.service.ts new file mode 100644 index 0000000..1ae2a46 --- /dev/null +++ b/src/app/core/common/loader.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class LoaderService { + + public isLoading = new BehaviorSubject(false); + constructor() { } +} \ No newline at end of file diff --git a/src/app/core/common/security.ts b/src/app/core/common/security.ts new file mode 100644 index 0000000..85bfef4 --- /dev/null +++ b/src/app/core/common/security.ts @@ -0,0 +1,154 @@ +import * as CryptoJS from 'crypto-js'; +import { JSEncrypt } from 'jsencrypt'; +export class securityFunctions { + + static yek = "$uPer@dm1n~dI@z7"; + static sayek = "$uper@dmin~diaZ1" + static savi = "$uper@dmin~diaZ1" + static rsa_public_key = `-----BEGIN PUBLIC KEY----- + MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgB0rRSHGZK/FtK15IRfQxtl + dN5ToPtfXGzTNBe1vGhow5xqp6BLubMKKPwCj3zOJiAm1Ip1VNqqYxWnaL8ZErBF + rErtE0r7kn50QgGgJCpdrWJ4unhaoe1su207d9oY6D6OBH90v1aXA6ZjN7zTJmiq + FJZOOTQE6t/XwNAOphq/B6Lcr1iQSQmSqaMozy4OQ4NvIzNTQn5tcs9qJBMsKFeU + cSp8VK76JBNEqSuEHNmbV2d/IQ5XAqVUiAs34kH2xWRSbBmy0WK3c3QKGzC1MRWM + 9JauLN56TKUFOmUSjfWY3caJru6HxsiMTGKnvflXHfgA2aLAPxu72pIHoCTy5Hxj + AUoKM7qXUn/kQj4Ci0M/0LRF4boqd37wpbyVNeXNvqm+dLjxklf/+NHMfNL2Wvb4 + ekHUVI8nMVPgswIcQ7q/Njf9DC+LA+/duf8m9JDjI3J6r9y1gQugdkLETGzF2Gj1 + ToU0Pocrg6CFHImqq2z+cOeWnURrV0f0I1UWWGCb79OZxZ5oDjM9uCLRsoe8+Npg + ACZNf4AbnM7OUNj5TEYs6t/tUYouvTB7gH452I3EH6KWBl+ZTgCg0RFkOMazNOjn + 4J0yfbaPvpVgKzF2WRyn63mTO2tdLRl5s9uqMFhXmCs6IzEqBpxMKL1aS6ONZLDG + 5qPtpCPJnUFQEBTVlSO15QIDAQAB + -----END PUBLIC KEY-----` + /** + * encrypting text using cryptoJS with 128/8 key size + * used CBC mode + * used Pkcs7 padding + * returning encrypted text + * @param plainText text to be encrypted + */ + //encrypt text using AES + public static encryptText(plainText) { + var key = CryptoJS.enc.Utf8.parse(this.yek); + var iv = CryptoJS.enc.Utf8.parse(this.yek); + + var encryptedText = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(plainText), key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }).toString(); + return encryptedText; + } + + /** + * decryption method for decrypt text that was decrypted in encrypt text method + * @param cipherText text to be encrypt + */ + //decrypt cypher text using AES + public static decryptText(cipherText) { + var key = CryptoJS.enc.Utf8.parse(this.yek); + var iv = CryptoJS.enc.Utf8.parse(this.yek); + + var decryptedText = CryptoJS.AES.decrypt(cipherText, key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8); + return decryptedText; + } + + public static setLocalStoage(key: string, value) { + localStorage.setItem(key, this.encryptText(value)); + } + + public static getLocalStoage(key: string) { + var value = localStorage.getItem(key); + if (value) { + return this.decryptText(value); + } + } + + public static setSessionStorage(key: string, value) { + sessionStorage.setItem(key, this.encryptText(value)); + } + + public static getSessionStorage(key: string) { + var value = sessionStorage.getItem(key); + if (value) { + return this.decryptText(value); + } + } + public static resetLocalStoage(key: string) { + localStorage.removeItem(key); + } + public static resetSessionStoage(key: string) { + sessionStorage.removeItem(key); + } + public static getSaUrlKey(userId) { + var key = CryptoJS.enc.Utf8.parse(this.sayek); + var iv = CryptoJS.enc.Utf8.parse(this.savi); + + var encryptedText = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(userId), key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }).toString(); + return encryptedText; + } + + public static DecryptReq(data) { + var key = CryptoJS.enc.Utf8.parse(this.sayek); + var iv = CryptoJS.enc.Utf8.parse(this.savi); + + // encrypt data using AES + var encrypted = CryptoJS.AES.decrypt(data, key, { iv: iv }); + + return encrypted.toString(CryptoJS.enc.Utf8) + } + + /** + * method to add restrict for priority + * + */ + checkLength(e, input) { + const functionalKeys = ['Backspace', 'ArrowRight', 'ArrowLeft']; + if (functionalKeys.indexOf(e.key) !== -1) { + return; + } + const keyValue = +e.key; + if (isNaN(keyValue)) { + e.preventDefault(); + return; + } + let newValue; + newValue = input.value + keyValue.toString(); + if (+newValue > 100 || +newValue == 0 || newValue.length > 3) { + e.preventDefault(); + } + } + public static EncryptReq(data) { + var key = CryptoJS.enc.Utf8.parse(this.sayek); + var iv = CryptoJS.enc.Utf8.parse(this.savi); + + // encrypt data using AES + var encrypted = CryptoJS.AES.encrypt(data, key, { iv: iv }); + + // convert encrypted data to base64 string for transport + var encryptedBase64 = encrypted.toString(); + return encryptedBase64 + } + + public static encryptRSA(publicKey: string, jsonString: string) { + const encryptor = new JSEncrypt(); + encryptor.setPublicKey(publicKey); + + const encrypted = encryptor.encrypt(jsonString); + + return encrypted; + } +} diff --git a/src/app/core/common/static-data.service.ts b/src/app/core/common/static-data.service.ts new file mode 100644 index 0000000..7c338fa --- /dev/null +++ b/src/app/core/common/static-data.service.ts @@ -0,0 +1,269 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class StaticDataService { + + ActivityOverViewtab = 0; + Hours = [ + { id: 0, name: '00' }, + { id: 1, name: '01' }, + { id: 2, name: '02' }, + { id: 3, name: '03' }, + { id: 4, name: '04' }, + { id: 5, name: '05' }, + { id: 6, name: '06' }, + { id: 7, name: '07' }, + { id: 8, name: '08' }, + { id: 9, name: '09' }, + { id: 10, name: '10' }, + { id: 11, name: '11' }, + { id: 12, name: '12' }, + { id: 13, name: '13' }, + { id: 14, name: '14' }, + { id: 15, name: '15' }, + { id: 16, name: '16' }, + { id: 17, name: '17' }, + { id: 18, name: '18' }, + { id: 19, name: '19' }, + { id: 20, name: '20' }, + { id: 21, name: '21' }, + { id: 22, name: '22' }, + { id: 23, name: '23' }, + ]; + HoursAndMinutes = [ + { hour: '00', minute: '00' }, + { hour: '00', minute: '30' }, + { hour: '01', minute: '00' }, + { hour: '01', minute: '30' }, + { hour: '02', minute: '00' }, + { hour: '02', minute: '30' }, + { hour: '03', minute: '00' }, + { hour: '03', minute: '30' }, + { hour: '04', minute: '00' }, + { hour: '04', minute: '30' }, + { hour: '05', minute: '00' }, + { hour: '05', minute: '30' }, + { hour: '06', minute: '00' }, + { hour: '06', minute: '30' }, + { hour: '07', minute: '00' }, + { hour: '07', minute: '30' }, + { hour: '08', minute: '00' }, + { hour: '08', minute: '30' }, + { hour: '09', minute: '00' }, + { hour: '09', minute: '30' }, + { hour: '10', minute: '00' }, + { hour: '10', minute: '30' }, + { hour: '11', minute: '00' }, + { hour: '11', minute: '30' }, + { hour: '12', minute: '00' }, + { hour: '12', minute: '30' }, + { hour: '13', minute: '00' }, + { hour: '13', minute: '30' }, + { hour: '14', minute: '00' }, + { hour: '14', minute: '30' }, + { hour: '15', minute: '00' }, + { hour: '15', minute: '30' }, + { hour: '16', minute: '00' }, + { hour: '16', minute: '30' }, + { hour: '17', minute: '00' }, + { hour: '17', minute: '30' }, + { hour: '18', minute: '00' }, + { hour: '18', minute: '30' }, + { hour: '19', minute: '00' }, + { hour: '19', minute: '30' }, + { hour: '20', minute: '00' }, + { hour: '20', minute: '30' }, + { hour: '21', minute: '00' }, + { hour: '21', minute: '30' }, + { hour: '22', minute: '00' }, + { hour: '22', minute: '30' }, + { hour: '23', minute: '00' }, + { hour: '23', minute: '30' }, + ]; + days = [ + { id: 0, name: '00' }, + { id: 1, name: '01' }, + { id: 2, name: '02' }, + { id: 3, name: '03' }, + { id: 4, name: '04' }, + { id: 5, name: '05' }, + { id: 6, name: '06' }, + { id: 7, name: '07' }, + { id: 8, name: '08' }, + { id: 9, name: '09' }, + { id: 10, name: '10' }, + { id: 11, name: '11' }, + { id: 12, name: '12' }, + { id: 13, name: '13' }, + { id: 14, name: '14' }, + { id: 15, name: '15' }, + { id: 16, name: '16' }, + { id: 17, name: '17' }, + { id: 18, name: '18' }, + { id: 19, name: '19' }, + { id: 20, name: '20' }, + { id: 21, name: '21' }, + { id: 22, name: '22' }, + { id: 23, name: '23' }, + { id: 24, name: '24' }, + { id: 25, name: '25' }, + { id: 26, name: '26' }, + { id: 27, name: '27' }, + { id: 28, name: '28' }, + { id: 29, name: '29' }, + { id: 30, name: '30' }, + { id: 31, name: '31' } + ]; + minutes = [ + { id: 0, name: '00' }, + { id: 1, name: '01' }, + { id: 2, name: '02' }, + { id: 3, name: '03' }, + { id: 4, name: '04' }, + { id: 5, name: '05' }, + { id: 6, name: '06' }, + { id: 7, name: '07' }, + { id: 8, name: '08' }, + { id: 9, name: '09' }, + { id: 10, name: '10' }, + { id: 11, name: '11' }, + { id: 12, name: '12' }, + { id: 13, name: '13' }, + { id: 14, name: '14' }, + { id: 15, name: '15' }, + { id: 16, name: '16' }, + { id: 17, name: '17' }, + { id: 18, name: '18' }, + { id: 19, name: '19' }, + { id: 20, name: '20' }, + { id: 21, name: '21' }, + { id: 22, name: '22' }, + { id: 23, name: '23' }, + { id: 24, name: '24' }, + { id: 25, name: '25' }, + { id: 26, name: '26' }, + { id: 27, name: '27' }, + { id: 28, name: '28' }, + { id: 29, name: '29' }, + { id: 30, name: '30' }, + { id: 31, name: '31' }, + { id: 32, name: '32' }, + { id: 33, name: '33' }, + { id: 34, name: '34' }, + { id: 35, name: '35' }, + { id: 36, name: '36' }, + { id: 37, name: '37' }, + { id: 38, name: '38' }, + { id: 39, name: '39' }, + { id: 40, name: '40' }, + { id: 41, name: '41' }, + { id: 42, name: '42' }, + { id: 43, name: '43' }, + { id: 44, name: '44' }, + { id: 45, name: '45' }, + { id: 46, name: '46' }, + { id: 47, name: '47' }, + { id: 48, name: '48' }, + { id: 49, name: '49' }, + { id: 50, name: '50' }, + { id: 51, name: '51' }, + { id: 52, name: '52' }, + { id: 53, name: '53' }, + { id: 54, name: '54' }, + { id: 55, name: '55' }, + { id: 56, name: '56' }, + { id: 57, name: '57' }, + { id: 58, name: '58' }, + { id: 59, name: '59' }, + ]; + AtoZ = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + WeekDaysList = [ + { + "ItemKey": "MONDAY", + "Itemkey2": "Monday", + "ItemToDisplay": "Mon", + "ItemOrder": 1, + }, + { + "ItemKey": "TUESDAY", + "Itemkey2": "Tuesday", + "ItemToDisplay": "Tue", + "ItemOrder": 2, + }, + { + "ItemKey": "WEDNESDAY", + "Itemkey2": "Wednesday", + "ItemToDisplay": "Wed", + "ItemOrder": 3, + }, + { + "ItemKey": "THURSDAY", + "Itemkey2": "Thursday", + "ItemToDisplay": "Thu", + "ItemOrder": 4, + }, + { + "ItemKey": "FRIDAY", + "Itemkey2": "Friday", + "ItemToDisplay": "Fri", + "ItemOrder": 5, + }, + { + "ItemKey": "SATURDAY", + "Itemkey2": "Saturday", + "ItemToDisplay": "Sat", + "ItemOrder": 6, + }, + { + "ItemKey": "SUNDAY", + "Itemkey2": "Sunday", + "ItemToDisplay": "Sun", + "ItemOrder": 7, + } + ]; + // flight contract + CabinsClassType = [ + { value: 'Y', displayName: 'Economy' }, + { value: 'W', displayName: 'Premium Economy' }, + { value: 'C', displayName: 'Business Class' }, + { value: 'F', displayName: 'First Class' }, + ]; + RefundType = [ + { value: 'REFUNDABLE', displayName: 'Refundable' }, + { value: 'NONREFUNDABLE', displayName: 'Non-Refundable' }, + ]; + ConfirmationType = [ + { value: 'YES', displayName: 'Instant' }, + { value: 'NO', displayName: 'Manual' }, + ]; + PaxTypes = [ + { value: 'A', displayName: 'Adult' }, + { value: 'C', displayName: 'Child' }, + { value: 'I', displayName: 'Infant' }, + ]; + AmountType = [ + { value: 'FIXED', displayName: 'Fixed' }, + { value: 'PERCENTAGE', displayName: 'Percentage' }, + ]; + BagUnit = [ + { value: 'KG', displayName: 'KG' }, + { value: 'POUNDS', displayName: 'Pounds' }, + { value: 'PIECE', displayName: 'Piece' }, + { value: 'TEXT', displayName: 'Text' }, + ]; + dateType = [ + { value: '1', displayName: 'Departure Date' }, + { value: '2', displayName: 'Return Date' }, + ]; + FareTypeApp = [ + { value: 'ONEWAY', displayName: 'Oneway Only' }, + { value: 'ROUNDTRIP', displayName: 'Roundtrip / Multicity Only' }, + { value: 'BOTH', displayName: 'Both' }, + ]; + Confirmation_Type = [ + { value: 'INSTANT', displayName: 'Instant' }, + { value: 'MANUAL', displayName: 'Manual' }, + ]; +} \ No newline at end of file diff --git a/src/app/core/common/validation.service.ts b/src/app/core/common/validation.service.ts new file mode 100644 index 0000000..0aff256 --- /dev/null +++ b/src/app/core/common/validation.service.ts @@ -0,0 +1,156 @@ +import { Injectable } from '@angular/core'; +import { AbstractControl, FormControl, ValidatorFn, Validators } from '@angular/forms'; + +@Injectable({ + providedIn: 'root', +}) + +export class ValidationService { + regExps = { + password: /^[0-9]{6}$/, + passwordV2: /(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,<>\/?~])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}/, + mobCode: /^[0-9]{2,4}$/, + mobNum: /^[0-9]*$/, + numbers: /[0-9]/, + decimal: /^(0|[1-9.]\d*)(\.\d+)?$/, + alpha_numeric: /^[a-zA-Z ]*$/, + lower_case: /[a-z]/, + Capital_case: /[A-Z]/, + special_characters: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/, + lat_long: /^-?(?=.*\d\.\d)(?!.*\.\d*\.)\d+\.?\d*$/ + }; + get email() { + return new FormControl('', [Validators.required, Validators.email]); + } + get email_non_required() { + return new FormControl('', [Validators.email]); + } + get passwordV2() { + return new FormControl('', [ + Validators.required, + Validators.pattern(this.regExps['passwordV2']), + ]); + } + get passwordV2_non_required() { + return new FormControl('', [ + Validators.required, + Validators.pattern(this.regExps['passwordV2']), + ]); + } + get password() { + return new FormControl('', [ + Validators.required, + Validators.pattern(this.regExps['password']), + ]); + } + get password_non_required() { + return new FormControl('', [ + Validators.pattern(this.regExps['password']), + ]); + } + get number() { + return new FormControl('', [ + Validators.required, + Validators.pattern(this.regExps['mobNum']), + ]); + } + get mobNo() { + return new FormControl('', [ + Validators.pattern(this.regExps['mobNum']), + Validators.required, + ]); + } + get alpha_numeric() { + return new FormControl('', [ + Validators.pattern(this.regExps['alpha_numeric']) + ]); + } + get alphaNumericWithReq() { + return new FormControl('', [ + Validators.pattern(this.regExps['alpha_numeric']), + Validators.required, + ]); + } + get required() { + return new FormControl(null, [Validators.required]); + } + + get decimal() { + return new FormControl('', [ + Validators.pattern(this.regExps['decimal']), + Validators.required, + ]); + } + get numreq() { + return new FormControl('', [ + Validators.pattern(this.regExps['mobNum']), + Validators.required, + ]); + } + get lat_long() { + return new FormControl('', [ + Validators.pattern(this.regExps['lat_long']), + Validators.required, + ]); + } + + + + onBlur(Control, validationType) { + return Control.hasError(validationType) && Control.touched; + } + + + getFormArrControls(formArrayName, index, controlName) { + return formArrayName.controls[index].controls[controlName]; + } + + showValidationsMsg(form) { + form.markAllAsTouched(); + } + + prioirtyValidation(alldata) { + let message = null + let pri_arr = alldata.filter((el, ind) => { + return alldata.findIndex(e => e.priority == el.priority) != ind; + }); + let negative_pr = alldata.filter(e => e.priority < 0); + let max_pr = alldata.filter(e => e.priority > 100); + let zero_pr = alldata.filter(e => e.priority == 0) + if (negative_pr.length > 0) { + message = "Priority can't be negative" + } else if (pri_arr.length > 0) { + message = "Priority can't be same" + } else if (max_pr.length > 0) { + message = "Priority can't be above 100" + } else if (zero_pr.length > 0) { + message = "Priority can't be 0" + } + return message + } + + + scrollTo(el: Element): void { + if (el) { + el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } + scrollToError(): void { + const errorInput = document.querySelector('.ErrorWrapper'); + const errorspan = document.querySelector('.errorspan'); + this.scrollTo(errorInput ? errorInput : errorspan); + } + dateRangeValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + + +} \ No newline at end of file diff --git a/src/app/core/guard/auth.guard.ts b/src/app/core/guard/auth.guard.ts new file mode 100644 index 0000000..e2afb30 --- /dev/null +++ b/src/app/core/guard/auth.guard.ts @@ -0,0 +1,43 @@ +// Angular +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +// RxJS +import { Observable } from 'rxjs'; +import { securityFunctions } from '../common/security'; +@Injectable() +export class AuthGuard implements CanActivate { + constructor( + private router: Router) { } + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { + if (securityFunctions.getSessionStorage('LoginUserData')) { + let userdata = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + if (userdata) { + if (userdata.user_id) { + // let tpinApplicable = sessionStorage.getItem('TpinApplicable') == 'true' ? true : false; + // let tpinActivated = sessionStorage.getItem('T_Activated') == 'true' ? true : false; + // let tpinExpired = sessionStorage.getItem('T_Expired') == 'true' ? true : false; + // if (tpinApplicable) { + // if (!tpinActivated || tpinExpired) { + // let userId = sessionStorage.getItem('userId') + // const now = new Date(); + // const formattedDate = now.toISOString().slice(0, 19).replace('T', ' '); + // let keyVal = securityFunctions.EncryptReq(userId + '~' + formattedDate + '~' + (tpinExpired ? 'expired' : 'create')).trim() + // this.router.navigate(['/Login/TPIN'], { queryParams: { key: keyVal } }) + // return false; + // } + // else { + // return true + // } + // } + return true + } + return false + } + return false; + } else { + window.location.href = '/Auth/Login'; + return false; + } + } +} diff --git a/src/app/core/models/Experience-Service/experience-manage-languag/experience-manage-lang.model.ts b/src/app/core/models/Experience-Service/experience-manage-languag/experience-manage-lang.model.ts new file mode 100644 index 0000000..b5b7287 --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-manage-languag/experience-manage-lang.model.ts @@ -0,0 +1,27 @@ + +export class ActivityContent { + activity_content_id: string | null; + org_id: string | null; + activity_id: string; + supplier_id: string; + language_code: string; + activity_name: string; + departure_point: string; + meeting_point: string; + drop_point: string; + activity_highlight: string; + activity_description: string; + activity_restriction: string; + activities_details: string; + activity_inclusion: string; + activity_exclusion: string; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean; + is_deleted: boolean; + additional_pick_up_details: string; + daywise_itinerary: string; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model.ts b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model.ts new file mode 100644 index 0000000..ce0c44d --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model.ts @@ -0,0 +1,31 @@ + +export class AllocationItems { + activity_allocation_id: string | null; + activity_contract_id: string | null; + activity_slot_id: string | null; + _date: string; + allocation_count: number | null; + release_days: number | null; + _allocation_type: string | null; + is_active: boolean; +} + + +export class UpdateAllocation { + activity_contract_id: string | null; + activity_slot_id: string | null; + allocationItems: AllocationItems[]; +} + +export class AllocationOverview { + activity_allocation_id: string | null; + activity_contract_id: string | null; + activity_slot_id: string | null; + _date: string; + allocation_count: number | null; + release_days: number | null; + booking_count: number | null; + remaining_count: number | null; + _allocation_type: string | null; + is_active: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model.ts b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model.ts new file mode 100644 index 0000000..759885b --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model.ts @@ -0,0 +1,30 @@ +export class CancellationDisplay { + activity_cancellation_policy_id: string; + date: string; + _cancellation_policy_type: string; + from: number; + to: number; + _charge_type: string; + charge_value: number; +} +export class GetCancellationPolicy { + contract_id: string; + from_date: string | null; + to_date: string | null; + slot_id: string | null; + seasonId: string[] | null; + days: string | null; +} + + +export class UpdateCancellationPolicy { + activity_contract_id: string; + _no_show_policy_type: string; + no_show_value: number; + cancellation_policy: CancellationDisplay[]; +} + +// export class UpdateCancellationPolicy { +// activity_contract_id: string; +// cancellation_policy: CancellationDisplay[]; +// } \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model.ts b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model.ts new file mode 100644 index 0000000..b27665c --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model.ts @@ -0,0 +1,16 @@ +export class EditActivityContractDetail { + contract_id: string; + option_name: string; + currency_code: string; + language_code: string; + include_nationality_code: string; + exclude_nationality_code: string; + _nationality_type: string; + is_exclude_nationality: boolean; + rate_inclusion: string; + contract_remark: string; + is_pickup_included: boolean; + is_drop_off_included: boolean; + is_guide_included: boolean; + guide_languages: string; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model.ts b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model.ts new file mode 100644 index 0000000..a9dade9 --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model.ts @@ -0,0 +1,80 @@ + + + +export class ActivityAllContract { + activity_id: string; + option_name: string | null; + is_pickup_included: boolean; + is_drop_off_included: boolean; +} + +export class GetRateDetails { + contract_id: string; + slot_id: string | null; + from_date: string | null; + to_date: string | null; + dates: string | null; + seasonId: string[] | null; + days: string | null; +} + +// export class GetTieredRateDetail { +// contract_id: string; +// slot_id: string; +// dates: string; +// days: string; +// } + + +export class EditActivityContractRate { + activity_contract_id: string; + activity_slot_id: string; + perPaxPrices: PaxRates[] | null; + perVehicleRates: VehicleRates[] | null; + tieredPricings: TieredPricingList[] | null; + privateTransfer: ActivityPrivateTransfer[] | null; + sharedTransfer: ActivitySharedTransfer | null; +} +export class PaxRates { + activity_rate_per_pax_id: string; + date: string; + adult_rate: number; + senior_rate: number; + youth_rate: number; + child_rate: number; +} + + +export class VehicleRates { + activity_rate_per_vehicle_id: string; + vehicle_supplier_id: string; + vehicle_id: string; + vehicle_max_occupancy: string; + date: string; + rate: number; +} + +export class TieredPricingList { + id: string; + pricing: PaxPricing[]; +} + +export class PaxPricing { + pax_type: string; + sequence: number; + rate: number; +} + +export class ActivityPrivateTransfer { + vehicle_id: string; + vehicle_occupancy: string; + vehicle_supplier_id: string; + rate: number; +} +export class ActivitySharedTransfer { + vehicle_supplier_id: string; + adult_rate: number; + senior_rate: number; + youth_rate: number; + child_rate: number; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model.ts b/src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model.ts new file mode 100644 index 0000000..e25bb29 --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model.ts @@ -0,0 +1,157 @@ + + +export class SaveActivityContractDetails { + activityContract: ActivityContract; + activityContractDetails: ActivityDetails[]; + privateTransfer: ActivityPrivateTransfer[]; + sharedTransfer: ActivitySharedTransfer; + incNationalityCodes: string[] | null; + excNationalityCodes: string[] | null; + seasonIdsForRateDates: string[] | null; + datesForRates: DateRange[]; + slotDetails: SlotDetails[] | null; + activityCancellationDetails: ActivityCancellationDetails[] | null; +} + +export class ActivityPrivateTransfer { + vehicle_id: string; + vehicle_occupancy: string; + vehicle_supplier_id: string; + rate: number; +} +export class ActivitySharedTransfer { + vehicle_supplier_id: string; + adult_rate: number; + senior_rate: number; + youth_rate: number; + child_rate: number; +} + +export class Specific { + specificTimeSlot: DateRange[]; + specificSlotRateRange: RateRange; + activityPaxRate: ActivityPaxRate; + activityVehicleRate: ActivityVehicleRate; +} + +export class SlotDetails { + slot: Slot[]; + applicableDays: string; + rateRange: RateRange | null; + activityPaxRate: ActivityPaxRate | null; + activityVehicleRate: ActivityVehicleRate[] | null; + activityCancellationDetails: ActivityCancellationDetails[] | null; +} +export class Slot { + slotId: string; + is_private_transfer: boolean; + is_shared_transfer: boolean; + is_without_transfer: boolean; +} + + +export class ActivityContract { + activity_contract_id: string | null; + org_id: string | null; + supplier_id: string; + activity_id: string | null; + currency_code: string; + _nationality_type: string; + is_exclude_nationality: boolean; + _period_type: string; + season_id: string; + is_pickup_included: boolean; + is_drop_off_included: boolean; + is_private_transfer_price_included: boolean; + is_shared_transfer_price_included: boolean; + is_slot_wise_cancellation_policy: boolean; + is_guide_included: boolean; + guide_languages: string; + _rate_type: string; + _pricing_type: string; + _no_show_policy_type: string; + no_show_charge_value: number; + is_approved: boolean; + is_rejected: boolean; + reviewed_by: string; + reviewer_comments: string; + reviewer_user_type: string; + reviewed_on: string | null; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean; + is_deleted: boolean; +} + +export class ActivityDetails { + language_code: string; + option_name: string; + rate_inclusion: string; + contract_remark: string; +} +export class DateRange { + Start: string; + End: string; +} + +export class AgeRange { + from_count: number; + to_count: number; + sequence: number; + rate: number; +} + + +export class RateRange { + adultAgeRange: AgeRange[]; + youthAgeRange: AgeRange[]; + seniorAgeRange: AgeRange[]; + childAgeRange: AgeRange[]; + allocationDetails: AllocationDetails | null; +} + + +export class ActivityPaxRate { + date: string; + adult_rate: number; + senior_rate: number; + youth_rate: number; + child_rate: number; + allocationDetails: AllocationDetails | null; +} +export class Slots { + slotId: string; + is_private_transfer: boolean; + is_shared_transfer: boolean; + is_without_transfer: boolean; +} + +export class ActivityVehicleRate { + rate: number; + vehicle_supplier_id: number; + vehicle_id: number; + vehicle_max_occupancy: number; + allocationDetails: AllocationDetails | null; +} + +export class ActivityCancellationDetails { + from: number; + to: number; + CP_Type: string; + CP_Value: number; + cancellation_Type: string; +} + +export class AllocationDetails { + _allocation_type: string; + allocation_count: number; + booking_count: number; + vehicle_id: string; + remaining_count: number; + _release_type: string; + date: string; + release_days: number; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/experience-sevice-add/experience-service-add.model.ts b/src/app/core/models/Experience-Service/experience-sevice-add/experience-service-add.model.ts new file mode 100644 index 0000000..b398710 --- /dev/null +++ b/src/app/core/models/Experience-Service/experience-sevice-add/experience-service-add.model.ts @@ -0,0 +1,88 @@ + +export class experience_add { + activity_id: string; + org_id: string; + supplier_id: string; + activity_code: number; + category_id: string; + emergency_phone_code: string; + emergency_phone_nbr: string; + default_lang_code: string; + _service_language: string; + service_days: number; + service_hours: number; + service_minutes: number; + starting_city: string; + is_pickup_included: boolean; + _pickup_point_type: string; + _hotel_pickup_type: string; + pickup_hotel: string; + hotel_zone: string; + pickup_before_hour: number; + pickup_before_minute: number; + meeting_before_hour: number; + meeting_before_minute: number; + is_drop_included: boolean; + min_pax: number; + max_pax: number; + is_adult: boolean; + adult_age_from: number; + adult_age_to: number; + is_senior: boolean; + senior_age_from: number; + senior_age_to: number; + is_youth: boolean; + youth_age_from: number; + youth_age_to: number; + is_child: boolean; + child_age_from: number; + child_age_to: number; + max_child_count: number; + free_child_age_from: number; + free_child_age_to: number; + is_child_seat: boolean; + thumbnail_image: string; + activity_images: string; + activity_videos: string; + requirements: string; + revision_nbr: number; + created_by: string; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean | null; + is_deleted: boolean | null; + category_name: string; + sub_category_id: string; + country_code: string; + city_id: string; + activityContents: ActivityContent[]; + activity_content_json: string; +} + +export class ActivityContent { + activity_content_id: string; + org_id: string; + activity_id: string; + supplier_id: string; + language_code: string; + activity_name: string; + departure_point: string; + meeting_point: string; + drop_point: string; + activity_highlight: string; + activity_description: string; + activity_restriction: string; + activities_details: string; + activity_inclusion: string; + activity_exclusion: string; + revision_nbr: number; + created_by: string; + created_on: string; + updated_by: string; + updated_on: string; + is_active: boolean; + is_deleted: boolean; + additional_pick_up_details: string; + daywise_itinerary: string; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/season-setting/season-setting-add.model.ts b/src/app/core/models/Experience-Service/season-setting/season-setting-add.model.ts new file mode 100644 index 0000000..e8adb3f --- /dev/null +++ b/src/app/core/models/Experience-Service/season-setting/season-setting-add.model.ts @@ -0,0 +1,23 @@ +export class ActivitySeasonDetails { + activitySeason: ActivitySeason; + seasondateRange: ActivitySeasonDateRange[]; +} + +export class ActivitySeasonDateRange { + fromDate: string; + toDate: string; +} + +export class ActivitySeason { + activity_season_id: string; + org_id: string; + activity_id: string; + supplier_id: string; + season_name: string; + created_by: string; + created_on: string; + updated_by: string; + updated_on: string; + is_active: boolean; + is_deleted: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/Experience-Service/slot/add-slots-model.ts b/src/app/core/models/Experience-Service/slot/add-slots-model.ts new file mode 100644 index 0000000..5ed5814 --- /dev/null +++ b/src/app/core/models/Experience-Service/slot/add-slots-model.ts @@ -0,0 +1,24 @@ +export class ActivitySlot { + activity_slot_id: string; + org_id: string; + supplier_id: string; + activity_id: string; + start_time: string; + end_time: string; + cut_off_time: string | null; + timezone: string | null; + revision_nbr: number; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean | null; + is_deleted: boolean | null; +} +export class GetActivitySlot { + activity_id: string; + from_hour: string | null; + from_minute: string | null; + to_hour: string | null; + to_minute: string | null; +} \ No newline at end of file diff --git a/src/app/core/models/common-model/Sign-in.model.ts b/src/app/core/models/common-model/Sign-in.model.ts new file mode 100644 index 0000000..92c87cc --- /dev/null +++ b/src/app/core/models/common-model/Sign-in.model.ts @@ -0,0 +1,58 @@ +export class LoginModel { + EmailID: string + Password: string + domain: string + ProjectId: string + MachineId: string + Platform: string + Browser: string + City: string + CountryCode: string + Lat: number + Lon: number + Proxy: boolean + IP: string + time: string +} + +export class OTPModel { + oTP: string; + userId: string; + city: string; + ProjectId: string; + countryCode: string; + lat: number; + lon: number; + proxy: boolean; + iP: string; + platform: string | null; + browser: string | null; + macId: string | null; +} + +export class SSOModel { + emailID: string; + domain: string; +} + +export class dtoKey { + key: string; +} + +export class agency_data { + is_pay_at_agency: boolean; + time_zone: string; + b2c_agency_code: string; + utc: string; + pay_at_agency_disclaimer: string; + org_id: string; + b2c_agency_id: string; + project: string; + domain: string; + is_active: boolean; +} +export class SSOLoginModel { + isSSO: boolean + isLoggedIn: boolean + token: string +} \ No newline at end of file diff --git a/src/app/core/models/common-model/user-logout.model.ts b/src/app/core/models/common-model/user-logout.model.ts new file mode 100644 index 0000000..38cfad6 --- /dev/null +++ b/src/app/core/models/common-model/user-logout.model.ts @@ -0,0 +1,11 @@ +export class UserLog{ + user_id:string; + user_type:string; + IsMFAApplicable:boolean; + ip_city:string; + ip_country_code:string; + ip_lat:number; + ip_lon:number; + ip_proxy:boolean; + ip:string; +} \ No newline at end of file diff --git a/src/app/core/models/common-model/userModel.ts b/src/app/core/models/common-model/userModel.ts new file mode 100644 index 0000000..0c05908 --- /dev/null +++ b/src/app/core/models/common-model/userModel.ts @@ -0,0 +1,66 @@ +export class changeUserLoginPassword { + user_id: string; + org_id: string; + first_name: string; + middle_name: string; + last_name: string; + user_mobile_country_code: string; + user_mobile: string; + email: string; + password: string; + country: string; + city: string; + user_type: string; + affiliate_id: string; + affiliate_type: string; + user_profile: string; + user_role: string; + is_active: boolean; + created_by: string; + updated_by: string; + created_on: string; + updated_on: string; + time_zone: string; +} + +export class UserLoginData { + user_id: string; + org_id: number; + first_name: string; + middle_name: string; + last_name: string; + user_mobile_country_code: string; + user_mobile: string; + email: string; + password: string; + country: string; + city: string; + user_type: string; + user_profile: string; + user_role: string; + is_active: boolean; + created_on: Date; + created_by: string; + updated_on: Date; + updated_by: string; + affiliate_id: number; + markup_type: string; + is_mfa_applicable: boolean; + is_inactive_wrong_attempt: boolean; + is_cancel_pnr: boolean; + is_cancel_ticketed_pnr: boolean; + is_import_pnr_access: boolean; + is_allow_void_ticket: boolean; + last_log_on: Date; + is_password_expired: boolean; + is_login_expired: boolean; + role_id: number; + jwt_token_id: number; + refresh_token: string; + refresh_token_expire_at: Date; + change_default_password: boolean; + is_b2b_surcharge: boolean; + is_reserve_hotel_booking: boolean; + extranet_vendor_id: string; + timezone: string; +} diff --git a/src/app/core/models/flight-service/flight-contracts.model.ts b/src/app/core/models/flight-service/flight-contracts.model.ts new file mode 100644 index 0000000..97962ae --- /dev/null +++ b/src/app/core/models/flight-service/flight-contracts.model.ts @@ -0,0 +1,221 @@ + + +export class FlightContractDTO { + contract_id: string | null; + org_id: string | null; + supplier_id: string; + contract_name: string; + contract_description: string; + pnr: string; + is_instant_confirmation: boolean; + _trip_type: string; + no_of_legs: number; + from_airport: string; + to_airport: string; + is_economy: boolean; + is_premium_economy: boolean; + is_business: boolean; + is_first_class: boolean; + is_all_pax_type: boolean; + is_adult: boolean; + is_child: boolean; + is_infant: boolean; + currency_code: string; + validating_airline: string; + is_multi_day: boolean; + is_multi_day_range: boolean; + outbound_date: string; + return_date: string; + operation_from: string; + operation_to: string; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean | null; + is_deleted: boolean | null; + outbound_days: string | null; + outbound_dates: string | null; + flightDetail: FlightDetailDto[]; + flightRate: FlightsRateDto[]; +} +export class FlightsRateDto { + rate_id: string | null; + org_id: string | null; + supplier_id: string | null; + contract_id: string | null; + contract_date_unique_id: string | null; + outbound_date: string; + return_date: string; + rbd: string; + cabin_class: string; + adt_base_fare: number; + adt_tax: number; + chd_base_fare: number; + chd_tax: number; + inf_base_fare: number; + inf_tax: number; + seat_allocation: number; + seat_booked: number; + seat_remaining: number; + adt_check_bag: number; + chd_check_bag: number; + inf_check_bag: number; + _check_bag_unit: number; + adt_cabin_bag: number; + chd_cabin_bag: number; + inf_cabin_bag: number; + _cabin_bag_unit: number; + _fare_type: number; + adt_fare_rule: string; + chd_fare_rule: string; + inf_fare_rule: string; + is_meal_included: boolean; + meal_details: string; + inclusions: string; + pnr: string; + is_instant_confirmation: boolean; + is_stop_sale: boolean; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean | null; + is_deleted: boolean | null; +} +// +export class FlightContractReq { + FlightContract: FlightContracts; + FlightDetails: FlightDetailDto[]; + FlightRates: FlightRateArray[]; +} +export class FlightContracts { + contract_name: string; + contract_description: string; + trip_type: string; + origin: string; + destination: string; + no_of_legs: number; + currency_code: string; + contracted_cabin_class: string; + contracted_pax_type: string; + validating_airline: string; + is_multi_day: boolean; + is_oneway_sale_allowed: boolean; + multi_day_operation_type: string; + operation_from: string; // Assuming you'll handle date parsing separately + operation_to: string; // Assuming you'll handle date parsing separately + departure_date: string; // Assuming you'll handle date parsing separately + return_date: string; // Assuming you'll handle date parsing separately + departure_days: string; + departure_dates: string; + is_nearby_airports: boolean; + is_active: boolean; + nearby_from_airports: string; + nearby_to_airports: string; + is_instant_confirmation: boolean; +} + +export class FlightDetailDto { + flight_details_id: string | null; + org_id: string | null; + supplier_id: string | null; + contract_id: string | null; + airline_code: string; + flight_no: string; + aircraft_type_id: string; + from_airport: string; + to_airport: string; + departure_date: string; + departure_time: string; + is_next_day_departure: boolean; + departure_terminal: string; + is_next_day_arrival: boolean; + arrival_date: string; + arrival_time: string; + arrival_terminal: string; + flying_duration: string; + sector_nbr: number | null; + _sector_type: string; + leg_nbr: number; + seg_nbr: number; + contract_date_unique_id: string | null; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean | null; + is_deleted: boolean | null; +} +export class FlightRateArray { + rate_id: string; + org_id: string; + contract_id: string; + contract_date_unique_id: string; + departure_date: Date; + rbd: string; + fare_family_group_id: string; + fare_family_name: string; + cabin_class: string; + adt_base_fare: number; + adt_tax: number; + chd_base_fare: number; + chd_tax: number; + inf_base_fare: number; + inf_tax: number; + fare_type_applicability: string; + round_trip_discount_type: string; + is_apply_discount_with_same_vc_only: boolean; + adult_round_trip_discount: number; + child_round_trip_discount: number; + infant_round_trip_discount: number; + seat_allocation: number; + seat_booked: number; + seat_cancelled: number; + is_checked_bag_included: boolean; + adt_check_bag: string; + chd_check_bag: string; + inf_check_bag: string; + _check_bag_unit: string; + adt_cabin_bag: string; + chd_cabin_bag: string; + inf_cabin_bag: string; + _cabin_bag_unit: string; + refund_type: string; + adt_fare_rule: string; + chd_fare_rule: string; + inf_fare_rule: string; + is_meal_included: boolean; + meal_details: string; + inclusions: string; + pnr: string; + is_instant_confirmation: boolean; + is_stop_sale: boolean; + updated_by: string; +} +export class FlightDetailsSearchModel { + contract_name: string; + vendor_id: string; + validating_airline: string; + trip_type: string; + flight_no: string; + cabin_class: string; + origin: string; + destination: string; + departure_days: string; + date_type: string; + from_date: string; + to_date: string; + pnr: string; + currency_code: string; + refund_type: string; + rbd: string; + is_instant_confirmation: boolean; + is_multi_day: boolean; + is_oneway_sale_allowed: boolean; + airline_code: any; + confirmation_type: string; +} \ No newline at end of file diff --git a/src/app/core/models/flight-service/flight-service-manage/edit-Rate-inventry.model.ts b/src/app/core/models/flight-service/flight-service-manage/edit-Rate-inventry.model.ts new file mode 100644 index 0000000..88a401b --- /dev/null +++ b/src/app/core/models/flight-service/flight-service-manage/edit-Rate-inventry.model.ts @@ -0,0 +1,44 @@ +export class FlightRateobj { + _id: string; + _from_date: string; + _to_date: string; + days: string; + _rbd: string; +} + + + +export class UpdateFlightRate { + contract_id: string; + flight_rate: dtoFlightRate[]; +} + +export class dtoFlightRate { + rate_id: string; + outbound_date: string; + adt_base_fare: number; + adt_tax: number; + chd_base_fare: number; + chd_tax: number; + inf_base_fare: number; + inf_tax: number; + seat_allocation: number; + adt_check_bag: number; + chd_check_bag: number; + inf_check_bag: number; + _check_bag_unit: number; + adt_cabin_bag: number; + chd_cabin_bag: number; + inf_cabin_bag: number; + _cabin_bag_unit: number; + _fare_type: number; + adt_fare_rule: string; + chd_fare_rule: string; + inf_fare_rule: string; + is_meal_included: boolean; + meal_details: string; + inclusions: string; + pnr: string; + is_instant_confirmation: boolean; + is_stop_sale: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/flight-service/flight-service-manage/edit-contract-details.model.ts b/src/app/core/models/flight-service/flight-service-manage/edit-contract-details.model.ts new file mode 100644 index 0000000..d0598bd --- /dev/null +++ b/src/app/core/models/flight-service/flight-service-manage/edit-contract-details.model.ts @@ -0,0 +1,13 @@ +export class ContractDetailDto { + contract_id: string; + contract_name: string; + contract_description: string; + is_premium_economy: boolean; + is_economy: boolean; + is_business: boolean; + is_first_class: boolean; + is_all_pax_type: boolean; + is_adult: boolean; + is_child: boolean; + is_infant: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/flight-service/flight-service-manage/edit-flight-details.model.ts b/src/app/core/models/flight-service/flight-service-manage/edit-flight-details.model.ts new file mode 100644 index 0000000..25236ca --- /dev/null +++ b/src/app/core/models/flight-service/flight-service-manage/edit-flight-details.model.ts @@ -0,0 +1,24 @@ +export class UpdateFlightDetail { + contract_id: string; + departure_dates: string; + outbound_days: string; + flight_detail: FlightDetailobj[]; +} + +export class FlightDetailobj { + airline_code: string; + flight_no: string; + _aircraft_type: string; + from_airport: string; + to_airport: string; + departure_time: string; + is_next_day_departure: boolean; + departure_terminal: string; + is_next_day_arrival: boolean; + arrival_time: string; + arrival_terminal: string; + flying_duration: string; + sector_nbr: number | null; + _sector_type: string; + leg_nbr: number; +} \ No newline at end of file diff --git a/src/app/core/models/flight-service/flight-service-search/flight-service-search.model.ts b/src/app/core/models/flight-service/flight-service-search/flight-service-search.model.ts new file mode 100644 index 0000000..7ac6835 --- /dev/null +++ b/src/app/core/models/flight-service/flight-service-search/flight-service-search.model.ts @@ -0,0 +1,25 @@ +export class FlightContractSearhObj { + contract_name: string; + supplier_name: string; + _trip_type: string; + airline_code: string; + flight_no: string; + from_airport: string; + to_airport: string; + dep_from_date: string; + dep_to_date: string; + ret_from_date: string; + ret_to_date: string; + dep_days: string; + ret_days: string; + is_multi_day: boolean; + pnr: string; + rbd: string; + currency_code: string; + fare_type: number; + is_instant_confirmation: boolean; + is_economy: boolean; + is_premium_economy: boolean; + is_business: boolean; + is_first_class: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/hotelService/AddRoom/Room.model.ts b/src/app/core/models/hotelService/AddRoom/Room.model.ts new file mode 100644 index 0000000..59066e0 --- /dev/null +++ b/src/app/core/models/hotelService/AddRoom/Room.model.ts @@ -0,0 +1,73 @@ + + +export class ContractRoom { + room_id: string; + org_id: string; + supplier_id: string; + room_category_name_code: number; + is_living_room: boolean; + living_room_count: number; + living_bed_count: number; + living_bed_type: number; + is_living_bed:boolean + is_bedroom: boolean; + bedroom_count: number; + bed_count: string; + is_bathroom: boolean; + bathroom_count: number; + is_bathtub: boolean; + is_jacuzzi: boolean; + room_size: number; + room_measure_unit: string; + room_images: string; + thumbnail_image: string; + display_room_name: string; + extra_bed_type: number; + hotel_id: string; + hotel_code: number; + room_view_code: number; + room_type_code: number; + room_code: number; + max_adult: number; + max_child: number; + min_total_occupancy: number; + max_total_occupancy: number; + min_adult_age: number; + min_child_age: number; + max_child_age: number; + is_extra_bed_supported: boolean; + max_extra_bed_count: number; + free_child_count: number; + free_child_age_from: number; + free_child_age_to: number; + is_group_rate: boolean; + is_paid_child_age_range: boolean; + room_amenity_codes: string; + revision_nbr: number; + is_deleted: boolean; + is_active: boolean; + created_by: string; + created_on: string; + updated_by: string | null; + updated_on: string | null; + contract_paid_child_age_range: ContractRoomPaidChildAgeRange[]; +} + + +export class ContractRoomPaidChildAgeRange { + contract_paid_child_age_range_id: string; + org_id: string; + supplier_id: string; + room_id: string; + from_age: number; + to_age: number; + sequence: number; + revision_nbr: number; + is_deleted: boolean; + is_active: boolean; + created_by: string; + created_on: string; + updated_by: string | null; + updated_on: string | null; + is_child_range: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/hotelService/OverViewData/RoomsOverView.model.ts b/src/app/core/models/hotelService/OverViewData/RoomsOverView.model.ts new file mode 100644 index 0000000..b0dddae --- /dev/null +++ b/src/app/core/models/hotelService/OverViewData/RoomsOverView.model.ts @@ -0,0 +1,34 @@ +export class OverViewData { + Date: any[]; + RoomDetails : roomsOverViewData[]; +} +export class roomsOverViewData { + room_name: string; + room_id: string; + currency_code: string; + status: string[]; + allocation: AllocationDet[]; + allocation_id: any[]; + net_sold: any[]; + availability: any[]; + RoomContractDetails: ContractDetails[]; +} +export class AllocationDet{ + id:string; + value:any; +} +export class ContractDetails { + contract_name: string; + aria_collapse: boolean; + rate_plan: string; + meal_plan: string; + child_age_range_1: string; + child_age_range_2: string; + min_stay: string[]; + ChildDataRange1: ChildDetailsArr[]; + ChildDataRange2: ChildDetailsArr[]; + AdultData: ChildDetailsArr[]; +} +export class ChildDetailsArr { + value: string[]; +} \ No newline at end of file diff --git a/src/app/core/models/hotelService/Tab-Content/tab-4/Tab-4.model.ts b/src/app/core/models/hotelService/Tab-Content/tab-4/Tab-4.model.ts new file mode 100644 index 0000000..4792bc5 --- /dev/null +++ b/src/app/core/models/hotelService/Tab-Content/tab-4/Tab-4.model.ts @@ -0,0 +1,28 @@ + +export class ViewSeason { + season: ContractSeason; + seasondateRange: SeasonDateRange[]; +} + +export class SeasonDateRange { + + fromDate: string; + toDate: string; +} + + + +export class ContractSeason { + season_id: string; + org_id: string; + supplier_id: string; + hotel_id: string; + hotel_code: string; + season_name: string; + created_by: string; + created_on: string; + updated_by: string | null; + updated_on: string | null; + is_active: boolean; + is_deleted: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/optional-ons/optional-ons.model.ts b/src/app/core/models/optional-ons/optional-ons.model.ts new file mode 100644 index 0000000..7dd25e7 --- /dev/null +++ b/src/app/core/models/optional-ons/optional-ons.model.ts @@ -0,0 +1,43 @@ + + +export class ActivityAddOn { + activity_add_on_id: string | null; + org_id: string | null; + supplier_id: string | null; + activity_id: string | null; + _rate_type: string | null; + currency_code: string | null; + per_service_rate: number; + revision_nbr: number | null; + created_by: string | null; + created_on: string | null; + updated_by: string | null; + updated_on: string | null; + is_active: boolean; + is_deleted: boolean; + adult_rate: number; + senior_rate: number; + youth_rate: number; + child_rate: number; + activityAddOnDetails: ActivityAddOnDetails[]; + activity_addon_details_json: string | null; +} + +export class ActivityAddOnDetails { + activity_add_on_details_id: string; + org_id: string; + supplier_id: string; + activity_id: string; + activity_add_on_id: string; + language_code: string; + add_on_name: string; + add_on_description: string; + add_on_image: string; + revision_nbr: number; + created_by: string; + created_on: string; + updated_by: string; + updated_on: string; + is_active: boolean; + is_deleted: boolean; +} \ No newline at end of file diff --git a/src/app/core/models/user-role-management/user-role.model.ts b/src/app/core/models/user-role-management/user-role.model.ts new file mode 100644 index 0000000..2d88b28 --- /dev/null +++ b/src/app/core/models/user-role-management/user-role.model.ts @@ -0,0 +1,61 @@ + +export class dtoRoleMaster_Root { + roleMaster: dtoRoleMaster; + roleAccessMapping: dtoRoleAccessMapping[]; + json_role_master: string; + json_role_access_mapping: string; +} + + +export class dtoRoleMaster { + role_id: string; + org_id: string; + role_name: string; + reporting_role_id: string; + role_description: string; + role_type: string; + affiliate_id: string; + extranet_vendor_id: string; + is_active: boolean | null; + created_on: string; + created_by: string; + updated_on: string; + updated_by: string; +} + + +export class dtoRoleAccessMapping { + role_access_id: string; + org_id: string; + role_id: string; + project_id: string; + menu_id: string; + permission: string; + is_active: boolean | null; + created_on: string; + created_by: string; + updated_on: string; + updated_by: string; +} + + +export class dtoRoleUserAccessUnmapping { + user_access_un_map_id: string; + org_id: string; + user_id: string; + role_id: string; + project_id: string; + menu_id: string; + permission: string; + is_active: boolean | null; + created_on: string | null; + created_by: string; + updated_on: string | null; + updated_by: string; +} + + +export class dtoRoleUserAccessUnMappingModel { + user_id: string; + user_access_unmapping_list: dtoRoleUserAccessUnmapping[]; +} \ No newline at end of file diff --git a/src/app/core/services/HotelServices/hotel_booking_management.service.ts b/src/app/core/services/HotelServices/hotel_booking_management.service.ts new file mode 100644 index 0000000..dc876c2 --- /dev/null +++ b/src/app/core/services/HotelServices/hotel_booking_management.service.ts @@ -0,0 +1,101 @@ +import { HttpClient } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { environment } from "src/environments/environment"; + +@Injectable() +export class HotelBookingManagementService { + + private headers = { 'Content-Type': 'application/json; charset=utf-8' }; + + constructor(private http: HttpClient) { + if(sessionStorage.getItem('userId')){ + this.headers['LoggedInUser'] = sessionStorage.getItem('userId'); + } + } + + // listing page + getAllAgency() { + return this.http.get(environment.APIBaseUrl + '/AgencyDetail/GetAllAffiliates', { headers: this.headers }) + } + getAllCompany() { + return this.http.get(environment.APIBaseUrl + '/CompanyMaster/GetAllCompanyDetails', { headers: this.headers }) + } + getAllEntity() { + return this.http.get(environment.APIBaseUrl + '/EntityMaster/GetAllEntity', { headers: this.headers }) + } + getAllHotelSupplier() { + return this.http.get(environment.APIBaseUrl + '/HotelSupplier/GetAllHotelSupplier', { headers: this.headers }) + } + getAllHotelSupplierV2() { + return this.http.get(environment.APIBaseUrl + '/HotelSupplierV2/GetAllHotelSupplierV2s', { headers: this.headers }) + } + getAllHotelCountry() { + return this.http.get(environment.APIBaseUrl + '/hotel/CountryList/en', { headers: this.headers }) + } + getAllHotelCityByCountry(country_code) { + return this.http.get(environment.APIBaseUrl + '/hotel/CityList/' + country_code+ '/en', { headers: this.headers }) + } + getHotelBookingList(reqData) { + return this.http.post(environment.APIBaseUrl + '/HotelBooking/GetBookingList', reqData, { headers: this.headers }) + } + bookingQualityCheck(trip_tbl_id) { + return this.http.post(environment.APIBaseUrl + '/Booking/UpdateQualityCheck/' + trip_tbl_id, null, { headers: this.headers }) + } + + // View page + getAllCurrency() { + return this.http.get(environment.APIBaseUrl + '/CurrencyMaster/GetAllCurrencies', { headers: this.headers }) + } + getCustomerDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetCustomerDetails/${trip_id}`, { headers: this.headers }) + } + GetItenaryDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetItenaryDetails/${trip_id}`, { headers: this.headers }) + } + getPassengerDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetPassengerDetails/${trip_id}`, { headers: this.headers }) + } + getCostingDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetCostingDetails/${trip_id}`, { headers: this.headers }) + } + getPaymentDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetPaymentDetails/${trip_id}`, { headers: this.headers }) + } + getDocumentDetails(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetDocumentDetails/${trip_id}`, { headers: this.headers }) + } + getNotesDetail(trip_id) { + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/GetNotesDetail/${trip_id}`, { headers: this.headers }) + } + getHotelBookingDetail(booking_id) { + const org_id = sessionStorage.getItem('org_id'); + return this.http.get(`${environment.hotelApiBaseUrl}/hotel/BookingDetails?org_id=${org_id}&booking_id=${booking_id}`, { headers: this.headers }) + } + saveConfirmationNumber(reqData) { + return this.http.post(`${environment.APIBaseUrl}/HotelBooking/SaveConfirmationNumber`, reqData, { headers: this.headers }) + } + saveNotesDetail(reqData){ + return this.http.post(`${environment.APIBaseUrl}/HotelBooking/SaveNotesDetail`, reqData, { headers: this.headers }) + } + printInvoiceDocument(document_number){ + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/SendInvoiceEmail/${document_number}`, { headers: this.headers }) + } + sendInvoiceDocumentMail(document_number, email_id){ + return this.http.get(`${environment.APIBaseUrl}/HotelBooking/SendInvoiceEmail/${document_number}/${email_id}`, { headers: this.headers }) + } + sendItineraryDocumentMail(reqData){ + return this.http.post(`${environment.APIBaseUrl}/HotelBooking/SendItineraryEmail`, reqData, { headers: this.headers }) + } + sendVoucherDocumentMail(reqData){ + return this.http.post(`${environment.APIBaseUrl}/HotelBooking/SendVoucherEmail`, reqData, { headers: this.headers }) + } + UpdateBooking(reqData){ + return this.http.post(`${environment.APIBaseUrl}/HotelBooking/UpdateBooking`, reqData, { headers: this.headers }) + }; + GethotelCityName(reqData){ + return this.http.post(`${environment.hotelApiBaseUrl}/hotel/hotelcitylist`, reqData, { headers: this.headers }) + }; + GetCancelBooking(reqData){ + return this.http.post(`${environment.hotelApiBaseUrl}/hotel/cancelfee`, reqData, { headers: this.headers }) + }; +} diff --git a/src/app/core/services/HotelServices/manage-hotel.service.ts b/src/app/core/services/HotelServices/manage-hotel.service.ts new file mode 100644 index 0000000..807d9aa --- /dev/null +++ b/src/app/core/services/HotelServices/manage-hotel.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ManageHotelService { + + Extranet_Hotel_Id; + Active_tab = 'OverView'; + constructor() { } +} diff --git a/src/app/core/services/PagesService/hotelService/AddRoomService/Add-Room.service.ts b/src/app/core/services/PagesService/hotelService/AddRoomService/Add-Room.service.ts new file mode 100644 index 0000000..cdac817 --- /dev/null +++ b/src/app/core/services/PagesService/hotelService/AddRoomService/Add-Room.service.ts @@ -0,0 +1,54 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { ContractRoom } from 'src/app/core/models/hotelService/AddRoom/Room.model'; +import { environment } from 'src/environments/environment'; +// import { CommonFunctions } from 'src/app/core/common/common-functions'; +// import { environment } from 'src/environments/environment'; + + + + +@Injectable({ + providedIn: 'root' +}) + +export class AddRoomService { + SaveRoom(dataPost: ContractRoom) { + throw new Error('Method not implemented.'); + } + constructor(private http: HttpClient) { } + getAllRoomCategory() { + return this.http.get(environment.APIBaseUrl + "/RoomCategoryName/GetAllRoomCategory") + }; + GetAllHotelAmenity() { + return this.http.get(environment.APIBaseUrl + "/HotelAmenity/GetAllHotelAmenity") + }; + GetAllRoomViewName() { + return this.http.get(environment.APIBaseUrl + "/RoomViewName/GetAllRoomViewName") + }; + GetAllRoomBedType() { + return this.http.get(environment.APIBaseUrl + "/BedTypeMaster/GetAllBedType") + }; + SaveRoomContract(roomDetails) { + return this.http.post(environment.APIBaseUrl + "/RoomContract/SaveContractRoom", roomDetails) + }; + UpdateRoomContract(roomDetails) { + return this.http.post(environment.APIBaseUrl + "/RoomContract/UpdateContractRoom", roomDetails) + }; + saveImage(file) { + return this.http.post(environment.APIBaseUrl + "/FileUpload/SaveFile", file) + }; + getlovtype() { + let formdata = { + "lov_types": [{ "lov_type": "MeasureUnit" }], + "lov_lang": "en" + } + return this.http.post(environment.APIBaseUrl + "/LovMaster/GetLov", formdata) + }; + GetRoomContractById(Id) { + return this.http.get(environment.APIBaseUrl + "/RoomContract/GetContractRoom/" + Id) + }; + + + +} \ No newline at end of file diff --git a/src/app/core/services/PagesService/hotelService/tab-content/tab-3/RoomContract.service.ts b/src/app/core/services/PagesService/hotelService/tab-content/tab-3/RoomContract.service.ts new file mode 100644 index 0000000..2866e16 --- /dev/null +++ b/src/app/core/services/PagesService/hotelService/tab-content/tab-3/RoomContract.service.ts @@ -0,0 +1,25 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; +// import { CommonFunctions } from 'src/app/core/common/common-functions'; +// import { environment } from 'src/environments/environment'; + + + + +@Injectable({ + providedIn: 'root' +}) + +export class RoomContractService { + constructor(private http: HttpClient) { } + + GetAllRoomContract() { + return this.http.get(environment.APIBaseUrl + "/RoomContract/GetAllContractRoom") + }; + + UpdateStatus(form) { + return this.http.post(environment.APIBaseUrl + "/RoomContract/UpdateStatus", form) + }; + +} \ No newline at end of file diff --git a/src/app/core/services/PagesService/hotelService/tab-content/tab-4/tab-4.service.ts b/src/app/core/services/PagesService/hotelService/tab-content/tab-4/tab-4.service.ts new file mode 100644 index 0000000..96a862e --- /dev/null +++ b/src/app/core/services/PagesService/hotelService/tab-content/tab-4/tab-4.service.ts @@ -0,0 +1,32 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; +// import { CommonFunctions } from 'src/app/core/common/common-functions'; +// import { environment } from 'src/environments/environment'; + + + + +@Injectable({ + providedIn: 'root' +}) + +export class SeasonSettingService { + constructor(private http: HttpClient) { } + GetAllSeason() { + return this.http.get(environment.APIBaseUrl + "/SeasonContract/GetAllSeason") + }; + UpdateStatus(formData) { + return this.http.post(environment.APIBaseUrl + "/SeasonContract/UpdateSeasonStatus", formData) + }; + SaveSeason(formData) { + return this.http.post(environment.APIBaseUrl + "/SeasonContract/SaveSeason", formData) + }; + UpdateSeason(formData) { + return this.http.post(environment.APIBaseUrl + "/SeasonContract/UpdateSeason", formData) + }; + GetContractSeasonById(id) { + return this.http.get(environment.APIBaseUrl + "/SeasonContract/GetContractSeasonById/"+ id) + }; + +} \ No newline at end of file diff --git a/src/app/core/services/active-sidebar.service.ts b/src/app/core/services/active-sidebar.service.ts new file mode 100644 index 0000000..6f27d9f --- /dev/null +++ b/src/app/core/services/active-sidebar.service.ts @@ -0,0 +1,46 @@ +import { BreakpointObserver, Breakpoints } from "@angular/cdk/layout"; +import { Injectable } from "@angular/core"; +import { Subject, takeUntil } from "rxjs"; + +@Injectable({ + providedIn: "root", +}) +export class ActiveSidebarService { + activeSide = "IsActive"; + MobileShow = true; + destroyed = new Subject(); + isTouchEvent!: boolean; + constructor( + breakpointObserver: BreakpointObserver, + ) { + breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]) + .pipe(takeUntil(this.destroyed)) + .subscribe((result) => { + if ( + result.breakpoints["(max-width: 599.98px)"] || + result.breakpoints["(min-width: 600px) and (max-width: 959.98px)"] + ) { + this.MobileShow = true; + } else { + this.MobileShow = false; + } + }); + } + SideBar(ele: string) { + // if (this.MobileShow) { + if (this.activeSide == ele) { + this.activeSide = ""; + //a.type == 'mouseenter' ? this.activeSide = "" : this.activeSide = "IsActive"; + } else { + this.activeSide = "IsActive"; + //a.type == 'mouseenter' ? this.activeSide = "IsActive" : this.activeSide = ""; + // } + } + } + //ActiveSideBar(ele) { + // this.activeSide = ""; + //} + //DisActiveSideBar(ele) { + // this.activeSide = "IsActive"; + //} +} diff --git a/src/app/core/services/api.service.ts b/src/app/core/services/api.service.ts new file mode 100644 index 0000000..ad12dcb --- /dev/null +++ b/src/app/core/services/api.service.ts @@ -0,0 +1,123 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { environment } from 'src/environments/environment'; + +@Injectable({ + providedIn: 'root' +}) + +export class API { + constructor(private http: HttpClient) { + } + private headers = { + 'Content-Type': 'application/json; charset=utf-8', + // 'LoggedInUser': sessionStorage.getItem('userId') + }; + // Extranet API Base Url + Post(url, obj) { + return this.http.post(environment.ExtranetAPIBaseUrl + url, obj, + { headers: this.headers } + ); + } + + Put(url, obj) { + return this.http.put(environment.ExtranetAPIBaseUrl + url, obj, + { headers: this.headers } + ); + } + + Delete(url) { + return this.http.delete(environment.ExtranetAPIBaseUrl + url, + { headers: this.headers } + ); + } + + Get(url) { + return this.http.get(environment.ExtranetAPIBaseUrl + url, + { headers: this.headers } + ); + } + // Admin API Base Url + AdminPost(url, obj) { + return this.http.post(environment.APIBaseUrl + url, obj, + { headers: this.headers } + ); + } + + AdminPut(url, obj) { + return this.http.put(environment.APIBaseUrl + url, obj, + { headers: this.headers } + ); + } + + AdminDelete(url) { + return this.http.delete(environment.APIBaseUrl + url, + { headers: this.headers } + ); + } + + AdminGet(url) { + return this.http.get(environment.APIBaseUrl + url, + { headers: this.headers } + ); + } + // admin api go + AdminGoPost(url, obj) { + return this.http.post(environment.AdminAPIGOBaseUrl + url, obj, + { headers: this.headers } + ); + } + + AdminGOPut(url, obj) { + return this.http.put(environment.AdminAPIGOBaseUrl + url, obj, + { headers: this.headers } + ); + } + + AdminGODelete(url) { + return this.http.delete(environment.AdminAPIGOBaseUrl + url, + { headers: this.headers } + ); + } + + AdminGOGet(url) { + return this.http.get(environment.AdminAPIGOBaseUrl + url, + { headers: this.headers } + ); + } + // + PostFile(url, obj) { + return this.http.post(environment.APIBaseUrl + url, obj,); + } + + PostFileExtranet(url, obj){ + return this.http.post(environment.ExtranetAPIBaseUrl + url, obj,); + } + + //Admin API GO + PostGo(url, obj, customHeaders = null) { + let postHeaders = JSON.parse(JSON.stringify(this.headers)) + if (customHeaders != null) { + postHeaders = { ...postHeaders, ...customHeaders } + } + return this.http.post(environment.APIBaseGoUrl + url, obj, + { headers: postHeaders } + ); + } + + GetGo(url) { + return this.http.get(environment.APIBaseGoUrl + url, + { headers: this.headers } + ); + } + + PostFileGo(url, obj) { + return this.http.post(environment.APIBaseGoUrl + url, obj,); + } + getAdjustedLocalTime(): number { + const calculatedTime = sessionStorage.getItem('UGT') || '0'; + const localTime = new Date().getTime(); + return localTime + parseInt(calculatedTime); + } +} + diff --git a/src/app/core/services/breakpoints.services.ts b/src/app/core/services/breakpoints.services.ts new file mode 100644 index 0000000..b52763d --- /dev/null +++ b/src/app/core/services/breakpoints.services.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; + +@Injectable({ + providedIn: 'root', +}) +export class BreakpointsService { + public IsMobile = new BehaviorSubject(false); + destroyed = new Subject(); + ngOnDestroy() { + this.destroyed.next(); + this.destroyed.complete(); + } + constructor(private breakpointObserver: BreakpointObserver) { + this.checkTest(); + } + + checkTest() { + this.breakpointObserver + .observe([Breakpoints.XSmall, Breakpoints.Small]) + .pipe(takeUntil(this.destroyed)) + .subscribe((result) => { + if ( + result.breakpoints['(max-width: 599.98px)'] || + result.breakpoints['(min-width: 600px) and (max-width: 959.98px)'] + ) { + this.IsMobile.next(true); + } else { + this.IsMobile.next(false); + } + }); + } + + checkMob() { + return this.IsMobile.getValue(); + } +} diff --git a/src/app/core/services/common.service.ts b/src/app/core/services/common.service.ts new file mode 100644 index 0000000..6af6201 --- /dev/null +++ b/src/app/core/services/common.service.ts @@ -0,0 +1,58 @@ +import { Injectable } from "@angular/core"; +import * as CryptoJS from 'crypto-js'; + +export class CommonService{ + static yek = "$uPer@dm1n~dI@z7"; + + private static encryptText(plainText) { + var key = CryptoJS.enc.Utf8.parse(this.yek); + var iv = CryptoJS.enc.Utf8.parse(this.yek); + + var encryptedText = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(plainText), key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }).toString(); + return encryptedText; + } + + public static decryptText(cipherText) { + var key = CryptoJS.enc.Utf8.parse(this.yek); + var iv = CryptoJS.enc.Utf8.parse(this.yek); + + var decryptedText = CryptoJS.AES.decrypt(cipherText, key, + { + keySize: 128 / 8, + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8); + return decryptedText; + } + public static setSessionStorage(key: string, value) { + sessionStorage.setItem(key, this.encryptText(value)); + } + + public static getSessionStoage(key: string) { + var value = sessionStorage.getItem(key); + if (value) { + return this.decryptText(value); + } else return null; + } + public static resetLocalStoage(key: string) { + localStorage.removeItem(key); + } + public static setLocalStoage(key: string, value) { + value = JSON.stringify(value); + localStorage.setItem(key, this.encryptText(value)); + } + + public static getLocalStoage(key: string) { + var value = localStorage.getItem(key); + if (value) { + return JSON.parse(this.decryptText(value)); + } + } +} \ No newline at end of file diff --git a/src/app/core/services/event-utils.ts b/src/app/core/services/event-utils.ts new file mode 100644 index 0000000..024b115 --- /dev/null +++ b/src/app/core/services/event-utils.ts @@ -0,0 +1,27 @@ + +let eventGuid = 0; +const TODAY_STR = new Date().toISOString().replace(/T.*$/, ''); // YYYY-MM-DD of today + +export const INITIAL_EVENTS = [ + { + id: createEventId(), + title: 'All-day event', + start: TODAY_STR + }, + { + id: createEventId(), + title: 'Timed event', + start: TODAY_STR + 'T00:00:00', + end: TODAY_STR + 'T03:00:00' + }, + { + id: createEventId(), + title: 'Timed event', + start: TODAY_STR + 'T12:00:00', + end: TODAY_STR + 'T15:00:00' + } +]; + +export function createEventId() { + return String(eventGuid++); +} diff --git a/src/app/core/services/events.calender.service.ts b/src/app/core/services/events.calender.service.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/app/core/services/flight-contract.service.ts/flight-contract.service.ts b/src/app/core/services/flight-contract.service.ts/flight-contract.service.ts new file mode 100644 index 0000000..55a9fbb --- /dev/null +++ b/src/app/core/services/flight-contract.service.ts/flight-contract.service.ts @@ -0,0 +1,133 @@ +import { MessageService } from "primeng/api"; +import { Injectable } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import * as moment from "moment"; +import { FileUpload } from "primeng/fileupload"; +import jsPDF from "jspdf"; +import * as FileSaver from "file-saver"; +import autoTable from 'jspdf-autotable'; +import { API } from "../api.service"; +import { ValidationService } from "../../common/validation.service"; + +@Injectable() +export class FlightContractService { + constructor( + public ApiServ: API, + public validationService: ValidationService, + public titleService: Title + ) { + } + + + ddLoader = { + AirLine: false, + Currency: false, + origin: false, + destination: false, + ToAirport: false, + FormAirport: false, + AirCraft: false, + } + timer; + AirlineList = []; + AirportList = []; + AllAirCraftList = []; + getAirLineBySearch(val) { + if (val.length >= 2) { + this.ddLoader.AirLine = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + let request = { + "langcode": "en", + "query": val + } + this.ApiServ.AdminGoPost(`/MasterSearch/GetAllAirLine`, request).subscribe(res => { + if (res) { + this.AirlineList = res?.Result; + this.ddLoader.AirLine = false; + } + }); + }, 500); + }; + if (!val) { + this.AirlineList = []; + } + }; + + GetAirportList(val, name) { + if (val.length >= 2) { + this.ddLoader[name] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.AdminGOGet(`/Airport/GetList/en/` + val).subscribe(res => { + if (res) { + this.AirportList = res; + this.ddLoader[name] = false; + } + }); + }, 500); + }; + if (!val) { + this.AirlineList = []; + } + }; + getAircraftList(val) { + let repObj = { + aircraft_name: val + }; + if (val.length >= 3) { + this.ddLoader.AirCraft = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.Post(`/MasterSearch/GetAllAircraftType`, repObj).subscribe(res => { + if (res) { + this.AllAirCraftList = res.data; + this.ddLoader.AirCraft = false; + } + }); + }, 500); + } + }; + GetAirportsByAirportCode(data) { + let obj = { + airport_code: data + } + this.ApiServ.AdminGoPost('/Airport/GetAirportsByAirportCode', obj).subscribe(res => { + if (res) { + if (res.Result && res.Result.length > 0) { + this.AirportList = res.Result; + this.AirportList = this.AirportList.map(e => ({ 'ac': e.airport_code, 'ct': e.city_name })); + } + setTimeout(() => { + this.AirportList = []; + }, 500); + } + }); + }; + GetAirlineByAirlineCode(data) { + let obj = { + airline_code: data + } + this.ApiServ.AdminGoPost('/MasterSearch/GetAirlineByAirlineCode', obj).subscribe(res => { + if (res) { + this.AirlineList = res.Result; + setTimeout(() => { + this.AirlineList = []; + }, 500); + } + }); + }; + GetAircraftTypeById(data) { + let obj = { + aircraft_type_id: data + } + this.ApiServ.Post('/MasterSearch/GetAircraftTypeById', obj).subscribe(res => { + if (res) { + this.AllAirCraftList = res.data; + setTimeout(() => { + this.AllAirCraftList = []; + }, 500); + } + }); + }; +} \ No newline at end of file diff --git a/src/app/core/services/node.service.ts b/src/app/core/services/node.service.ts new file mode 100644 index 0000000..9d59bbc --- /dev/null +++ b/src/app/core/services/node.service.ts @@ -0,0 +1,21 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; + +import { TreeNode } from 'primeng/api'; + +@Injectable() +export class NodeService { + constructor(private http: HttpClient) { } + + getFiles() { + return this.http.get('assets/files.json') + .toPromise() + .then(res => res.data); + } + + getLazyFiles() { + return this.http.get('assets/files-lazy.json') + .toPromise() + .then(res => res.data); + } +} \ No newline at end of file diff --git a/src/app/core/services/nodeservice.ts b/src/app/core/services/nodeservice.ts new file mode 100644 index 0000000..1a4211c --- /dev/null +++ b/src/app/core/services/nodeservice.ts @@ -0,0 +1,787 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class NodeService { + [x: string]: any; + getTreeNodesData() { + return [ + { + key: '0', + label: 'Documents', + data: 'Documents Folder', + icon: 'pi pi-fw pi-inbox', + children: [ + { + key: '0-0', + label: 'Work', + data: 'Work Folder', + icon: 'pi pi-fw pi-cog', + children: [ + { key: '0-0-0', label: 'Expenses.doc', icon: 'pi pi-fw pi-file', data: 'Expenses Document' }, + { key: '0-0-1', label: 'Resume.doc', icon: 'pi pi-fw pi-file', data: 'Resume Document' } + ] + }, + { + key: '0-1', + label: 'Home', + data: 'Home Folder', + icon: 'pi pi-fw pi-home', + children: [{ key: '0-1-0', label: 'Invoices.txt', icon: 'pi pi-fw pi-file', data: 'Invoices for this month' }] + } + ] + }, + { + key: '1', + label: 'Events', + data: 'Events Folder', + icon: 'pi pi-fw pi-calendar', + children: [ + { key: '1-0', label: 'Meeting', icon: 'pi pi-fw pi-calendar-plus', data: 'Meeting' }, + { key: '1-1', label: 'Product Launch', icon: 'pi pi-fw pi-calendar-plus', data: 'Product Launch' }, + { key: '1-2', label: 'Report Review', icon: 'pi pi-fw pi-calendar-plus', data: 'Report Review' } + ] + }, + { + key: '2', + label: 'Movies', + data: 'Movies Folder', + icon: 'pi pi-fw pi-star-fill', + children: [ + { + key: '2-0', + icon: 'pi pi-fw pi-star-fill', + label: 'Al Pacino', + data: 'Pacino Movies', + children: [ + { key: '2-0-0', label: 'Scarface', icon: 'pi pi-fw pi-video', data: 'Scarface Movie' }, + { key: '2-0-1', label: 'Serpico', icon: 'pi pi-fw pi-video', data: 'Serpico Movie' } + ] + }, + { + key: '2-1', + label: 'Robert De Niro', + icon: 'pi pi-fw pi-star-fill', + data: 'De Niro Movies', + children: [ + { key: '2-1-0', label: 'Goodfellas', icon: 'pi pi-fw pi-video', data: 'Goodfellas Movie' }, + { key: '2-1-1', label: 'Untouchables', icon: 'pi pi-fw pi-video', data: 'Untouchables Movie' } + ] + } + ] + } + ]; + } + + getTreeTableNodesData() { + return [ + { + key: '0', + data: { + name: 'Applications', + view: '100kb', + add: 'Folder' + }, + children: [ + { + key: '0-0', + data: { + name: 'React', + view: '25kb', + add: 'Folder' + }, + children: [ + { + key: '0-0-0', + data: { + name: 'react.app', + view: '10kb', + add: 'Application' + } + }, + { + key: '0-0-1', + data: { + name: 'native.app', + view: '10kb', + add: 'Application' + } + }, + { + key: '0-0-2', + data: { + name: 'mobile.app', + view: '5kb', + add: 'Application' + } + } + ] + }, + { + key: '0-1', + data: { + name: 'editor.app', + view: '25kb', + add: 'Application' + } + }, + { + key: '0-2', + data: { + name: 'settings.app', + view: '50kb', + add: 'Application' + } + } + ] + }, + { + key: '1', + data: { + name: 'Cloud', + view: '20kb', + add: 'Folder' + }, + children: [ + { + key: '1-0', + data: { + name: 'backup-1.zip', + view: '10kb', + add: 'Zip' + } + }, + { + key: '1-1', + data: { + name: 'backup-2.zip', + view: '10kb', + add: 'Zip' + } + } + ] + }, + { + key: '2', + data: { + name: 'Desktop', + view: '150kb', + add: 'Folder' + }, + children: [ + { + key: '2-0', + data: { + name: 'note-meeting.txt', + view: '50kb', + add: 'Text' + } + }, + { + key: '2-1', + data: { + name: 'note-todo.txt', + view: '100kb', + add: 'Text' + } + } + ] + }, + { + key: '3', + data: { + name: 'Documents', + view: '75kb', + add: 'Folder' + }, + children: [ + { + key: '3-0', + data: { + name: 'Work', + view: '55kb', + add: 'Folder' + }, + children: [ + { + key: '3-0-0', + data: { + name: 'Expenses.doc', + view: '30kb', + add: 'Document' + } + }, + { + key: '3-0-1', + data: { + name: 'Resume.doc', + view: '25kb', + add: 'Resume' + } + } + ] + }, + { + key: '3-1', + data: { + name: 'Home', + view: '20kb', + add: 'Folder' + }, + children: [ + { + key: '3-1-0', + data: { + name: 'Invoices', + view: '20kb', + add: 'Text' + } + } + ] + } + ] + }, + { + key: '4', + data: { + name: 'Downloads', + view: '25kb', + add: 'Folder' + }, + children: [ + { + key: '4-0', + data: { + name: 'Spanish', + view: '10kb', + add: 'Folder' + }, + children: [ + { + key: '4-0-0', + data: { + name: 'tutorial-a1.txt', + view: '5kb', + add: 'Text' + } + }, + { + key: '4-0-1', + data: { + name: 'tutorial-a2.txt', + view: '5kb', + add: 'Text' + } + } + ] + }, + { + key: '4-1', + data: { + name: 'Travel', + view: '15kb', + add: 'Text' + }, + children: [ + { + key: '4-1-0', + data: { + name: 'Hotel.pdf', + view: '10kb', + add: 'PDF' + } + }, + { + key: '4-1-1', + data: { + name: 'Flight.pdf', + view: '5kb', + add: 'PDF' + } + } + ] + } + ] + }, + { + key: '5', + data: { + name: 'Main', + view: '50kb', + add: 'Folder' + }, + children: [ + { + key: '5-0', + data: { + name: 'bin', + view: '50kb', + add: 'Link' + } + }, + { + key: '5-1', + data: { + name: 'etc', + view: '100kb', + add: 'Link' + } + }, + { + key: '5-2', + data: { + name: 'var', + view: '100kb', + add: 'Link' + } + } + ] + }, + { + key: '6', + data: { + name: 'Other', + view: '5kb', + add: 'Folder' + }, + children: [ + { + key: '6-0', + data: { + name: 'todo.txt', + view: '3kb', + add: 'Text' + } + }, + { + key: '6-1', + data: { + name: 'logo.png', + view: '2kb', + add: 'Picture' + } + } + ] + }, + { + key: '7', + data: { + name: 'Pictures', + view: '150kb', + add: 'Folder' + }, + children: [ + { + key: '7-0', + data: { + name: 'barcelona.jpg', + view: '90kb', + add: 'Picture' + } + }, + { + key: '7-1', + data: { + name: 'primeng.png', + view: '30kb', + add: 'Picture' + } + }, + { + key: '7-2', + data: { + name: 'prime.jpg', + view: '30kb', + add: 'Picture' + } + } + ] + }, + { + key: '8', + data: { + name: 'Videos', + view: '1500kb', + add: 'Folder' + }, + children: [ + { + key: '8-0', + data: { + name: 'primefaces.mkv', + view: '1000kb', + add: 'Video' + } + }, + { + key: '8-1', + data: { + name: 'intro.avi', + view: '500kb', + add: 'Video' + } + } + ] + } + ]; + } + + getLazyNodesData() { + return [ + { + "label": "Lazy Node 0", + "data": "Node 0", + "expandedIcon": "pi pi-folder-open", + "collapsedIcon": "pi pi-folder", + "leaf": false + }, + { + "label": "Lazy Node 1", + "data": "Node 1", + "expandedIcon": "pi pi-folder-open", + "collapsedIcon": "pi pi-folder", + "leaf": false + }, + { + "label": "Lazy Node 1", + "data": "Node 2", + "expandedIcon": "pi pi-folder-open", + "collapsedIcon": "pi pi-folder", + "leaf": false + } + ] + } + + getFileSystemNodesData() { + return [ + { + "data":{ + "name":"Applications", + "view":"200mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"Angular", + "view":"25mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"angular.app", + "view":"10mb", + "add":"Application" + } + }, + { + "data":{ + "name":"cli.app", + "view":"10mb", + "add":"Application" + } + }, + { + "data":{ + "name":"mobile.app", + "view":"5mb", + "add":"Application" + } + } + ] + }, + { + "data":{ + "name":"editor.app", + "view":"25mb", + "add":"Application" + } + }, + { + "data":{ + "name":"settings.app", + "view":"50mb", + "add":"Application" + } + } + ] + }, + { + "data":{ + "name":"Cloud", + "view":"20mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"backup-1.zip", + "view":"10mb", + "add":"Zip" + } + }, + { + "data":{ + "name":"backup-2.zip", + "view":"10mb", + "add":"Zip" + } + } + ] + }, + { + "data": { + "name":"Desktop", + "view":"150kb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"note-meeting.txt", + "view":"50kb", + "add":"Text" + } + }, + { + "data":{ + "name":"note-todo.txt", + "view":"100kb", + "add":"Text" + } + } + ] + }, + { + "data":{ + "name":"Documents", + "view":"75kb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"Work", + "view":"55kb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"Expenses.doc", + "view":"30kb", + "add":"Document" + } + }, + { + "data":{ + "name":"Resume.doc", + "view":"25kb", + "add":"Resume" + } + } + ] + }, + { + "data":{ + "name":"Home", + "view":"20kb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"Invoices", + "view":"20kb", + "add":"Text" + } + } + ] + } + ] + }, + { + "data": { + "name":"Downloads", + "view":"25mb", + "add":"Folder" + }, + "children":[ + { + "data": { + "name":"Spanish", + "view":"10mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"tutorial-a1.txt", + "view":"5mb", + "add":"Text" + } + }, + { + "data":{ + "name":"tutorial-a2.txt", + "view":"5mb", + "add":"Text" + } + } + ] + }, + { + "data":{ + "name":"Travel", + "view":"15mb", + "add":"Text" + }, + "children":[ + { + "data":{ + "name":"Hotel.pdf", + "view":"10mb", + "add":"PDF" + } + }, + { + "data":{ + "name":"Flight.pdf", + "view":"5mb", + "add":"PDF" + } + } + ] + } + ] + }, + { + "data": { + "name":"Main", + "view":"50mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"bin", + "view":"50kb", + "add":"Link" + } + }, + { + "data":{ + "name":"etc", + "view":"100kb", + "add":"Link" + } + }, + { + "data":{ + "name":"var", + "view":"100kb", + "add":"Link" + } + } + ] + }, + { + "data":{ + "name":"Other", + "view":"5mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"todo.txt", + "view":"3mb", + "add":"Text" + } + }, + { + "data":{ + "name":"logo.png", + "view":"2mb", + "add":"Picture" + } + } + ] + }, + { + "data":{ + "name":"Pictures", + "view":"150kb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"barcelona.jpg", + "view":"90kb", + "add":"Picture" + } + }, + { + "data":{ + "name":"primeng.png", + "view":"30kb", + "add":"Picture" + } + }, + { + "data":{ + "name":"prime.jpg", + "view":"30kb", + "add":"Picture" + } + } + ] + }, + { + "data":{ + "name":"Videos", + "view":"1500mb", + "add":"Folder" + }, + "children":[ + { + "data":{ + "name":"primefaces.mkv", + "view":"1000mb", + "add":"Video" + } + }, + { + "data":{ + "name":"intro.avi", + "view":"500mb", + "add":"Video" + } + } + ] + } + ] + } + + getTreeTableNodes() { + return Promise.resolve(this.getTreeTableNodesData()); + } + + getTreeNodes() { + return Promise.resolve(this.getTreeNodesData()); + } + + getFiles() { + return Promise.resolve(this.getTreeNodesData()); + } + + getLazyFiles() { + return Promise.resolve(this.getLazyNodesData()); + } + + getFilesystem() { + return Promise.resolve(this.getFileSystemNodesData()); + } + +}; \ No newline at end of file diff --git a/src/app/core/services/product.service.ts b/src/app/core/services/product.service.ts new file mode 100644 index 0000000..95c7aac --- /dev/null +++ b/src/app/core/services/product.service.ts @@ -0,0 +1,113 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; + +import { Product } from './product'; + +@Injectable() +export class ProductService { + + status: string[] = ['OUTOFSTOCK', 'INSTOCK', 'LOWSTOCK']; + + productNames: string[] = [ + "Bamboo Watch", + "Black Watch", + "Blue Band", + "Blue T-Shirt", + "Bracelet", + "Brown Purse", + "Chakra Bracelet", + "Galaxy Earrings", + "Game Controller", + "Gaming Set", + "Gold Phone Case", + "Green Earbuds", + "Green T-Shirt", + "Grey T-Shirt", + "Headphones", + "Light Green T-Shirt", + "Lime Band", + "Mini Speakers", + "Painted Phone Case", + "Pink Band", + "Pink Purse", + "Purple Band", + "Purple Gemstone Necklace", + "Purple T-Shirt", + "Shoes", + "Sneakers", + "Teal T-Shirt", + "Yellow Earbuds", + "Yoga Mat", + "Yoga Set", + ]; + + constructor(private http: HttpClient) { } + + getProductsSmall() { + return this.http.get('assets\products.json') + .toPromise() + .then(res => res.data) + .then(data => { return data; }); + } + + getProducts() { + return this.http.get('assets/products.json') + .toPromise() + .then(res => res.data) + .then(data => { return data; }); + } + + getProductsWithOrdersSmall() { + return this.http.get('assets/products-orders-small.json') + .toPromise() + .then(res => res.data) + .then(data => { return data; }); + } + + generatePrduct(): Product { + const product: Product = { + id: this.generateId(), + name: this.generateName(), + description: "Product Description", + price: this.generatePrice(), + quantity: this.generateQuantity(), + category: "Product Category", + inventoryStatus: this.generateStatus(), + rating: this.generateRating() + }; + + // product.image = product.name.toLocaleLowerCase().split(/[ ,]+/).join('-')+".jpg";; + return product; + } + + generateId() { + let text = ""; + let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < 5; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + + return text; + } + + generateName() { + return this.productNames[Math.floor(Math.random() * Math.floor(30))]; + } + + generatePrice() { + return Math.floor(Math.random() * Math.floor(299)+1); + } + + generateQuantity() { + return Math.floor(Math.random() * Math.floor(75)+1); + } + + generateStatus() { + return this.status[Math.floor(Math.random() * Math.floor(3))]; + } + + generateRating() { + return Math.floor(Math.random() * Math.floor(5)+1); + } +} \ No newline at end of file diff --git a/src/app/core/services/product.ts b/src/app/core/services/product.ts new file mode 100644 index 0000000..9d7b4e8 --- /dev/null +++ b/src/app/core/services/product.ts @@ -0,0 +1,12 @@ +export interface Product { + id?:string; + code?:string; + name?:string; + description?:string; + price?:number; + quantity?:number; + inventoryStatus?:string; + category?:string; + image?:string; + rating?:number; +} \ No newline at end of file diff --git a/src/app/core/services/sso.service.ts b/src/app/core/services/sso.service.ts new file mode 100644 index 0000000..28167f9 --- /dev/null +++ b/src/app/core/services/sso.service.ts @@ -0,0 +1,109 @@ +import { HttpClient, HttpHeaders } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Router } from "@angular/router"; +import { environment } from "src/environments/environment"; +import { CommonService } from "./common.service"; +import { of } from "rxjs"; +import { LoginModel, SSOLoginModel } from "../models/common-model/Sign-in.model"; +import { API } from "./api.service"; +import { securityFunctions } from "../common/security"; +import { CommonFunctionService } from "../common/common-function.service"; +import * as moment from "moment"; + +@Injectable() +export class SSOService { + sso: SSOLoginModel = new SSOLoginModel(); + constructor(private http: HttpClient, private router: Router, private apiServ: API, private commonService: CommonFunctionService) { } + validateSSOLogin(key, loginUserId?) { + sessionStorage.removeItem('LoginUserData'); + this.http.get("https://pro.ip-api.com/json/?fields=query,countryCode,lat,lon,city,proxy&&key=JZDsrdeBzIM0yyN").subscribe(data => { + if (data) { + let obj = { + city: data['city'], + countryCode: data['countryCode'], + lat: data['lat'], + lon: data['lon'], + proxy: data['proxy'], + iP: data['query'], + }; + sessionStorage.setItem('IP', JSON.stringify(obj)); + let loginModel = new LoginModel(); + if (key) { + let req_obj = { + key: encodeURIComponent(key), + city: obj.city, + countryCode: obj.countryCode, + lat: obj.lat, + lon: obj.lon, + proxy: obj.proxy, + iP: obj.iP, + }; + this.apiServ.AdminPost('/KeyGenerate/VendorSSOKey', req_obj).subscribe({ + next: res => { + if (res && res.resp) { + let data = null; + if (loginUserId) { + if (loginUserId.includes(" ")) { + data = loginUserId.replace(/ /g, "+"); + } else { + data = loginUserId; + } + } + let loginId = loginUserId ? securityFunctions.decryptText(data) : null; + // set before jwt token so other api work proper + sessionStorage.setItem('JwtToken', res.respObj.JwtToken); + sessionStorage.setItem('RefreshToken', res.respObj.RefreshToken); + sessionStorage.setItem('JwtTokenExpiry', res.respObj.JwtTokenExpiry); + securityFunctions.setSessionStorage('LoginUserData', JSON.stringify(res.respObj.userLogin)); + let date = new Date(moment(res.respObj.userLogin.last_login).format("YYYY MM DD hh:mm:ss") + " UTC"); + let lastLogin = moment(date.toString()).format("hh:mm:ss, DD MMM YYYY"); + sessionStorage.setItem('lastLogin', lastLogin); + sessionStorage.setItem('userName', res.respObj.userLogin.first_name); + this.commonService.FetchExtranetVendorMaster(res.respObj.userLogin.extranet_vendor_id, false).subscribe(data => { + if (data) { + securityFunctions.setSessionStorage('VData', JSON.stringify(data.Result[0])); + } + }); + this.router.navigate(['/']) + this.commonService.StartTimer(); + } else { + this.router.navigate(['/Auth/Login']); + } + }, + error: err => { + this.router.navigate(['/Auth/Login']); + } + }); + } else { + this.router.navigate(['/Auth/Login']); + } + } + }); + + } + + // GetUserdata(userid) { + // if (userid) { + // return this.http.get(environment.adminAPIUrl + "/UserAccount/GetUserDetail/" + userid) + // } else { + // return of('continue'); + // } + // } + UserIpDetails; + GetIpAddress() { + this.http.get("https://pro.ip-api.com/json/?fields=query,countryCode,lat,lon,city,proxy&&key=JZDsrdeBzIM0yyN").subscribe(res => { + if (res) { + this.UserIpDetails = res; + let obj = { + city: res['city'], + countryCode: res['countryCode'], + lat: res['lat'], + lon: res['lon'], + proxy: res['proxy'], + iP: res['query'], + } + sessionStorage.setItem('IP', JSON.stringify(obj)); + } + }) + }; +} \ No newline at end of file diff --git a/src/app/core/shared/intercept-loader/intercept-loader.component.html b/src/app/core/shared/intercept-loader/intercept-loader.component.html new file mode 100644 index 0000000..e0894e0 --- /dev/null +++ b/src/app/core/shared/intercept-loader/intercept-loader.component.html @@ -0,0 +1,14 @@ +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/core/shared/intercept-loader/intercept-loader.component.ts b/src/app/core/shared/intercept-loader/intercept-loader.component.ts new file mode 100644 index 0000000..111ec7e --- /dev/null +++ b/src/app/core/shared/intercept-loader/intercept-loader.component.ts @@ -0,0 +1,23 @@ +import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { LoaderService } from 'src/app/core/common/loader.service'; + +@Component({ + selector: 'app-loader', + templateUrl: './intercept-loader.component.html', +}) +export class LoaderComponent implements OnInit { + + loading: boolean; + + constructor(private loaderService: LoaderService, private cd: ChangeDetectorRef) { + + + } + + ngOnInit() { + this.loaderService.isLoading.subscribe((v) => { + this.loading = v; + this.cd.detectChanges(); + }); + } +} diff --git a/src/app/core/shared/shared.module.ts b/src/app/core/shared/shared.module.ts new file mode 100644 index 0000000..fcf4ed7 --- /dev/null +++ b/src/app/core/shared/shared.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + + + +@NgModule({ + declarations: [ + ], + imports: [ + CommonModule + ] +}) +export class SharedModule { } diff --git a/src/app/layouts/base/base.component.html b/src/app/layouts/base/base.component.html new file mode 100644 index 0000000..7cdf612 --- /dev/null +++ b/src/app/layouts/base/base.component.html @@ -0,0 +1,19 @@ +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/app/layouts/base/base.component.ts b/src/app/layouts/base/base.component.ts new file mode 100644 index 0000000..fd657b3 --- /dev/null +++ b/src/app/layouts/base/base.component.ts @@ -0,0 +1,34 @@ +import { Component, ElementRef, OnDestroy, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; +import { ActiveSidebarService } from 'src/app/core/services/active-sidebar.service'; + +@Component({ + templateUrl: './base.component.html', + selector: 'app-base', +}) +export class BaseComponent { + constructor(public ChcekSidebar: ActiveSidebarService) {} + + @ViewChild('headerElement') headerElement!: ElementRef; + headerHeight: number = 0; + resizeObserver!: ResizeObserver; + ngAfterViewInit() { + this.resizeObserver = new ResizeObserver(entries => { + for (let entry of entries) { + if (entry.target === this.headerElement.nativeElement) { + this.headerHeight = entry.contentRect.height; + } + } + }); + + if (this.headerElement && this.headerElement.nativeElement) { + this.resizeObserver.observe(this.headerElement.nativeElement); + } + } + + ngOnDestroy() { + if (this.resizeObserver && this.headerElement && this.headerElement.nativeElement) { + this.resizeObserver.unobserve(this.headerElement.nativeElement); + } + } +} diff --git a/src/app/layouts/intercept-loader/loader/loader.component.html b/src/app/layouts/intercept-loader/loader/loader.component.html new file mode 100644 index 0000000..43df8df --- /dev/null +++ b/src/app/layouts/intercept-loader/loader/loader.component.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/src/app/layouts/intercept-loader/loader/loader.component.ts b/src/app/layouts/intercept-loader/loader/loader.component.ts new file mode 100644 index 0000000..7cb7b95 --- /dev/null +++ b/src/app/layouts/intercept-loader/loader/loader.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { LoaderService } from 'src/app/core/common/loader.service'; + +@Component({ + selector: 'app-loader', + templateUrl: './loader.component.html', +}) +export class LoaderComponent implements OnInit { + + loading: boolean; + + constructor(private loaderService: LoaderService, private cd: ChangeDetectorRef) { + + + } + ngOnInit() { + this.loaderService.isLoading.subscribe((v) => { + this.loading = v; + this.cd.detectChanges(); + }); + } +} diff --git a/src/app/layouts/pages-routing.module.ts b/src/app/layouts/pages-routing.module.ts new file mode 100644 index 0000000..ebb0cf4 --- /dev/null +++ b/src/app/layouts/pages-routing.module.ts @@ -0,0 +1,68 @@ +// Angular +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +// Components +import { AuthGuard } from '../core/guard/auth.guard'; +import { BaseComponent } from './base/base.component'; +import { unauthorizedComponent } from './unauthorized/unauthorized.component'; +// Auth + +const routes: Routes = [ + { + path: '', + canActivate: [AuthGuard], + component: BaseComponent, + children: [ + { + path: "Unauthorized", + component: unauthorizedComponent, + }, + { + path: 'BookingManagement', + loadChildren: () => + import('../modules/booking-management/booking-management.module').then( + (m) => m.BookingManagementModule + ), + }, + { + path: 'Services', + loadChildren: () => + import('../modules/services/services.module').then((m) => m.ServicesModule), + }, + { + path: 'UserConfiguration', + loadChildren: () => + import('../modules/user-configuration/user-configuration.module').then((m) => m.UserConfigurationModule), + }, + { + path: 'ActivityConfiguration', + loadChildren: () => + import('../modules/services/activity-config/activity-config.module').then((m) => m.ActivityConfigModule), + }, + // { + // path: 'Error/403', + // data: { + // type: 'error-v6', + // code: 403, + // title: '403... Access forbidden', + // desc: "Looks like you don't have permission to access for requested page.
    Please, contact administrator", + // }, + // }, + // { + // path: 'Error/404', + // data: { + // type: 'error-v4', + // }, + // }, + // { path: 'Error/:type' }, + { path: '', redirectTo: '', pathMatch: 'full' }, + { path: '**', redirectTo: 'Error/404', pathMatch: 'full' }, + ], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class PagesRoutingModule { } diff --git a/src/app/layouts/theme.module.ts b/src/app/layouts/theme.module.ts new file mode 100644 index 0000000..5b6715e --- /dev/null +++ b/src/app/layouts/theme.module.ts @@ -0,0 +1,51 @@ + +// Angular +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +// NgBootstrap +// Translation +import { BaseComponent } from './base/base.component'; +import { PagesRoutingModule } from './pages-routing.module'; +import { FooterComponent } from '../modules/common/footer/footer.component'; +import { HeaderComponent } from '../modules/common/header/header.component'; +//Angular Material +import { MatExpansionModule } from '@angular/material/expansion'; +import { AuthGuard } from '../core/guard/auth.guard'; +import { SideBarComponent } from '../modules/common/sidebar/sidebar.component'; +import { PanelMenuModule } from 'primeng/panelmenu'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { unauthorizedComponent } from './unauthorized/unauthorized.component'; +import { CustomSidebarComponent } from '../modules/common/custom-sidebar/custom-sidebar.component'; +import { CustomSidebarItemComponent } from '../modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component'; + +@NgModule({ + declarations: [ + BaseComponent, + FooterComponent, + HeaderComponent, + SideBarComponent, + unauthorizedComponent, + CustomSidebarComponent, + CustomSidebarItemComponent, + ], + imports: [ + CommonModule, + RouterModule, + PagesRoutingModule, + + // material module + MatExpansionModule, + MatButtonModule, + MatMenuModule, + // material module + + // prime ng + PanelMenuModule + ], + exports: [], + providers: [], +}) +export class ThemeModule { } + diff --git a/src/app/layouts/unauthorized/unauthorized.component.html b/src/app/layouts/unauthorized/unauthorized.component.html new file mode 100644 index 0000000..0cbf86f --- /dev/null +++ b/src/app/layouts/unauthorized/unauthorized.component.html @@ -0,0 +1,59 @@ +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    4Ø3

    +

    Sorry! You are not authorized to view this page.

    +
    Please contact your administrator
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/layouts/unauthorized/unauthorized.component.ts b/src/app/layouts/unauthorized/unauthorized.component.ts new file mode 100644 index 0000000..60736ab --- /dev/null +++ b/src/app/layouts/unauthorized/unauthorized.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; + +@Component({ + selector: 'app-Unauthorized', + templateUrl: './unauthorized.component.html', +}) +export class unauthorizedComponent implements OnInit { + + constructor(private _commonSer: CommonFunctionService) { } + + ngOnInit(): void { + this._commonSer.CheckTokenExpireTime(false) + } + +} diff --git a/src/app/modules/auth/auth.component.html b/src/app/modules/auth/auth.component.html new file mode 100644 index 0000000..e69de29 diff --git a/src/app/modules/auth/auth.component.ts b/src/app/modules/auth/auth.component.ts new file mode 100644 index 0000000..002b40b --- /dev/null +++ b/src/app/modules/auth/auth.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-auth', + templateUrl: './auth.component.html', +}) +export class AuthComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/auth/auth.module.ts b/src/app/modules/auth/auth.module.ts new file mode 100644 index 0000000..ce32f06 --- /dev/null +++ b/src/app/modules/auth/auth.module.ts @@ -0,0 +1,63 @@ +import { CommonModule } from '@angular/common'; +import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { RouterModule, Routes } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { PasswordModule } from 'primeng/password'; +import { ToastModule } from 'primeng/toast'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { LoginComponent } from './login/login.component'; +import { InterceptLoader } from 'src/app/core/common/intercept-loader.service'; +import { ForgetPasswordComponent } from './forget-password/forget-password.component'; +import { VerifyEmailComponent } from './verify-email/verify-email.component'; +import { NgOtpInputModule } from 'ng-otp-input'; +import { SingleSignOnComponent } from './single-sign-on/single-sign-on.component'; +import { SSOService } from 'src/app/core/services/sso.service'; +import { ButtonModule } from 'primeng/button'; + +const routes: Routes = [ + { + path: 'Login', + component: LoginComponent + }, + { + path: 'Forget-Password', + component: ForgetPasswordComponent + }, + { + path: 'verify-email', + component: VerifyEmailComponent + }, + { + path: 'SSOLogin', + component: SingleSignOnComponent + }, + { path: '', redirectTo: 'Login', pathMatch: 'full' }, +]; + +@NgModule({ + declarations: [ + LoginComponent, + ForgetPasswordComponent, + VerifyEmailComponent, + SingleSignOnComponent, + ], + imports: [ + ButtonModule, + ToastModule, + CommonModule, + PasswordModule, + NgOtpInputModule, + HttpClientModule, + FormsModule, + ReactiveFormsModule, + MatCheckboxModule, + RouterModule.forChild(routes), + ], + providers: [MessageService, ValidationService, + SSOService, + { provide: HTTP_INTERCEPTORS, useClass: InterceptLoader, multi: true }] +}) +export class AuthModule { } diff --git a/src/app/modules/auth/forget-password/forget-password.component.html b/src/app/modules/auth/forget-password/forget-password.component.html new file mode 100644 index 0000000..4b4595b --- /dev/null +++ b/src/app/modules/auth/forget-password/forget-password.component.html @@ -0,0 +1,89 @@ +
    +
    + +
    +
    +
    +

    Reset Your Password

    + Enter your new password and then re-enter it for confirmation. +
    +
    + Create your password +
    + + + +
    + + Please enter password + + Please check the password criteria +
    +
    +
      +
    • One + lowercase letter
    • +
    • One + uppercase + letter
    • +
    • + One number
    • +
    +
      +
    • + One + special character
    • +
    • 8 + characters minimum
    • +
    +
    +
    + Confirm new password + +
    + + + +
    + Please + enter confirm password +
    +
    + +
    +
    +
    +
    +
    +
    + Image +

    Thank you.

    +

    {{showMsgValid.Message}}

    +

    You can close this page.

    +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/auth/forget-password/forget-password.component.ts b/src/app/modules/auth/forget-password/forget-password.component.ts new file mode 100644 index 0000000..3a229b0 --- /dev/null +++ b/src/app/modules/auth/forget-password/forget-password.component.ts @@ -0,0 +1,88 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-forget-password', + templateUrl: './forget-password.component.html', +}) +export class ForgetPasswordComponent implements OnInit { + + + constructor( + private router: Router, + public fb: FormBuilder, + public validationService: ValidationService, + public ApiServ: API, + private route: ActivatedRoute, + public commonService: CommonFunctionService + + ) { } + showPass = false; + confirmPass = false; + ResetPswdForm: FormGroup; + + ngOnInit(): void { + this.ResetPswdForm = this.fb.group({ + Password: this.validationService.passwordV2, + confirm_password: this.validationService.required, + EncryptedData: [''], + }); + this.route.queryParams.subscribe((key_obj) => { + if (key_obj) { + this.ResetPswdForm.get('EncryptedData').setValue(key_obj['key']); + this.checkResetPassAllow(key_obj['key']) + } + }); + } + ResetPassword() { + if (this.ResetPswdForm.status == 'INVALID') { + this.validationService.showValidationsMsg(this.ResetPswdForm); + return; + } + let reset_pswd_obj_val = this.ResetPswdForm.getRawValue(); + if (reset_pswd_obj_val.Password != reset_pswd_obj_val.confirm_password) { + this.commonService.showMessage(false, 'Your password does not match with confirm password') + return; + } + let data = { + Password: reset_pswd_obj_val.Password, + EncryptedData: reset_pswd_obj_val.EncryptedData, + }; + let Object = { + key: securityFunctions.encryptRSA(securityFunctions.rsa_public_key, JSON.stringify(data)), + }; + this.ApiServ.AdminGoPost('/ExtranetUserMaster/UpdatePassword', Object).subscribe(res => { + if (res.resp) { + this.commonService.showMessage(true, 'Your password has been changed successfully.') + } + else { + this.commonService.showMessage(res['Resp'], res['Message']) + } + setTimeout(() => { + res.Resp ? this.router.navigate(['/Auth/Login']) : ''; + }, 500); + }) + } + btnClick() { + this.router.navigateByUrl("Auth/Login"); + }; + + showMsgValid; + checkResetPassAllow(dataObj) { + this.ApiServ.AdminGOGet("/ExtranetUserMaster/IsLinkValid/" + dataObj + '/true').subscribe(res => { + if (res) { + this.showMsgValid = res + } + }) + } + onKeyUp(event: KeyboardEvent) { + if (event.keyCode === 13) { // If Enter key is pressed + this.ResetPassword(); + } + } +} diff --git a/src/app/modules/auth/login/login.component.html b/src/app/modules/auth/login/login.component.html new file mode 100644 index 0000000..b7e8a04 --- /dev/null +++ b/src/app/modules/auth/login/login.component.html @@ -0,0 +1,239 @@ +
    +
    +
    + + + + + +
    +
    + Image +

    For your security

    +

    Please verify your identification by clicking on the verification link send on your mail which is + valid for 5 minutes.

    +
    +
    + +
    + +
    +

    OTP Verification

    +

    Code sent to {{Email}}

    +
    + +
    + Resend code in 00:{{timeLeft >= 0 && timeLeft <= 9?'0' + + timeLeft : timeLeft}} + +
    +

    Didn't receive an OTP?

    + Please try again to login +
    +
    + {{errorMessage}} +
    +
    + +
    +
    +
    + +
    + +
    +

    Forget Your Password

    +
    +
    + Reset your password using your email +
    + + + + +
    +
    + Please enter + email + Please enter + valid email +
    + +
    +

    If you don't remember the email address you used to create your account,please + Contact us + +

    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/app/modules/auth/login/login.component.ts b/src/app/modules/auth/login/login.component.ts new file mode 100644 index 0000000..57e6991 --- /dev/null +++ b/src/app/modules/auth/login/login.component.ts @@ -0,0 +1,578 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Component, OnInit, Renderer2 } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Title } from '@angular/platform-browser'; +import { Router } from '@angular/router'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { CookieService } from 'ngx-cookie-service'; +import { LoginModel, OTPModel } from 'src/app/core/models/common-model/Sign-in.model'; +import { NgOtpInputConfig } from 'ng-otp-input'; +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', +}) +export class LoginComponent implements OnInit { + + constructor( + private router: Router, + public ApiServ: API, + public commonService: CommonFunctionService, + public titleService: Title, + public fb: FormBuilder, + public validationService: ValidationService, + private http: HttpClient, + private cookieService: CookieService, + private renderer: Renderer2, + ) { } + SignInForm: FormGroup; + ResetPswdForm: FormGroup; + ShowUserVerificationBox = false; + showPass: boolean = false; + userInterval; + errorMessage = ''; + OTPSection = false; + ForgetPassword = false; + Email = ''; + UserIpDetails; + // Timer + resendBtn; + timerBtn; + timeLeft: number; + interval; + NewPaas = false; + comfirmPass = false; + ngOnInit(): void { + sessionStorage.removeItem('excd'); + securityFunctions.resetSessionStoage('lastLogin') + securityFunctions.resetSessionStoage('LoginUserData') + securityFunctions.resetSessionStoage('VData') + securityFunctions.resetSessionStoage('userName') + securityFunctions.resetSessionStoage('JwtToken') + securityFunctions.resetSessionStoage('RefreshToken') + securityFunctions.resetSessionStoage('JwtTokenExpiry') + securityFunctions.resetSessionStoage('menu') + this.SignInForm = this.fb.group({ + EmailID: this.validationService.email, + Password: this.validationService.required, + OTP: this.validationService.required, + forgetPassEmail: this.validationService.email + }); + this.IsPassWordChange = false; + this.GetIpAddress(); + this.changePasswordCreate(); + }; + SetupPage() { + this.getLogo() + } + orgLogo + getLogo() { + const favicon = this.renderer.selectRootElement('link[rel="icon"]', true); + this.ApiServ.AdminGet('/ForgotPassword/GetOrgLogo').subscribe((res) => { + if (res != null) if (res["logo"] != null) { + this.orgLogo = res["logo"]; + sessionStorage.setItem("logo", JSON.stringify(res)); + this.titleService.setTitle('Inventory Management | ' + res.org_name) + document.documentElement.style.setProperty('--primary-theme', res['primary_color']); + document.documentElement.style.setProperty('--secondary-theme', res['secondary_color']); + this.renderer.setAttribute(favicon, 'href', res['favicon'] ? res['favicon'] : './assets/images/TMC.svg'); + } else { + this.orgLogo = "https://cdn-aos.b-cdn.net/Static/Email/TMC.svg"; + } + }) + } + onKeyUp(event) { + if (event.keyCode == 13 && !this.disableSignInButton) { + this.SignIn(); + } + + } + viewPass() { + this.showPass = !this.showPass; + } + // config OTP + config: NgOtpInputConfig = { + allowNumbersOnly: true, + length: 4, + isPasswordInput: false, + disableAutoFocus: true, + placeholder: '●', + }; + + userId = ''; + disableSignInButton = false; + SignIn() { + if (this.SignInForm.get('EmailID').status == "INVALID" || this.SignInForm.get('Password').status == "INVALID") { + this.validationService.showValidationsMsg(this.SignInForm.get('EmailID')); + this.validationService.showValidationsMsg(this.SignInForm.get('Password')); + return; + } + this.disableSignInButton = true; + clearInterval(this.userInterval); + let val = this.SignInForm.getRawValue(); + let postData = new LoginModel(); + postData.EmailID = val.EmailID; + postData.Password = val.Password; + postData.domain = document.location.host; + // postData.domain = 'extranet.aos-dev.com'; + postData.ProjectId = '2405170833594899108'; + postData.Browser = this.getBrowserName(); + postData.City = this.UserIpDetails.city; + postData.CountryCode = this.UserIpDetails.countryCode; + postData.IP = this.UserIpDetails.query; + postData.Lon = this.UserIpDetails.lon; + postData.Lat = this.UserIpDetails.lat; + postData.Proxy = this.UserIpDetails.proxy; + postData.Platform = this.getPlatform(); + postData.MachineId = this.cookieService.check('MacId') ? this.cookieService.get('MacId') : '' + postData.time = (this.ApiServ.getAdjustedLocalTime() * 10000 + 621355968000000000).toString() + localStorage.setItem('UserEmail', val.EmailID); + let obj = { + key: securityFunctions.encryptRSA(securityFunctions.rsa_public_key, JSON.stringify(postData)), + }; + // let domain = 'extranet.aos-dev.com' + // // let domain = document.location.host; + // let domainName = domain.replace(/^(https?:\/\/)?/, ''); + // let domain_time = domainName + '~' + new Date().getTime(); + // let key = securityFunctions.rsa_public_key; + // let encrypted_string = securityFunctions.encryptRSA(key, domain_time).toString(); + // const headers = new HttpHeaders({ + // 'token': encrypted_string, + // }); + // const options = { headers: headers }; + this.ApiServ.AdminPost('/ExtranetLogin/ValidateLogin', obj).subscribe((res) => { + if (res !== null) { // Check if res is not null + this.disableSignInButton = false + this.CheckUserStatusForLogin(res, true); + } else { + this.disableSignInButton = false + this.router.navigateByUrl("Auth/Login"); + } + }, error => { + this.disableSignInButton = false + this.router.navigateByUrl("Auth/Login"); + }); + }; + + + // verify + CheckUserVerification(key_resp) { + let req = { + key: key_resp + } + // let domain = document.location.host + // let domainName = domain.replace(/^(https?:\/\/)?/, ''); + // let domain_time = domainName + '~' + new Date().getTime(); + // let key = securityFunctions.rsa_public_key; + // let encrypted_string = securityFunctions.encryptRSA(key, domain_time).toString(); + // const headers = new HttpHeaders({ + // // 'Referer': window.location.origin, // Assuming you want to send the current origin as Referer + // 'token': encrypted_string + // }); + // const options = { headers: headers }; + this.ApiServ.AdminPost('/UserMachine/CheckUserVerified', req).subscribe(res => { + if (res) { + if (res.Status) { + clearInterval(this.userInterval); + if (res.VerificationStatus == 'APPROVED') { + this.SignIn(); + } else if (res.VerificationStatus == 'REJECT') { + this.ShowUserVerificationBox = false; + this.OTPSection = false; + this.errorMessage = 'Access Rejected'; + } + } else { + if (res.Message == 'Key Expired.') { + clearInterval(this.userInterval); + this.ShowUserVerificationBox = false; + this.errorMessage = 'Key Expired'; + } + } + } + }) + } + + loginPage() { + this.ShowUserVerificationBox = false; + this.OTPSection = false; + this.ForgetPassword = false; + } + + // OTP set + onOtpChange(otp) { + this.SignInForm.get('OTP').setValue(otp); + // if (otp.keyCode == 13 ) { + // this.Verify(); + // } + } + // Common verify + CheckUserStatusForLogin(res, MFACheck) { + if (res.Status) { + this.userId = res.ResponseObject.user_id; + if (!res.ResponseObject.change_default_password) { + const expirationDate = new Date(); + expirationDate.setFullYear(expirationDate.getFullYear() + 1); + res.MachineId && res.MachineId != 'null' ? this.cookieService.set('MacId', res.MachineId, expirationDate) : ''; + if (MFACheck && res.ResponseObject.IsMFAApplicable) { + if (res.ResponseObject.IsMFAApplicable) { + this.timerBtn = true; + this.resendBtn = false; + this.OTPSection = true; + this.errorMessage = ''; + this.timeLeft = 60; + this.startTimer(); + this.Email = localStorage.getItem('UserEmail'); + return + } + } + else { + if (MFACheck) { + if (!res.IsVerified) { + let time = (this.ApiServ.getAdjustedLocalTime() * 10000 + 621355968000000000).toString(); + var url_content = res.ResponseObject.user_id + "-" + res.MachineId.replace(/-/g, "~") + "-" + time; + let key = securityFunctions.EncryptReq(url_content) + this.ShowUserVerificationBox = true; + this.OTPSection = false; + this.userInterval = setInterval(() => { + this.CheckUserVerification(key); + }, 6000); + let verificationTimeout = 5 * 60 * 1000; + setTimeout(() => { + clearInterval(this.userInterval); + }, verificationTimeout); + return; + } + else { + this.SetSessionForLogin(res); + } + } else { + this.SetSessionForLogin(res); + this.commonService.showMessage(res['ResponseObject'], res['Message']); + } + }; + // this.getMenus().subscribe(res => { + // if (res) { + // // sessionStorage.setItem('menu', JSON.stringify(res)) + // // this.IsOpenDefaultUrl(res); + // } + // }) + } else { + this.IsPassWordChange = true; + return + } + } else { + // !res.Status ? this.loginPage() : ''; + if (res.Message == 'token details not saved') { + this.loginPage() + } + this.errorMessage = res.Message + } + } + + SetSessionForLogin(res) { + clearInterval(this.userInterval); + let date = new Date(moment(res.ResponseObject.last_login).format("YYYY MM DD hh:mm:ss") + " UTC"); + let lastLogin = moment(date.toString()).format("hh:mm:ss, DD MMM YYYY"); + securityFunctions.setSessionStorage('LoginUserData', JSON.stringify(res.ResponseObject)); + sessionStorage.getItem('JwtToken') ? '' : sessionStorage.setItem('JwtToken', res.JwtToken); + sessionStorage.getItem('RefreshToken') ? '' : sessionStorage.setItem('RefreshToken', res.RefreshToken); + sessionStorage.getItem('JwtTokenExpiry') ? '' : sessionStorage.setItem('JwtTokenExpiry', res.JwtTokenExpiry); + this.commonService.FetchExtranetVendorMaster(res.ResponseObject.extranet_vendor_id, false).subscribe(data => { + if (data) { + securityFunctions.setSessionStorage('VData', JSON.stringify(data.Result[0])); + } + }); + sessionStorage.setItem('userName', res.ResponseObject.first_name); + sessionStorage.setItem('org_id', res.ResponseObject.org_id); + sessionStorage.setItem('lastLogin', lastLogin); + // sessionStorage.setItem('IscancelPNR', res.ResponseObject.IsCancelPnr); + // sessionStorage.setItem('Is_Void', res.ResponseObject.IsAllowVoidTicket); + // sessionStorage.setItem('TpinApplicable', res.TpinApplicable); + // sessionStorage.setItem('T_Activated', res.TpinActivated); + // sessionStorage.setItem('T_Expired', res.TpinExpired); + this.ShowUserVerificationBox = false; + this.OTPSection = false; + this.router.navigateByUrl("/"); + this.commonService.StartTimer(); + } + // MFA + startTimer() { + this.interval = setInterval(() => { + if (this.timeLeft > 0) { + this.timeLeft--; + } + if (this.timeLeft == 0) { + clearInterval(this.interval); + this.resendBtn = true; + this.timerBtn = false; + } + }, 1000); + } + + ReSendOTP() { + this.SendOTP(); + this.timerBtn = false; + this.resendBtn = false; + this.timeLeft = -1; + }; + SendOTP() { + this.ApiServ.AdminGet('/OTP/ResendOTP/' + this.userId).subscribe( + (data) => { + if (data) { + this.commonService.showMessage(data['resp'], data['respMsg']); + } + } + ); + }; + getMenus() { + return this.http.get(environment.APIBaseUrl + '/MenuMasterNew/GetAllMenuByUserId/' + sessionStorage.getItem('userId') + '/2405170833594899108') + } + Verify() { + if (this.SignInForm.get('OTP').status == "INVALID") { + this.errorMessage = 'Please enter valid OTP' + return; + } + let val = this.SignInForm.getRawValue(); + let postData = new OTPModel(); + postData.oTP = val.OTP; + postData.userId = this.userId; + postData.browser = this.getBrowserName(); + postData.city = this.UserIpDetails.city; + postData.countryCode = this.UserIpDetails.countryCode; + postData.iP = this.UserIpDetails.query; + postData.lon = this.UserIpDetails.lon; + postData.lat = this.UserIpDetails.lat; + postData.proxy = this.UserIpDetails.proxy; + postData.ProjectId = '2405170833594899108'; + postData.platform = this.getPlatform(); + postData.macId = this.cookieService.check('MacId') ? this.cookieService.get('MacId') : ''; + this.ApiServ.AdminPost('/OTP/VerifyOTP', postData).subscribe(res => { + if (res) { + this.CheckUserStatusForLogin(res, false); + } else { + this.router.navigateByUrl("Auth/Login"); + } + }) + }; + // forget Password + SendMail() { + if (this.SignInForm.get('forgetPassEmail').status == "INVALID") { + this.validationService.showValidationsMsg(this.SignInForm.get('forgetPassEmail')); + return; + } + let val = this.SignInForm.get('forgetPassEmail').value; + let request = { + email: val, + domain: window.location.origin, + time: (this.ApiServ.getAdjustedLocalTime()).toString() + }; + let obj = { + key: securityFunctions.encryptRSA(securityFunctions.rsa_public_key, JSON.stringify(request)), + }; + this.ApiServ.AdminGoPost('/ExtranetUserMaster/ValidateEmail', obj).subscribe( + (data) => { + if (data) { + this.commonService.showMessage(data['Resp'], data['Message']); + } + } + ); + }; + // get user details + getPlatform() { + var platform = ""; + const userAgent = window.navigator.userAgent.toLowerCase(); + if (/android/i.test(userAgent)) { + platform = 'Android device'; + } else if (/iphone|ipad|ipod/i.test(userAgent)) { + platform = 'iOS device'; + } else if (/windows phone/i.test(userAgent)) { + platform = 'Windows phone'; + } else if (/win/i.test(userAgent)) { + platform = 'Windows desktop'; + } else if (/mac/i.test(userAgent)) { + platform = 'Mac desktop'; + } else if (/linux/i.test(userAgent)) { + platform = 'Linux desktop'; + } else { + platform = 'Unknown device'; + } + return platform; + } + // getBrowser() { + // var browserName = ''; + // var userAgent = navigator.userAgent; + + // if (userAgent.indexOf('Firefox') > -1) { + // browserName = 'Mozilla Firefox'; + // } else if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) { + // browserName = 'Opera'; + // } else if (userAgent.indexOf('Trident') > -1) { + // browserName = 'Microsoft Internet Explorer'; + // } else if (userAgent.indexOf('Edge') > -1) { + // browserName = 'Microsoft Edge'; + // } else if (userAgent.indexOf('Chrome') > -1) { + // browserName = 'Google Chrome'; + // } else if (userAgent.indexOf('Safari') > -1) { + // browserName = 'Apple Safari'; + // } + + // return browserName; + // } + + getBrowserName(): string { + const userAgent = navigator.userAgent; + if (userAgent.includes("Chrome")) { + return "Google Chrome"; + } else if (userAgent.includes("Firefox")) { + return "Mozilla Firefox"; + } else if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) { + return "Apple Safari"; + } else if (userAgent.includes("Edge")) { + return "Microsoft Edge"; + } else if (userAgent.includes("OPR") || userAgent.includes("Opera")) { + return "Opera"; + } else if (userAgent.includes("MSIE") || userAgent.includes("Trident/")) { + return "Internet Explorer"; + } else { + return "Unknown Browser"; + } + } + + // Example usage: + GetIpAddress() { + this.http.get("https://pro.ip-api.com/json/?fields=query,countryCode,lat,lon,city,proxy&&key=JZDsrdeBzIM0yyN").subscribe(res => { + if (res) { + this.UserIpDetails = res; + let obj = { + city: res['city'], + countryCode: res['countryCode'], + lat: res['lat'], + lon: res['lon'], + proxy: res['proxy'], + iP: res['query'], + }; + this.SetupPage(); + sessionStorage.setItem('IP', JSON.stringify(obj)); + } + }) + }; + + // common function + addRemoveValid(name, check) { + if (check) { + this.SignInForm.get(name).addValidators([Validators.required]); + } else { + this.SignInForm.get(name).clearValidators(); + } + this.SignInForm.get(name).updateValueAndValidity(); + this.SignInForm.get(name).markAsUntouched(); + }; + + // Tpin + // CheckTpinAllowOrNot(response) { + // if (response.TpinApplicable) { + // if (!response.TpinActivated || response.TpinExpired) { + // const now = new Date(); + // const formattedDate = now.toISOString().slice(0, 19).replace('T', ' '); + // let keyVal = securityFunctions.EncryptReq(response.ResponseObject.user_id + '~' + formattedDate + '~' + (response.TpinExpired ? 'expired' : 'create')).trim() + // this.router.navigate(['/Login/TPIN'], { queryParams: { key: keyVal } }); + // return false + // } + // } + // return true + // } + + password_criteria_obj = { + is_lowerCase: false, + is_Uppercase: false, + is_Capital_case: false, + is_numbers: false, + is_special_characters: false, + is_length: false + }; + IsPassWordChange = false; + changePasswordCreate() { + this.password_criteria_obj = { + is_lowerCase: false, + is_Uppercase: false, + is_Capital_case: false, + is_numbers: false, + is_special_characters: false, + is_length: false + }; + this.ResetPswdForm = this.fb.group({ + Password: this.validationService.passwordV2, + confirm_password: this.validationService.required, + }); + } + password_criteria(password_Value) { + password_Value.length >= 8 ? this.password_criteria_obj.is_length = true : this.password_criteria_obj.is_length = false; + password_Value.match(this.validationService.regExps.lower_case) ? this.password_criteria_obj.is_lowerCase = true : this.password_criteria_obj.is_lowerCase = false; + password_Value.match(this.validationService.regExps.Capital_case) ? this.password_criteria_obj.is_Uppercase = true : this.password_criteria_obj.is_Uppercase = false; + password_Value.match(this.validationService.regExps.numbers) ? this.password_criteria_obj.is_numbers = true : this.password_criteria_obj.is_numbers = false; + password_Value.match(this.validationService.regExps.special_characters) ? this.password_criteria_obj.is_special_characters = true : this.password_criteria_obj.is_special_characters = false; + }; + + // ResetPassword() { + // if (this.ResetPswdForm.status == 'INVALID') { + // this.validationService.showValidationsMsg(this.ResetPswdForm); + // return; + // } + // let reset_pswd_obj_val = this.ResetPswdForm.getRawValue(); + // if (reset_pswd_obj_val.Password != reset_pswd_obj_val.confirm_password) { + // this.commonService.showMessage(false, 'Your password does not match with confirm password') + // return; + // } + // let PostData = { + // "user_id": this.userId, + // "password": reset_pswd_obj_val.Password, + // "change_default_password": false + // } + // let encryptRSAData = { + // key: securityFunctions.encryptRSA(securityFunctions.rsa_public_key, JSON.stringify(PostData)), + // }; + // this.http.post(environment.APIBaseUrl + '/StaffMaster/ResetStaffPasswordHome', encryptRSAData).subscribe(res => { + // if (res.resp) { + // this.commonService.showMessage(true, 'Your password has been changed successfully.'); + // this.IsPassWordChange = false; + // } + // else { + // this.commonService.showMessage(res.resp, res.respMsg); + // } + // }) + // } + + + // + // IsOpenDefaultUrl(data) { + // let agency = data.find(e => e.menu_id == '2306211409428416327'); + // let flight_booking = data.find(e => e.menu_id == '2307251023313127095'); + // let hotel_booking = data.find(e => e.menu_id == '2307251027232645472'); + // let flight_transaction = data.find(e => e.menu_id == '2307251045530701040'); + // let lead_management = data.find(e => e.menu_id == '2307251305094097395'); + // if (agency) this.navigateMenuLink(agency); + // else if (flight_booking) this.navigateMenuLink(flight_booking); + // else if (hotel_booking) this.navigateMenuLink(hotel_booking); + // else if (lead_management) this.navigateMenuLink(lead_management); + // else if (flight_transaction) this.navigateMenuLink(flight_transaction); + // else this.router.navigateByUrl("/Home/Dashboard"); + // } + navigateMenuLink(menu) { + let url = '/' + menu.ui_controller + '/' + menu.ui_action; + if (url) { + sessionStorage.setItem('selMenu', url); + window.location.href = window.location.origin + url; + } + }; + + onKeyup(event: KeyboardEvent) { + if (event.keyCode === 13) { // If Enter key is pressed + this.SendMail(); + } + } + +} diff --git a/src/app/modules/auth/single-sign-on/single-sign-on.component.html b/src/app/modules/auth/single-sign-on/single-sign-on.component.html new file mode 100644 index 0000000..959175f --- /dev/null +++ b/src/app/modules/auth/single-sign-on/single-sign-on.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/modules/auth/single-sign-on/single-sign-on.component.ts b/src/app/modules/auth/single-sign-on/single-sign-on.component.ts new file mode 100644 index 0000000..31e04d6 --- /dev/null +++ b/src/app/modules/auth/single-sign-on/single-sign-on.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { SSOService } from 'src/app/core/services/sso.service'; + +@Component({ + selector: 'app-single-sign-on', + templateUrl: './single-sign-on.component.html', +}) +export class SingleSignOnComponent implements OnInit { + IPData; + constructor( + private route: ActivatedRoute, + private ssoService: SSOService, + ) { + this.route.queryParams.subscribe((params) => { + ssoService.validateSSOLogin(params['key'], params['LoginUserId']); + if (params['langcode']) { + sessionStorage.setItem('LangCode', params['langcode']); + } + }); + }; + ngOnInit(): void { + + } + +} diff --git a/src/app/modules/auth/verify-email/verify-email.component.html b/src/app/modules/auth/verify-email/verify-email.component.html new file mode 100644 index 0000000..7b91dd6 --- /dev/null +++ b/src/app/modules/auth/verify-email/verify-email.component.html @@ -0,0 +1,34 @@ +
    +
    +
    + Image +

    Thank you.

    +

    Sign-in attempt was approved.

    +

    You can close this page.

    +
    +
    +
    +
    + Image +

    Thank you.

    +

    Your account has been deactivated.

    +

    You can close this page.

    +
    +
    +
    +
    + Image +

    Thank you.

    +

    Sign-in attempt was denied.

    +

    You can close this page.

    +
    +
    +
    +
    + Image +

    The link you followed has expired.

    +

    Please try to login again.

    +

    You can close this page.

    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/auth/verify-email/verify-email.component.ts b/src/app/modules/auth/verify-email/verify-email.component.ts new file mode 100644 index 0000000..1cea634 --- /dev/null +++ b/src/app/modules/auth/verify-email/verify-email.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-verify-email', + templateUrl: './verify-email.component.html', +}) +export class VerifyEmailComponent implements OnInit { + + IPData; + constructor( + private route: ActivatedRoute, + private ApiServ: API, + public commonService: CommonFunctionService, + ) { } + ShowApprovalCard = false; + ShowRejectedCard = false; + ShowDeactivateCard = false; + ShowExpiredCard = false; + ngOnInit() { + this.ShowApprovalCard = false; + this.ShowRejectedCard = false; + this.ShowDeactivateCard = false; + this.ShowExpiredCard = false; + this.route.queryParams.subscribe((params) => { + this.VerifyUserEmail(params['key']); + }); + } + + + + VerifyUserEmail(key_resp) { + let obj = { + key: key_resp, + }; + this.ApiServ.AdminPost('/UserMachine/VerifyMachineEmail', obj).subscribe( + (d) => { + if (d && d.Status) { + if (d.VerificationStatus == 'APPROVED') this.ShowApprovalCard = true; + else if (d.VerificationStatus == 'REJECT') this.ShowRejectedCard = true; + else this.ShowDeactivateCard = true; + } else { + if (!d.Status && d.Message == 'Key Expired') { + this.ShowExpiredCard = true; + } + } + } + ); + }; + +} diff --git a/src/app/modules/booking-management/booking-management.component.html b/src/app/modules/booking-management/booking-management.component.html new file mode 100644 index 0000000..a085aaf --- /dev/null +++ b/src/app/modules/booking-management/booking-management.component.html @@ -0,0 +1 @@ +

    booking-management works!

    diff --git a/src/app/modules/booking-management/booking-management.component.ts b/src/app/modules/booking-management/booking-management.component.ts new file mode 100644 index 0000000..ffad177 --- /dev/null +++ b/src/app/modules/booking-management/booking-management.component.ts @@ -0,0 +1,11 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-booking-management', + templateUrl: './booking-management.component.html', +}) +export class BookingManagementComponent implements OnInit { + constructor() {} + + ngOnInit(): void {} +} diff --git a/src/app/modules/booking-management/booking-management.module.ts b/src/app/modules/booking-management/booking-management.module.ts new file mode 100644 index 0000000..0713af5 --- /dev/null +++ b/src/app/modules/booking-management/booking-management.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { BookingManagementComponent } from './booking-management.component'; +import { ExperienceBookingComponent } from './experience-booking/experience-booking.component'; + +const routes: Routes = [ + { + path: 'HotelBooking', + loadChildren: () => + import('./hotel-booking/hotel-booking.module').then( + (m) => m.HotelBookingModule + ), + }, + { + path: 'ExperienceBooking', + loadChildren: () => + import('./experience-booking/experience-booking.module').then( + (m) => m.ExperienceBookingModule + ), + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'search', + }, +]; + +@NgModule({ + declarations: [BookingManagementComponent, ExperienceBookingComponent], + imports: [CommonModule, RouterModule.forChild(routes)], +}) +export class BookingManagementModule {} diff --git a/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.html b/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.html new file mode 100644 index 0000000..935304b --- /dev/null +++ b/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.html @@ -0,0 +1 @@ +

    Experience-booking-search works!

    diff --git a/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.ts b/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.ts new file mode 100644 index 0000000..eb9bd72 --- /dev/null +++ b/src/app/modules/booking-management/experience-booking/experience-booking-search/experience-booking-search.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-Experience-booking-search', + templateUrl: './experience-booking-search.component.html', +}) +export class ExperienceBookingSearchComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/booking-management/experience-booking/experience-booking.component.html b/src/app/modules/booking-management/experience-booking/experience-booking.component.html new file mode 100644 index 0000000..736899f --- /dev/null +++ b/src/app/modules/booking-management/experience-booking/experience-booking.component.html @@ -0,0 +1 @@ +

    Experience-booking works!

    diff --git a/src/app/modules/booking-management/experience-booking/experience-booking.component.ts b/src/app/modules/booking-management/experience-booking/experience-booking.component.ts new file mode 100644 index 0000000..11dd16f --- /dev/null +++ b/src/app/modules/booking-management/experience-booking/experience-booking.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-Experience-booking', + templateUrl: './experience-booking.component.html', +}) +export class ExperienceBookingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/booking-management/experience-booking/experience-booking.module.ts b/src/app/modules/booking-management/experience-booking/experience-booking.module.ts new file mode 100644 index 0000000..ad67c9a --- /dev/null +++ b/src/app/modules/booking-management/experience-booking/experience-booking.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { ExperienceBookingSearchComponent } from './experience-booking-search/experience-booking-search.component'; + +const routes: Routes = [ + { + path: 'Search', + component: ExperienceBookingSearchComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ExperienceBookingSearchComponent], + imports: [CommonModule, RouterModule.forChild(routes)], +}) +export class ExperienceBookingModule {} diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.html b/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.html new file mode 100644 index 0000000..37aa38a --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.html @@ -0,0 +1,672 @@ +
    +
    +
    +

    Hotel Booking

    +
    +
    +
    +
    +
    +
    +
    + Trip ID + +
    +
    +
    +
    + Booking ID + +
    +
    +
    +
    + Company + + +
    +
    +
    +

    Company

    +
    + +
    +
    +
    + +
    + +
    Company
    +
    +
    +
    +
    +
    +
    +
    + Branch + + +
    +
    +
    +

    Branch

    +
    + +
    +
    +
    + +
    + +
    Branch
    +
    +
    +
    +
    +
    +
    +
    + Hotel Name + +
    +
    +
    +
    + Country + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + +
    + +
    Country
    +
    + +
    +
    +
    +
    +
    +
    + City + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + +
    + +
    City
    +
    + +
    +
    +
    +
    +
    +
    + Star Rating + + +
    +
    +
    +

    Star Rating

    +
    + +
    +
    +
    + +
    + +
    Star Rating
    +
    +
    +
    +
    +
    +
    +
    + Guest Name + +
    +
    +
    +
    + Contact Number + +
    +
    +
    +
    + Booking Status + + +
    +
    +
    +

    Booking Status

    +
    + +
    +
    +
    + +
    + +
    Booking Status
    +
    +
    +
    +
    +
    +
    +
    + Invoice Status + + +
    +
    +
    +

    Invoice Status

    +
    + +
    +
    +
    + +
    + +
    Invoice Status
    +
    +
    +
    +
    +
    + +
    +
    + Confirmation No. + +
    +
    +
    +
    +
    + Date Type +
    + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + +
    + +
    Payment Status
    +
    +
    +
    +
    +
    +
    +
    + From Date + + +
    +
    +
    +

    Date

    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + To Date + + +
    +
    +
    +

    Date

    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + Under Free Cancellation +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Trip ID + + + + Booking ID + + + + Hotel Name + + + + Country + + + + City + + + + Booking Date + + + + Check In Date + + + + Check Out Date + + + + No Of Nights + + + + No Of Rooms + + + + Room Name + + + + Lead Guest + + + + Lead Nationality + + + + Lead Mobile Number + + + + + Confirmation No + + + + Vendor Booking Amount + + + + Booking Status + + + + GUID + + + + Action + + + + + + {{HotelBooking.trip_id}} + {{HotelBooking.booking_id}} + {{HotelBooking.hotel_name}} + {{HotelBooking.hotel_country}} + {{HotelBooking.hotel_city}} + {{HotelBooking.booking_date}} + {{HotelBooking.checkin_date}} + {{HotelBooking.checkout_date}} + {{HotelBooking.no_of_nights}} + {{HotelBooking.no_of_rooms}} + {{HotelBooking.room_names_custom }} + {{HotelBooking.lead_guest}} + {{HotelBooking.guest_nationality_code}} + {{HotelBooking.guest_mobile_no}} + + {{HotelBooking.hotel_confirmation_number}} + {{HotelBooking.total}} + {{map_booking_status(HotelBooking.status_id, HotelBooking.payment_status)}} + {{HotelBooking.booking_guid}} + +
    + + + + + +
    + + +
    + + + + No data found + + + +
    +
    + +
    + + + + + + + + \ No newline at end of file diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.ts b/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.ts new file mode 100644 index 0000000..7ec2f71 --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking-search/hotel-booking-search.component.ts @@ -0,0 +1,560 @@ +import { Component, NgModule, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; +import { HotelBookingManagementService } from 'src/app/core/services/HotelServices/hotel_booking_management.service'; +import { Product } from 'src/app/core/services/product'; +import { securityFunctions } from 'src/app/core/common/security'; + +@Component({ + selector: 'hotel-booking-search', + templateUrl: './hotel-booking-search.component.html', +}) +export class HotelBookingSearchComponent implements OnInit { + analyticsData; + cols: any[]; + exportColumns; + products: Product[]; + HotelBookingFiltersForm: FormGroup; + confirmationForm: FormGroup; + selectedProducts: Product[]; + Agencylist; + Companylist; + Entitylist; + Countrylist; + Citylist; + AssignUserList=[]; + AssignSupportList=[]; + AssignUser=[]; + AssignSupport=[]; + AssignUserSearch=[]; + User_Type; + User_Name; + User_Id = [{user_id:'',user_name:'Assign to me'}]; + User_Id_sup = [{user_id:'',user_name:'Assign to me'}]; + HotelSupplierlist; + HotelBookingList; + @ViewChild('dt') myTable; + To_Date_Start; + AllCurrency; + isOpenAddConfirmationNumberModal: boolean = false; + AgencyType = [ + { key: "B2C", value: "B2C" }, + { key: "B2B", value: "B2B" } + ]; + Date_Type = [ + 'Booking Date', + 'Check In', + 'Check Out', + 'Cancellation Deadline' + ] + StarRating = [ + { key: "0", value: "0 Star" }, + { key: "1", value: "1 Star" }, + { key: "2", value: "2 Star" }, + { key: "3", value: "3 Star" }, + { key: "4", value: "4 Star" }, + { key: "5", value: "5 Star" } + ]; + BookingStatus = [ + { key:"0", value:"In Progress"}, + { key:"1", value:"Pending"}, + { key:"3", value:"Confirmed"}, + { key:"4", value:"Cancelled"}, + { key:"6", value:"Reserved"} + ]; + PaymentStatus = [ + { key: "PENDING", value: "Pending" }, + { key: "FAILED", value: "Failed" }, + { key: "PAID", value: "Paid" }, + { key: "PARTLYPAID", value: "Partly Paid" }, + { key: "PAID(AUTHORIZED)", value: "Paid (Authorized)" }, + ]; + InvoiceStatus = [ + { key: "INVOICED", value: "Invoiced" }, + { key: "INVOICEFAILED", value: "Invoice Failed" }, + { key: "INVOICEPENDING", value: "Invoice Pending" }, + { key: "INVOICEVOID", value: "Invoice Void" }, + ]; + + constructor( + private router: Router, + private formBuilder: FormBuilder, + private apiserv: API, + private hotelBkgMgmtService: HotelBookingManagementService, + private fb: FormBuilder, + public commonserv: CommonFunctionService + ) { } + ngOnInit(): void { + // this.apiserv.setTitle('Hotel Booking'); + this.cols = [ + { field: 'assigned_user_name', header: 'Assign User' }, + { field: 'assigned_user_name_2', header: 'Assign Support' }, + { field: 'trip_id', header: 'Trip Id' }, + { field: 'booking_id', header: 'Booking Id' }, + { field: 'payment_transaction_id', header: 'Payment Transaction Id' }, + { field: 'hotel_name', header: 'Hotel Name' }, + { field: 'hotel_country', header: 'Country' }, + { field: 'hotel_city', header: 'City' }, + { field: 'new_booking_date', header: 'Booking Date' }, + { field: 'checkin_date', header: 'Check In Date' }, + { field: 'checkout_date', header: 'Check Out Date' }, + { field: 'no_of_nights', header: 'No Of Nights' }, + { field: 'no_of_rooms', header: 'No Of Rooms' }, + { field: 'room_names_custom', header: 'Room Name' }, + { field: 'lead_guest', header: 'Lead Guest' }, + { field: 'guest_nationality_code', header: 'Lead Nationality' }, + { field: 'guest_mobile_no', header: 'Lead Mobile Number' }, + { field: 'guest_email_address', header: 'Lead Email Address ' }, + { field: 'supplier_name', header: 'Supplier' }, + { field: 'supplier_ref_no', header: 'Supplier Ref no.' }, + { field: 'agency_name', header: 'Agency' }, + { field: 'agency_type', header: 'Agency Type' }, + { field: 'booking_by', header: 'Booking By' }, + { field: 'quality_check', header: 'Quality Check' }, + { field: 'payment_status_custom', header: 'Payment Status' }, + { field: 'promo_code', header: 'Promo Code' }, + { field: 'payment_mode_custom', header: 'Payment Mode' }, + { field: 'total', header: 'Total Booking Amount' }, + { field: 'booking_status_custom', header: 'Booking Status' }, + { field: 'thirdparty_invoice_number', header: 'Accounting Invoice No.' }, + { field: 'thirdparty_invoice_status', header: 'AC Invoice No.' }, + { field: "NotesStr", header: "notes" }, + ]; + this.exportColumns = this.cols.map(col => ({ + title: col.header, + dataKey: col.field + })); + this.User_Type = sessionStorage.getItem('userType'); + this.User_Name = sessionStorage.getItem('userName'); + this.User_Id[0]['user_id'] = sessionStorage.getItem('userId'); + this.User_Id_sup[0]['user_id'] = sessionStorage.getItem('userId'); + this.formInitialize(); + this.getAllCurrency(); + this.getCompanyList(); + this.getEntityList(); + this.getHotelSupplierListV2(); + this.getHotelCountryList(); + this.setDefaultDate(); + } + formInitialize() { + this.HotelBookingFiltersForm = this.formBuilder.group({ + fltr_trip_id: [''], + fltr_booking_id: [''], + fltr_payment_transaction_id: [''], + fltr_company: [], + fltr_branch: [], + fltr_agency: [], + fltr_agency_type: [], + fltr_hotel_name: [''], + fltr_country: [], + fltr_city: [], + fltr_star_rating: [], + fltr_supplier: [], + fltr_supplier_ref_no: [''], + fltr_guest_name: [''], + fltr_guest_contact_no: [''], + fltr_guest_email: [''], + fltr_booking_status: [], + fltr_payment_status: [], + fltr_invoice_status: [], + fltr_date: [null], + from_Date: [''], + To_Date: [''], + promo_code: [''], + assigned_user: [''], + under_cancel: [false], + is_promo_code_applied: [false], + fail_cancel: [false], + }); + } + + getCompanyList() { + this.hotelBkgMgmtService.getAllCompany().subscribe((res) => { + if (res) { + this.Companylist = res; + console.log(this.Companylist); + } + }); + } + getHotelCountryList() { + this.hotelBkgMgmtService.getAllHotelCountry().subscribe((res) => { + if (res) { + this.Countrylist = res; + console.log(this.Countrylist); + } + }); + } + getHotelCityList(country_code) { + this.Citylist = null; + this.hotelBkgMgmtService.getAllHotelCityByCountry(country_code).subscribe((res) => { + if (res) { + this.Citylist = res; + } + }); + } + getEntityList() { + this.hotelBkgMgmtService.getAllEntity().subscribe((res) => { + if (res) { + this.Entitylist = res; + } + }); + } + + getAllCurrency() { + this.hotelBkgMgmtService.getAllCurrency().subscribe((res) => { + if (res) { + this.AllCurrency = res; + } + }); + } + getHotelSupplierList() { + this.hotelBkgMgmtService.getAllHotelSupplier().subscribe((res) => { + if (res) { + this.HotelSupplierlist = res; + } + }); + } + getHotelSupplierListV2() { + this.hotelBkgMgmtService.getAllHotelSupplierV2().subscribe((res) => { + if (res) { + this.HotelSupplierlist = res; + } + }); + } + getFormatedDate(obj) { + if (obj != null && obj != '' && obj) { + return moment(obj).format("DD MMM YYYY"); + } else { + return ""; + } + } + /** + * @Description setting the min date for To Date calender + * @param Date From Date + */ + + applyToDate(date) { + this.To_Date_Start = date + } + + search_bookings() { + let form_data = this.HotelBookingFiltersForm.value; + let VData = securityFunctions.getSessionStorage('VData') ? JSON.parse(securityFunctions.getSessionStorage('VData')) : ''; + let reqData = { + user_time_zone: this.commonserv.GetTimeZoneGMT(), + trip_id: form_data.fltr_trip_id, + booking_id: form_data.fltr_booking_id, + payment_transaction_id: form_data.fltr_payment_transaction_id, + agency_id: form_data.fltr_agency, + agency_type: form_data.fltr_agency_type, + user_id: "", + company_id: form_data.fltr_company, + entity_id: form_data.fltr_branch, + hotel_name: form_data.fltr_hotel_name, + country: form_data.fltr_country, + city: form_data.fltr_city, + star_rating: form_data.fltr_star_rating, + vendor_id: VData ? VData.extranet_vendor_id : '', + supplier: '', + supplier_ref_no: form_data.fltr_supplier_ref_no, + guest_name: form_data.fltr_guest_name, + contact: form_data.fltr_guest_contact_no, + email: form_data.fltr_guest_email, + promo_code: form_data.promo_code, + assigned_user: form_data.assigned_user?form_data.assigned_user:'', + is_promo_code_applied: form_data.is_promo_code_applied ? form_data.is_promo_code_applied.toString() : '', + fail_cancel: form_data.fail_cancel, + booking_status: form_data.fltr_booking_status, + payment_status: form_data.fltr_payment_status === 'PAID(AUTHORIZED)' ? 'PAID' : form_data.fltr_payment_status, + invoice_status: form_data.fltr_invoice_status, + booking_from_date: '', + booking_to_date: '', + + check_in_from_date: '', + check_in_to_date: '', + + check_out_from_date: '', + check_out_to_date: '', + + cancellation_deadline_from : '', + cancellation_deadline_to : '', + under_cancel: form_data.under_cancel, + is_authorized: form_data.fltr_payment_status === 'PAID(AUTHORIZED)' ? '1' : '0' + }; + if (form_data.fltr_date == 'Booking Date') { + reqData.booking_from_date = this.getFormatedDate(form_data.from_Date); + reqData.booking_to_date = this.getFormatedDate(form_data.To_Date) + } + else if (form_data.fltr_date == 'Check In') { + reqData.check_in_from_date = this.getFormatedDate(form_data.from_Date); + reqData.check_in_to_date = this.getFormatedDate(form_data.To_Date); + } + else if (form_data.fltr_date == 'Check Out') { + reqData.check_out_from_date = this.getFormatedDate(form_data.from_Date); + reqData.check_out_to_date = this.getFormatedDate(form_data.To_Date); + } + else if (form_data.fltr_date == 'Cancellation Deadline') { + reqData.cancellation_deadline_from = this.getFormatedDate(form_data.from_Date); + reqData.cancellation_deadline_to = this.getFormatedDate(form_data.To_Date); + } + + this.hotelBkgMgmtService.getHotelBookingList(reqData).subscribe((res) => { + if (res) { + this.myTable.first = 0; + this.HotelBookingList = res.map((x,i) => { + let obj_currency = this.AllCurrency.filter(g => g.currency_code == x.currency); + let amountFormat = obj_currency && obj_currency.length > 0 ? obj_currency[0].amount_format : '#,###,###,###.##'; + let decimalSeperator = obj_currency && obj_currency.length > 0 ? obj_currency[0].decimal_seperator : '.'; + x['total'] = x.supplier_currency + ' ' + this.commonserv.amountFormater(x.supplier_total_amount, amountFormat, decimalSeperator); + x['custom_booking_date'] = x.booking_date; + x['room_names_custom'] = x.room_names ? x.room_names.replaceAll(' <-> ',', ') : x.room_names; + x["NotesStr"] = x.notes ? x.notes.join(',') : ""; + x['new_booking_date'] = moment(x.booking_date).format('DD MMM YYYY, HH:mm:ss'); + x['custom_booking_date'] = x.booking_date; + x.booking_date = this.commonserv.UtcToLocaleTime(x.booking_date, 'DD MMM YYYY, HH:mm:ss'); + x['custom_checkin_date'] = x.checkin_date + x.checkin_date = moment(x.checkin_date).format('DD MMM YYYY'); + x['custom_checkout_date'] = x.checkout_date + x.checkout_date = moment(x.checkout_date).format('DD MMM YYYY'); + x['booking_status_custom'] = this.map_booking_status(x.status_id, x.payment_status); + x['payment_status_custom'] = this.map_payment_status(x.payment_status, x.is_authorised); + x['payment_mode_custom'] = x.payment_mode; + x["Index"] = i; + if(x.assigned_user){ + x.assigned_user == this.User_Id[0]['user_id']? this.User_Id[0]['user_name'] = this.User_Name :this.AssignUserList[i] = [{user_id:x.assigned_user,user_name:x.assigned_user_name}]; + } + if(x.assigned_user_2){ + x.assigned_user_2 == this.User_Id_sup[0]['user_id']? this.User_Id_sup[0]['user_name'] = this.User_Name :this.AssignSupportList[i] = [{user_id:x.assigned_user_2,user_name:x.assigned_user_name_2}]; + } + this.AssignUser[i] = x.assigned_user?x.assigned_user:null; + this.AssignSupport[i] = x.assigned_user_2?x.assigned_user_2:null; + return x; + }); + console.log(this.HotelBookingList); + } + }); + + } + map_payment_status(status, is_authorised) { + if (status != null && status != "") { + switch (status) { + case "PAID": { + return is_authorised ? 'Paid (Authorized)' : 'Paid'; + } + case "PENDING": { + return 'Pending'; + } + case "FAILED": { + return 'Failed'; + } + case "PARTLYPAID": { + return 'Partly Paid'; + } + default : { + return 'Not Attempt'; + } + } + } else { + return 'Not Attempt'; + } + } + map_payment_mode(mode) { + if (mode != null && mode != "") { + switch (mode) { + case "WALLET": { + return 'Wallet'; + } + case "CREDIT": { + return 'Credit'; + } + case "PAYATAGENCY": { + return 'Pay at Agency'; + } + case "PAYMENTGATEWAY": { + return 'Payment Gateway'; + } + case "PAYMENTGETWAY": { + return 'Payment Gateway'; + } + default : { + return '-'; + } + } + } else { + return '-'; + } + } + map_booking_status(booking_status, payment_status) { + if (booking_status != null) { + if (booking_status == 3) { + return 'Confirmed'; + } + else if (booking_status == 4) { + return 'Cancelled'; + } + else if(booking_status == 6) { + return 'Reserved'; + } + else if ((booking_status == 0 || booking_status == 2) && payment_status != null) { + return 'Pending'; + } + else { + return 'In Progress'; + } + } else { + return 'In Progress'; + } + } + search_form_reset() { + this.formInitialize(); + this.Citylist = null; + } + select_booking(trip_id) { + let obj = { + id: trip_id + } + const url = this.router.serializeUrl( + this.router.createUrlTree(['/BookingManagement/HotelBooking/View'], { queryParams: obj }) + ); + window.open(url, '_blank'); + } + quality_check(trip_tbl_id) { + this.hotelBkgMgmtService.bookingQualityCheck(trip_tbl_id).subscribe((res) => { + if (res) { + this.search_bookings(); + console.log(res); + } + }); + } + onCountrySelect(e) { + this.HotelBookingFiltersForm.get('fltr_city').setValue(null); + e ? this.getHotelCityList(e.country_code) : this.Citylist = null; + } + + GetAssignUser(event,index){ + let Obj={ + user_type:this.User_Type, + keyword:event.target.value + } + if(event.target.value.length>=3){ + this.apiserv.PostGo('/BookingManagement/GetOrgUserSearchDetails',Obj).subscribe(data=>{ + this.AssignUserList[index] = data.Result + this.AssignSupportList[index] = data.Result + }) + } + } + GetAssignUserValue(event){ + let Obj={ + user_type:this.User_Type, + keyword:event.target.value + } + if(event.target.value.length>=3){ + this.apiserv.PostGo('/BookingManagement/GetOrgUserSearchDetails',Obj).subscribe(data=>{ + this.AssignUserSearch = data.Result + }) + } + } + Save_User(trip_id,Value,i,update_type){ + let Obj = { + trip_id:trip_id, + user_id:Value?Value:'', + user_type:this.User_Type, + update_type: update_type + } + if(!Value){ + if(update_type == '1') { + this.AssignUser[i] = null; + } else { + this.AssignSupport[i] = null; + } + }else if(Value == this.User_Id[0]['user_id'] && update_type == '1'){ + this.User_Id[0]['user_name'] = this.User_Name; + } else if(Value == this.User_Id_sup[0]['user_id'] && update_type == '2'){ + this.User_Id_sup[0]['user_name'] = this.User_Name; + } + this.apiserv.PostGo('/BookingManagement/AssignTripToOrgUser',Obj).subscribe(data=>{ + // this.AssignUserList = data.Result + this.commonserv.showMessage(data['Resp'],data['Message']) + }) + } + GetDatabyAgencyType() { + this.HotelBookingFiltersForm.get('fltr_agency').setValue(null); + } + + // Set Default for the from date & to date + setDefaultDate(){ + this.HotelBookingFiltersForm.get("fltr_date").setValue("Booking Date"); + let from_date = new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000); + let to_date = new Date(); + this.HotelBookingFiltersForm.get("from_Date").setValue(from_date); + this.HotelBookingFiltersForm.get("To_Date").setValue(to_date); + } + initConfirmationForm(itinerary_data) { + let obj = { + booking_id: itinerary_data != null && itinerary_data.booking_id != null && itinerary_data.booking_id != '' ? itinerary_data.booking_id : "", + // hotel_confirmation_number: itinerary_data != null && itinerary_data.hotel_confirmation_number != null && itinerary_data.hotel_confirmation_number != '' ? itinerary_data.hotel_confirmation_number.split(',') : [], + hotel_confirmation_number_date: itinerary_data != null && itinerary_data.hotel_confirmation_number_date != null && itinerary_data.hotel_confirmation_number_date != '' ? new Date(itinerary_data.hotel_confirmation_number_date) : new Date(), + hotel_confirmation_staff_name: itinerary_data != null && itinerary_data.hotel_confirmation_staff_name != null && itinerary_data.hotel_confirmation_staff_name != '' ? itinerary_data.hotel_confirmation_staff_name : "", + hotel_confirmation_staff_remarks: itinerary_data != null && itinerary_data.hotel_confirmation_staff_remarks != null && itinerary_data.hotel_confirmation_staff_remarks != '' ? itinerary_data.hotel_confirmation_staff_remarks : "", + supplier_confirmation_number: itinerary_data != null && itinerary_data.supplier_confirmation_number != null && itinerary_data.supplier_confirmation_number != '' ? itinerary_data.supplier_confirmation_number : "" + } + this.confirmationForm = this.fb.group({ + booking_id: [obj.booking_id], + // hotel_confirmation_number: [obj.hotel_confirmation_number], + hotel_confirmation_number:this.fb.array([]), + supplier_confirmation_number:[obj.supplier_confirmation_number], + hotel_confirmation_number_date: [obj.hotel_confirmation_number_date], + hotel_confirmation_staff_name: [obj.hotel_confirmation_staff_name], + hotel_confirmation_staff_remarks: [obj.hotel_confirmation_staff_remarks], + }); + let formarray = this.confirmationForm.controls['hotel_confirmation_number'] as FormArray; + if(itinerary_data?.room_list.length > 0){ + itinerary_data.room_list.forEach(data=>{ + formarray.push( + this.fb.group({ + room_name:data.room_name, + room_id:data.hotel_room_id, + confirmation_no:data.hotel_confirmation_number, + }) + ) + }) + } + } + + openConfirmationNumberModal( itinerary_data) { + this.initConfirmationForm(itinerary_data); + this.isOpenAddConfirmationNumberModal = true; + } + + saveConfirmationNumber() { + let obj = this.confirmationForm.value; + let postdata = { + booking_id:obj.booking_id, + supplier_confirmation_number:obj.supplier_confirmation_number, + hotel_confirmation_number_date:obj.hotel_confirmation_number_date, + hotel_confirmation_staff_name:obj.hotel_confirmation_staff_name, + hotel_confirmation_staff_remarks:obj.hotel_confirmation_staff_remarks, + hotel_rooms:[] + } + let hotel_confirm_number = []; + obj.hotel_confirmation_number.forEach(data=>{ + hotel_confirm_number.push( + { + hotel_room_id:data.room_id, + hotel_confirmation_number:data.confirmation_no + } + ); + }) + postdata.hotel_rooms = hotel_confirm_number; + this.hotelBkgMgmtService.saveConfirmationNumber(postdata).subscribe((data) => { + if(data?.resp){ + this.isOpenAddConfirmationNumberModal = false; + this.search_bookings(); + } + }); + } + +} diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.html b/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.html new file mode 100644 index 0000000..5896f59 --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.html @@ -0,0 +1,594 @@ + +
    +
    +
    +

    Booking Details

    +
    +
    +
    +
    +
    +
    +
    Trip ID
    +

    {{ booking_customer_data.trip_id }}

    +
    +
    +
    Booking Date
    +

    {{ booking_customer_data.booking_date }}

    +
    +
    +
    +
    +
    Customer ID
    +

    {{ booking_customer_data.customer_id }}

    +
    +
    +
    Cutomer Contact
    +

    {{ booking_customer_data.customer_contact }}

    +
    +
    +
    Customer Email
    +

    {{ booking_customer_data.customer_email }}

    +
    +
    +
    Customer Profile Status
    +

    + + {{booking_customer_data.customer_profile_status?'Active':'Deactive'}} + +

    +
    +
    +
    Lead Guest
    +

    {{ booking_customer_data.lead_guest }}

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    Hotel Name
    +

    {{ itinerary.hotel_name }} ({{ itinerary.hotel_star_category }} Star) , {{itinerary.default_hotel_name}} +

    +
    +
    +
    Hotel Address
    +

    {{ itinerary.hotel_address }} , {{itinerary.default_hotel_address}}

    +
    +
    +
    City Name
    +

    {{cityList[i].cityName}}

    +
    +
    +
    Country Name
    +

    {{cityList[i].country}}

    +
    +
    +
    Check In
    +

    {{ itinerary.checkin_date | date: "dd MMM yyyy" }}

    +
    +
    +
    Check Out
    +

    {{ itinerary.checkout_date | date: "dd MMM yyyy" }}

    +
    +
    +
    No of Nights
    +

    {{ itinerary.no_of_nights }}

    +
    +
    +
    No of Rooms
    +

    {{ itinerary.no_of_rooms }}

    +
    +
    +
    +
    +
    Booking ID
    +

    {{ itinerary.booking_id }}

    +
    +
    +
    Booking Status
    +

    {{ map_booking_status( itinerary.status_id, itinerary.payment_status ) }} {{itinerary.status_id == '6' && itinerary.fail_cancel ? '('+ 'Auto Cancellation Failed'+')' :''}}

    +
    +
    +
    Confirmation Number
    +

    {{itinerary.hotel_confirmation_number}}

    + + + Add + Edit + + +
    +
    +
    Vendor Total Amount
    +

    {{itinerary.supplier_currency}} {{itinerary.supplier_total_amount}}

    +
    +
    +
    Total Original Booking Rate
    +

    {{itinerary.supplier_currency}} {{itinerary.supplier_total_amount}}

    +
    +
    +
    Total Vendor Cancellation Rate
    +

    {{itinerary.supplier_cancellation_currency}} {{itinerary.supplier_cancellation_amount}}

    +
    + +
    +
    Session ID
    +

    {{ itinerary.booking_guid }}

    +
    +
    +
    Latitude | Longitude
    +
    +

    {{itinerary.lan +' '}}

    +
    |
    +

    {{''+itinerary.lon}}

    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Room No.Room NameConfirmation NumberMeal TypeGuestStatus
    {{ i + 1 }}{{ room.room_name }}{{ room.room_supplier_confirmation_number }}{{ room.meal_plan }} {{ room.adt }} Adult, {{ room.chd }} Child + {{ map_room_status(room.room_booking_status) }}
    +
    +
    +
    +

    Itinerary Data not found

    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    Booking ID
    +

    {{ bkg.booking_id }}

    +
    +
    +
    Booking Status
    +

    {{ map_booking_status(bkg.status_id, bkg.payment_status) }}

    +
    +
    +
    Booking Date
    +

    {{ bkg.booking_date }}

    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Room No.Room NameMeal TypeGuestGuest NameGuest Nationality
    {{ i + 1 }} + {{ room.room_name }} + {{ room.meal_plan }} {{ room.adt }} Adult, {{ room.chd }} Child + +
    + {{ guest.guest_name }} + TBA + ({{ guest.guest_age }} years) +
    +
    {{itinerary_tab_data ? itinerary_tab_data[0].guest_nationality : ''}}
    +
    +
    + + + + + + + + + {{ bkg.special_request }}N/A + + +
    Special Request:-
    +
    +
    +
    +
    +

    Passenger Data not found

    +
    +
    + + +
    +
    +
    +
    +
    +
    Trip Id
    +

    {{ costing_tab_data.trip_id }}

    +
    +
    +
    Booking Id
    +

    {{ bkg.booking_id }}

    +
    + +
    +
    Contract Name
    +

    {{ bkg.Contract }}

    +
    +
    +
    Offer Details:
    +

    {{ bkg.Offer }}

    +
    +
    +
    Supplements:
    +

    {{ bkg.Supplement }}

    +
    +
    +
    + +
    +
    Currency
    +

    {{ bkg.supplier_currency }}

    +
    +
    +
    Vendor Total
    +

    {{ bkg.supplier_amount }}

    +
    + +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Room No.RoomMeal TypeGuest CountLead GuestConfirmation Number
    {{i+1}}{{Room_Details.room_name}}{{Room_Details.meal_plan}}{{ Room_Details.adt }} Adult, {{ Room_Details.chd }} Child{{Room_Details.lead_guest}}{{Room_Details.hotel_confirmation_number}} + + {{ Room_Details.hotel_confirmation_number ? 'Edit' : 'Add'}} + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Date{{Date}}Total
    Price{{Price}}{{Room_Details.Room_Allocation_Data.total}}
    Allocation{{allocation}}-
    Booked{{booked}}-
    Available after booking{{book_avail}}-
    +
    +
    +
    +
    +
    + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Sr NoNoteNote ByNoted On
    {{ i + 1 }}{{ note.note }}{{ note.note_by }}{{ note.noted_on }}
    + No data found +
    +
    +
    +
    +
    + + + + + + + + + + +
    + +
    +
    +
    +
    + {{ c_p_room.room_name }} +
    +
    +
    Supplier Cancellation Policy
    +
    +
  • From {{ can_p.from_date }} to {{ can_p.to_date }} charge of + {{ can_p.currency == '%' ? + can_p.amount + can_p.currency : can_p.currency + ' ' +can_p.amount }} + {{can_p.amount + ' ' +can_p.currency}} +
  • + +
    +

    {{can_p.text}}

    +
    + + + +
    Cancellation Policy Timezone: {{selectedItinerary && selectedItinerary.length > 0 ? selectedItinerary[0].timezone : ''}} {{cityList ? '(' + cityList[0].cityName + ')' : ''}}
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Invoice Number + + Please + enter invoice number +
    +
    + + + +
    + \ No newline at end of file diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.ts b/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.ts new file mode 100644 index 0000000..931f708 --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking-view/hotel-booking-view.component.ts @@ -0,0 +1,1243 @@ +import { Component, ElementRef, OnInit, ViewChild } from "@angular/core"; +import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms"; +import { ActivatedRoute, Router } from "@angular/router"; +import * as _ from 'lodash'; +import * as moment from "moment"; +import { MessageService, PrimeNGConfig } from 'primeng/api'; +import { forkJoin } from "rxjs"; +import { CommonFunctionService } from "src/app/core/common/common-function.service"; +import { ValidationService } from "src/app/core/common/validation.service"; +import { HotelBookingManagementService } from "src/app/core/services/HotelServices/hotel_booking_management.service"; +import { API } from "src/app/core/services/api.service"; + +@Component({ + selector: 'app-hotel-booking-view', + templateUrl: './hotel-booking-view.component.html', +}) +export class HotelBookingViewComponent { + dialogStatus = []; + isOpenAddNote: boolean = false; + VendorInvoiceForm:FormGroup; + isOpenCancellationPolicyModal: boolean = false; + isOpenAddConfirmationNumberModal: boolean = false; + isOpenAddVendorInvoiceNumberModal: boolean = false; + isOpenAddInvoiceNumberModal: boolean = false; + openInvoiceNumberModal() { + this.isOpenAddInvoiceNumberModal = true; + } + trip_id = ''; + active_tab; + AllCurrency; + addConfirmationNumber + AssignUserList; + User_Name; + User_Id = [{ user_id: '', user_name: 'Assign to me' }]; + AssignUser; + User_Type; + value: Date; + AllLanguage; + WhatsApp_Support; + agency_decimal_definer = '2'; + supplier_decimal_definer = '2'; + modalReference; + hotelBookingResp; + hotelItenaryResp; + hotelRoomDetail; + hotelGuestDetail; + hotelRoomGuestDetail; + hotelPassengerResp; + hotelCostingResp; + hotelPaymentResp; + hotelPaymentList; + hotelTotalAmount; + hotelNotesResp; + bookingId; + supplierNightlyRate = []; + hotelDocumentResp; + hotelSupplierCancellationPolicy; + hotelAgentCancellationPolicy; + hotelPassSupplierCancellationPolicy; + hotelPassAgentCancellationPolicy; + title = "appBootstrap"; + @ViewChild("NotesText") NotesInp: ElementRef; + closeResult: string = ""; + confirmationForm: FormGroup; + updateAccountingForm: FormGroup; + ConfirmationNo; + ConfirmationDate; + ConfirmationStaffName; + ConfirmationStaffRemarks; + agencyPolicyCharge; + supplierPolicyCharge; + bookingHistory: boolean = false; + bookingDetails: boolean = false; + ReleaseModal: boolean = false; + UpdateInStatus: boolean = false; + UpdAccountPayStatus: boolean = false; + rateBreakup: boolean = false; + CancellationDetails = null; + is_roomwise_policy: boolean = false; + checkBookingCancel = false; + CancellationRemarks = ''; + Cancellation_Agent_Amont = 0; + Cancellation_Supp_Amont = 0; + //SAGAR + currency_list = null; + booking_customer_data = null; + itinerary_tab_data = null; + guest_tab_data = null; + costing_tab_data = null; + payment_tab_data = null; + document_tab_data = null; + note_tab_data = null; + verification_tab_data = null; + veri_tab_data_mid = null; + selected__mail_document_type = ""; + mailForm: FormGroup; + StatusGroup: FormGroup; + hotelBookingForm: FormGroup; + notesform: FormGroup; + updateAccountingPayForm: FormGroup; + BookingStatus = [ + { key: 0, value: "In Progress" }, + { key: 1, value: "Pending" }, + { key: 3, value: "Confirmed" }, + { key: 4, value: "Cancelled" }, + { key: 6, value: "Reserved" } + ]; + thirdPartyInvoiceStatus = [ + {name: 'In Process' ,value: 'In Process'}, + {name: 'Pending' ,value: 'Pending'}, + {name: 'Success' ,value: 'Success'}, + {name: 'Failed' ,value: 'Failed'} + ] + paymentStatusList = [ + {name: 'Paid' ,value: 'PAID'}, + {name: 'Partly Paid' ,value: 'PARTLYPAID'}, + ] + paymentModeList = [ + {name: 'Payment Gateway', value: 'PAYMENTGATEWAY'}, + {name: 'Wallet Adjustment', value: 'WALLET'}, + {name: 'Accounting System Ledger', value: 'ACCONTING'}, + ] + tab_data_status = { itinerary: "loading", passenger: "loading", costing: "loading", payment: "loading", document: "loading" }; + features; + AllPaymentData; + constructor( + private router: Router, + private route: ActivatedRoute, + private fb: FormBuilder, + public APIServ: HotelBookingManagementService, + private ApiServ: API, + private messageService: MessageService, + public validationServ: ValidationService, + private primengConfig: PrimeNGConfig, + public commonserv: CommonFunctionService, + ) { + this.route.queryParams.subscribe(params => { + this.trip_id = params['id']; + }); + } + + // private getDismissReason(reason: any): string { + // if (reason === ModalDismissReasons.ESC) { + // return "by pressing ESC"; + // } else if (reason === ModalDismissReasons.BACKDROP_CLICK) { + // return "by clicking on a backdrop"; + // } else { + // return `with: ${reason}`; + // } + // } + ngOnInit(): void { + // this.ApiServ.setTitle('Hotel Booking'); + this.getFeatures('2308111245266426287'); + this.initFormsGroup(); + this.GetAllData(); + this.initConfirmationForm(null); + this.primengConfig.ripple = true; + this.User_Type = sessionStorage.getItem('userType'); + this.User_Name = sessionStorage.getItem('userName'); + this.User_Id[0]['user_id'] = sessionStorage.getItem('userId'); + } + + GetAllData(){ + forkJoin( + this.getCurrencyList(), + this.APIServ.getAllCurrency(), + this.getPageHeadersDetails(), + this.GetAllLAng(), + ).subscribe(res=>{ + if(res?.length > 0){ + this.AllCurrency = res[0]; + this.currency_list = res[1]; + if (res[2]) { + this.booking_customer_data = res[2]; + this.booking_customer_data.booking_date = this.booking_customer_data.booking_date ? this.commonserv.UtcToLocaleTime(this.booking_customer_data.booking_date, 'DD MMM YYYY, HH:mm:ss') : null; + this.booking_customer_data.customer_contact = this.booking_customer_data.customer_contact != null && this.booking_customer_data.customer_contact.trim() != '' ? (this.booking_customer_data.customer_contact.charAt(0) == '+' || this.booking_customer_data.customer_contact.charAt(0) == '-' ? this.booking_customer_data.customer_contact : '+' + this.booking_customer_data.customer_contact) : ''; + this.AssignUser = this.booking_customer_data.assigned_user_name?this.booking_customer_data.assigned_user_name:null; + } + this.AllLanguage = res[3]; + this.getItineraryTabDetails(); + } + }) + } + + initFormsGroup() { + this.StatusGroup = this.fb.group({ + statusArr: this.fb.array([]) + }); + + this.hotelBookingForm = this.fb.group({ + reasonOfNote: this.validationServ.required + }); + this.notesform = this.fb.group({ + Note: this.validationServ.required + }); + this.updateAccountingForm = this.fb.group({ + acc_invoice_status: this.validationServ.required, + acc_invoice_number: this.validationServ.required, + acc_ref_number: this.validationServ.required + }); + + this.updateAccountingPayForm = this.fb.group({ + booking_id: this.validationServ.required, + payment_status: this.validationServ.required, + payment_mode: this.validationServ.required, + currency: [""], + pending_amt: [0], + amount: this.validationServ.required, + receipt_no: this.validationServ.required, + remark: this.validationServ.required, + }); + this.VendorInvoiceForm = this.fb.group({ + vendor_invoice_number : this.validationServ.required + }); + }; + + get statusArr() { + return this.StatusGroup.get('statusArr') as FormArray; + }; + + showStatusDialog(ind) { + this.dialogStatus[ind] = true; + } + + CreateStatusGroup(data) { + if (data.length > 0 && data) { + data.forEach((e, i) => { + this.dialogStatus[i] = false; + this.statusArr.push(this.fb.group({ + status: [e.status_id, Validators.required] + })); + }); + }; + }; + + + tabClick(e) { + console.log(e); + switch (e.index) { + case 0: { + this.active_tab = e.index; + this.getItineraryTabDetails(); + break; + } + case 1: { + this.active_tab = e.index; + this.getPassengerTabDetails(); + break; + } + case 2: { + this.active_tab = e.index; + this.getCostingTabDetails(); + break; + } + case 3: { + this.active_tab = e.index; + this.getBookingNoteDetails(); + break; + } + case 4: { + this.getDocumentTabDetails(); + break; + } + case 5: { + this.getBookingNoteDetails(); + break; + } + case 6: { + this.getHBookingDetails(); + break; + } + } + } + getPageHeadersDetails() { + this.booking_customer_data = null; + return this.APIServ.getCustomerDetails(this.trip_id) + } + getItineraryTabDetails() { + this.tab_data_status.itinerary = "loading"; + this.itinerary_tab_data = null; + this.APIServ.GetItenaryDetails(this.trip_id).subscribe((data: any) => { + if (data) { + this.CreateStatusGroup(data); + this.itinerary_tab_data = data; + this.WhatsApp_Support = data[0] ? data[0].is_whatsapp_notify : false;//added is whatapp check of agency + if (this.itinerary_tab_data[0].payment_mode) { + this.updateAccountingPayForm.get('payment_mode').setValue(this.itinerary_tab_data[0].payment_mode); + } + if (this.itinerary_tab_data.assigned_user) { + this.itinerary_tab_data.assigned_user == this.User_Id[0]['user_id'] ? this.User_Id[0]['user_name'] = this.User_Name : this.itinerary_tab_data = [{ user_id: this.itinerary_tab_data.assigned_user, user_name: this.itinerary_tab_data.assigned_user_name }] + } + let hotelCities = []; + if (this.itinerary_tab_data.length > 0 && this.itinerary_tab_data) { + this.itinerary_tab_data.forEach(e => { + e.reserved_timeline_local = e.reserved_timeline_local ? this.commonserv.UtcToLocaleTime(e.reserved_timeline_local, 'DD MMM YYYY, HH:mm:ss') : e.reserved_timeline_local; + let onlyTime = e.user_timezone ? e.user_timezone.replace('UTC', '') : ''; + let obj_supplier_currency = this.currency_list.find(x => x.currency_code == e['supplier_currency']); + let supplier_decimal_definer = obj_supplier_currency ? obj_supplier_currency.currency_deci_definer : '2'; + e['supplier_total_amount'] = e['supplier_total_amount'] ? this.commonserv.amountDefiner(e['supplier_total_amount'],supplier_decimal_definer) : e['supplier_total_amount']; + if (onlyTime) { + let time = onlyTime.replace(')', ' Local Time)'); + e.user_timezone = time; + } + if (e.hotel_city_code) { + hotelCities.push(e.hotel_city_code); + }; + e['lan'] = null; + e['lon'] = null; + e['Ip'] = null; + if (e?.booking_user_lat_lon) { + let booking_user_IP_details = JSON.parse(e.booking_user_lat_lon); + e['lan'] = booking_user_IP_details ? booking_user_IP_details?.lat : null + e['lon'] = booking_user_IP_details ? booking_user_IP_details?.lon : null + e['Ip'] = booking_user_IP_details ? booking_user_IP_details?.query : null + }; + }) + } + if (hotelCities.length > 0 && hotelCities) { + this.GetSpecifiCitydetail(hotelCities); + } + this.tab_data_status.itinerary = "success"; + } else { + this.tab_data_status.itinerary = "failed"; + } + }, (error) => { + this.tab_data_status.itinerary = "failed"; + }); + } + cityList = null; + /** + * @author Abdul Razzak + * to get Specific city list + * @param val city code + */ + GetSpecifiCitydetail(val) { + let obj = { + cityCodes: val, + }; + this.APIServ.GethotelCityName(obj).subscribe((data) => { + if (data) { + this.cityList = data; + } else { + this.cityList = null; + } + }); + } + + mapHotelBkgDeadline(data) { + let agent_cancellation_policy = data.cancellation_policy.filter(x => x.from_type == 'agent').sort(function (a, b) { return a.sequence_no - b.sequence_no }); + let dateTimeArray = []; + if (agent_cancellation_policy && agent_cancellation_policy.length > 0) { + agent_cancellation_policy.forEach(cp => { + let date = cp.deadline_date_from != null && cp.deadline_date_from != '' ? this.commonserv.UtcToLocaleTime(cp.deadline_date_from, 'DD MMM YYYY') : ''; + let time = cp.deadline_time_from != null && cp.deadline_time_from != '' ? this.commonserv.UtcToLocaleTime(cp.deadline_time_from, 'hh:mm A') : ''; + let datetime = date && date != '' ? `${date} ${time}` : '' + if (datetime && datetime != null) { + dateTimeArray.push(datetime); + } + }); + + let $this = this; + dateTimeArray = dateTimeArray.sort(function (a, b) { return parseInt($this.commonserv.UtcToLocaleTime(a, 'YYYYMMDDHHmm')) - parseInt($this.commonserv.UtcToLocaleTime(b, 'YYYYMMDDHHmm')) }); + } + return dateTimeArray && dateTimeArray.length > 0 ? dateTimeArray[0] : ''; + } + + getPassengerTabDetails() { + this.tab_data_status.passenger = "loading"; + this.guest_tab_data = null; + this.APIServ.getPassengerDetails(this.trip_id).subscribe((data: any) => { + if (data) { + this.guest_tab_data = data; + this.guest_tab_data.map(li => { + li.booking_date = this.commonserv.UtcToLocaleTime(li.booking_date, 'DD MMM YYYY, HH:mm:ss') + }) + this.tab_data_status.passenger = "success"; + } else { + this.tab_data_status.passenger = "failed"; + } + }, (error) => { + this.tab_data_status.passenger = "failed"; + }); + } + getCostingTabDetails() { + this.tab_data_status.costing = "loading"; + this.costing_tab_data = null; + this.APIServ.getCostingDetails(this.trip_id).subscribe((data: any) => { + if (data) { + let booking_list = []; + data.map(bkg => { + let Supplements = []; + let contract_name = []; + let Offers = []; + let room_name = []; + let booking_count = 1; + let obj_agency_currency = this.currency_list.find(x => x.currency_code == bkg.currency); + let agency_decimal_definer = obj_agency_currency ? obj_agency_currency.currency_deci_definer : '2'; + let obj_supplier_currency = this.currency_list.find(x => x.currency_code == bkg.room_rate_list[0].supplier_currency); + let supplier_decimal_definer = obj_supplier_currency ? obj_supplier_currency.currency_deci_definer : '2'; + + bkg.room_rate_list.map(room_rate_det=>{ + room_rate_det['Date']=[]; + room_rate_det['Price']=[]; + room_rate_det['Allocation']=[]; + room_rate_det['Booked']=[]; + room_rate_det['Available_after_booking']=[]; + room_rate_det['total'] = 0; + let nightly_rate = room_rate_det.nightly_rate ? JSON.parse(room_rate_det.nightly_rate) : undefined; + if(room_rate_det.contract_name){ + contract_name.push(room_rate_det.contract_name); + } + let Supplement_obj = room_rate_det.supplements ? JSON.parse(room_rate_det.supplements) : undefined; + if(Supplement_obj){ + Supplement_obj[0].forEach(supp_data=>{ + Supplements.push(supp_data.Description); + }) + } + let Offer_Obj = room_rate_det.offers ? JSON.parse(room_rate_det.offers) : undefined; + if(Offer_Obj?.length > 0){ + Offer_Obj.forEach(e=>{ + Offers.push(e.offer_name); + }) + } + if(nightly_rate){ + room_name.push(room_rate_det.room_name); + if(room_name.includes(room_rate_det.room_name)){ + let filter_data = room_name.filter(e=>e == room_rate_det.room_name); + booking_count = filter_data.length; + } + nightly_rate.forEach(night_rate=>{ + let booked = bkg.room_list?.[0].room_booking_status == '3' ? (parseInt(night_rate.booked ) + booking_count) : night_rate.booked; + let price_obj = night_rate.PriceDetails.find(e=>e.PriceDetailType == 'BasePrice') + room_rate_det.Date.push(night_rate.date); + room_rate_det.Allocation.push(night_rate.allocation); + room_rate_det.Booked.push(booked); + room_rate_det.Price.push(price_obj.PriceInSourceCurrency); + room_rate_det.Available_after_booking.push(night_rate.allocation != 'FREESALE' ? (night_rate.allocation - booked) : night_rate.allocation); + room_rate_det.total += price_obj.PriceInSourceCurrency; + }); + room_rate_det.total = this.commonserv.amountDefiner(room_rate_det.total,supplier_decimal_definer) + } + }) + let room_details_arr = []; + bkg.room_list.forEach((room_det,i)=>{ + room_det['hotel_confirmation_number'] = room_det.hotel_confirmation_number; + room_det['booking_id'] = bkg.booking_id; + room_det['lead_guest'] = this.booking_customer_data.lead_guest; + room_det['hotel_confirmation_number_date'] = bkg.hotel_confirmation_number_date; + room_det['hotel_confirmation_staff_name'] = bkg.hotel_confirmation_staff_name; + room_det['hotel_confirmation_staff_remarks'] = bkg.hotel_confirmation_staff_remarks; + room_det['supplier_confirmation_number'] = bkg.supplier_confirmation_number; + room_det['Room_Allocation_Data'] = bkg.room_rate_list[i]; + room_details_arr.push(room_det); + }) + Offers = [...new Set(Offers)]; + let obj_booking = { + booking_id: bkg.booking_id, + invoice_no: bkg.vendor_invoice_number, + agency_currency: bkg.currency, + supplier_currency: bkg.room_rate_list[0].supplier_currency, + supplier_name: bkg.supplier_name, + supplier_amount: this.commonserv.amountDefiner(bkg.supplier_total_amount, supplier_decimal_definer), + total_amount: this.commonserv.amountDefiner(bkg.agent_total_amount, agency_decimal_definer), + rate_list_total_amount: this.commonserv.amountDefiner(bkg.agent_total_amount_without_buffer, agency_decimal_definer), + invoice_number: bkg.invoice_number, + Supplement: Supplements.join(', '), + Contract: contract_name.join(', '), + Offer: Offers.join(', '), + adjustment: this.commonserv.amountDefiner(bkg.buffer, agency_decimal_definer), + commercial_plan: bkg.commercial_plan, + adt: bkg.adt, + chd: bkg.chd, + promo_name: bkg.promo_code, + redeemed_points: bkg.redeemed_points, + loyalty_point_discount: bkg.loyalty_point_discount, + promo_amt: this.commonserv.amountDefiner(bkg.promo_total_discount, agency_decimal_definer), + hold_amount: this.commonserv.amountDefiner(bkg.hold_amount, agency_decimal_definer), + room_details_list:room_details_arr + } + booking_list.push(obj_booking); + }); + let obj_agency_currency = this.currency_list.find(x => x.currency_code == data[0].currency); + let agency_decimal_definer = obj_agency_currency ? obj_agency_currency.currency_deci_definer : '2'; + let obj_costing_tab = { + trip_id: data[0].trip_id, + coupon_code: "", + coupon_discount: this.commonserv.amountDefiner(0, agency_decimal_definer), + currency: data[0].currency, + payment_gateway: data[0].payment_gateway_name, + pg_fee: this.commonserv.amountDefiner(data[0].pg_fee, agency_decimal_definer), + thirdparty_invoice_number: data[0].thirdparty_invoice_number, + thirdparty_invoice_status: data[0].thirdparty_invoice_status, + thirdparty_reference_number: data[0].thirdparty_reference_number, + booking_list: booking_list, + } + this.costing_tab_data = obj_costing_tab; + this.tab_data_status.costing = this.costing_tab_data ? "success" : "failed"; + console.log(this.costing_tab_data); + } else { + this.tab_data_status.costing = "failed"; + } + }, (error) => { + this.tab_data_status.costing = "failed"; + }); + } + getPaymentTabDetails() { + this.tab_data_status.payment = "loading"; + this.payment_tab_data = null; + this.APIServ.getPaymentDetails(this.trip_id).subscribe((data: any) => { + if (data) { + this.payment_tab_data = data; + if (this.payment_tab_data) { + let obj_agency_currency = this.currency_list.find(x => x.currency_code == this.payment_tab_data.booking_list[0].invoice_currency); + this.agency_decimal_definer = obj_agency_currency ? obj_agency_currency.currency_deci_definer : '2'; + + this.payment_tab_data.total_amount = this.commonserv.amountDefiner(this.payment_tab_data.total_amount, this.agency_decimal_definer); + this.payment_tab_data.total_paid_amount = this.commonserv.amountDefiner(this.payment_tab_data.total_paid_amount, this.agency_decimal_definer); + this.payment_tab_data.total_pending_amount = this.commonserv.amountDefiner(this.payment_tab_data.total_pending_amount, this.agency_decimal_definer); + + this.updateAccountingPayForm.get('currency').setValue(this.payment_tab_data.booking_list[0].invoice_currency); + this.updateAccountingPayForm.get('booking_id').setValue(this.payment_tab_data.booking_list[0].booking_id); + this.updateAccountingPayForm.get('pending_amt').setValue(this.payment_tab_data.total_pending_amount); + + if (this.payment_tab_data.booking_list) { + this.payment_tab_data.booking_list.map(x => { + x.invoice_number = x.invoice_number != null && x.invoice_number != '' ? x.invoice_number : 'Pending'; + x.payment_gateway_name = x.payment_gateway_name != null && x.payment_gateway_name != '' ? x.payment_gateway_name : 'NA'; + x.transaction_number = x.transaction_number != null && x.transaction_number != '' ? x.transaction_number : 'NA'; + x.invoice_date_and_time = x.invoice_date_and_time != null ? this.commonserv.UtcToLocaleTime(x.invoice_date_and_time, 'DD MMM YYYY, HH:mm:ss') : 'NA'; + x.invoice_due_date = x.invoice_due_date != null ? this.commonserv.UtcToLocaleTime(x.invoice_due_date, 'DD MMM YYYY, HH:mm:ss') : 'NA'; + x.invoice_paid_amount = this.commonserv.amountDefiner(x.invoice_paid_amount, this.agency_decimal_definer); + x.amount = this.commonserv.amountDefiner(x.amount, this.agency_decimal_definer); + }); + } + } + this.tab_data_status.payment = "success"; + } else { + this.tab_data_status.payment = "failed"; + } + }, (error) => { + this.tab_data_status.payment = "failed"; + }); + } + getDocumentTabDetails() { + this.tab_data_status.document = "loading"; + this.document_tab_data = null; + this.APIServ.getDocumentDetails(this.trip_id).subscribe((data: any) => { + if (data) { + this.document_tab_data = data.filter(x => x.document_number != null && x.document_number != ''); + this.document_tab_data.map(li => { + li.issue_date = this.commonserv.UtcToLocaleTime(li.issue_date, 'DD MMM YYYY, HH:mm:ss') + }) + this.tab_data_status.document = this.document_tab_data ? "success" : "failed"; + } else { + this.tab_data_status.document = "failed"; + } + }, (error) => { + this.tab_data_status.document = "failed"; + }); + } + getBookingNoteDetails() { + this.note_tab_data = null; + this.APIServ.getNotesDetail(this.trip_id).subscribe((data) => { + if (data) { + this.note_tab_data = data; + this.note_tab_data.map(li => { + li.noted_on = this.commonserv.UtcToLocaleTime(li.noted_on, 'DD MMM YYYY, HH:mm:ss') + }) + } + }, (error) => { + }); + } + + getHBookingDetails() { + this.APIServ.getHotelBookingDetail(this.itinerary_tab_data[0].booking_id).subscribe((data) => { + if (!data || !Array.isArray(data) || data.length < 2) { + console.error('Invalid data format:', data); + return; + } + let SuppData = data.filter(li => li.type == 'Supplier')[0] + let AgencyData = data.filter(li => li.type == 'Agency')[0] + const extractRoomData = (roomData) => { + return roomData.rooms.reduce((acc, room) => { + acc.room_names.push(room.roomName); + acc.board_types.push(room.boardType); + acc.guests.push(room.guests); + acc.lead_guest.push(room.leadGuest); + return acc; + }, { + room_names: [], + board_types: [], + guests: [], + lead_guest: [] + }); + }; + + const verificationTabData = extractRoomData(SuppData); + const verificationTabDataMid = extractRoomData(AgencyData); + this.verification_tab_data = { + ...SuppData, + ...verificationTabData + }; + + this.veri_tab_data_mid = { + ...AgencyData, + ...verificationTabDataMid + }; + + const setCancellationCharge = (data) => { + switch (data.cancelType) { + case 'Night': + data.SupCanclCharge = `${data.cancellationCharge} Night`; + data.AgencyCanclCharge = `${data.agentCancellationCharge} Night`; + break; + case 'Percentage': + data.SupCanclCharge = `${data.cancellationCharge} %`; + data.AgencyCanclCharge = `${data.agentCancellationCharge} %`; + break; + case 'Flat': + data.SupCanclCharge = `${data.currency} ${data.cancellationCharge}`; + data.AgencyCanclCharge = `${data.agencyCurrency} ${data.agentCancellationCharge}`; + break; + default: + break; + } + }; + + setCancellationCharge(this.veri_tab_data_mid); + setCancellationCharge(this.verification_tab_data); + if (this.AllCurrency && this.AllCurrency.length > 0 && this.veri_tab_data_mid.currency) { + let obj_currency = this.AllCurrency.find(x => x.currency_code == this.veri_tab_data_mid.currency); + let agnecy_currency = this.AllCurrency.find(x => x.currency_code == this.veri_tab_data_mid.agencyCurrency); + + let amount_format = obj_currency ? obj_currency.amount_format : ""; + let decimal_seperator = obj_currency ? obj_currency.decimal_seperator : ""; + let agnecy_amount_format = obj_currency ? agnecy_currency.amount_format : ""; + let agnecy_decimal_seperator = obj_currency ? agnecy_currency.decimal_seperator : ""; + this.veri_tab_data_mid.supplierAmount = this.commonserv.amountFormater(this.veri_tab_data_mid.supplierAmount, agnecy_amount_format, agnecy_decimal_seperator) + this.veri_tab_data_mid.bookingAmount = this.commonserv.amountFormater(this.veri_tab_data_mid.bookingAmount, agnecy_amount_format, agnecy_decimal_seperator) + this.verification_tab_data.supplierAmount = this.commonserv.amountFormater(this.verification_tab_data.supplierAmount, amount_format, decimal_seperator) + this.verification_tab_data.bookingAmount = this.commonserv.amountFormater(this.verification_tab_data.bookingAmount, amount_format, decimal_seperator) + + } + this.veri_tab_data_mid.isBoardH = JSON.stringify(verificationTabData.board_types) != JSON.stringify(verificationTabDataMid.board_types); + this.veri_tab_data_mid.isRoomH = JSON.stringify(verificationTabData.room_names) != JSON.stringify(verificationTabDataMid.room_names); + this.veri_tab_data_mid.isGuestH = JSON.stringify(verificationTabData.guests) != JSON.stringify(verificationTabDataMid.guests); + this.veri_tab_data_mid.isLeadGH = JSON.stringify(verificationTabData.lead_guest) != JSON.stringify(verificationTabDataMid.lead_guest); + this.veri_tab_data_mid.isSupCanc = new Date(this.verification_tab_data.cancellationDeadline?.hotelCancellationDeadline)?.getTime() < new Date(this.veri_tab_data_mid.cancellationDeadline?.hotelCancellationDeadline)?.getTime(); + this.veri_tab_data_mid.isAgenCanc = new Date(this.verification_tab_data.cancellationDeadline?.utcCancellationDeadline)?.getTime() < new Date(this.veri_tab_data_mid.cancellationDeadline?.utcCancellationDeadline)?.getTime(); + this.veri_tab_data_mid.isInDateH = moment(this.verification_tab_data.checkInDate).format('dd MMM YYYY') != moment(this.veri_tab_data_mid.checkInDate).format('dd MMM YYYY'); + this.veri_tab_data_mid.isOutDateH = moment(this.verification_tab_data.checkOutDate).format('dd MMM YYYY') != moment(this.veri_tab_data_mid.checkOutDate).format('dd MMM YYYY'); + }, (error) => { + console.error('Error fetching hotel booking details:', error); + }); + } + + getCurrencyList(){ + return this.ApiServ.AdminGet("/CurrencyMaster/GetAllCurrencies") + } + + initConfirmationForm(itinerary_data) { + let obj = { + booking_id: itinerary_data != null && itinerary_data.booking_id != null && itinerary_data.booking_id != '' ? itinerary_data.booking_id : "", + // hotel_confirmation_number: itinerary_data != null && itinerary_data.hotel_confirmation_number != null && itinerary_data.hotel_confirmation_number != '' ? itinerary_data.hotel_confirmation_number.split(',') : [], + hotel_confirmation_number_date: itinerary_data != null && itinerary_data.hotel_confirmation_number_date != null && itinerary_data.hotel_confirmation_number_date != '' ? new Date(itinerary_data.hotel_confirmation_number_date) : new Date(), + hotel_confirmation_staff_name: itinerary_data != null && itinerary_data.hotel_confirmation_staff_name != null && itinerary_data.hotel_confirmation_staff_name != '' ? itinerary_data.hotel_confirmation_staff_name : "", + hotel_confirmation_staff_remarks: itinerary_data != null && itinerary_data.hotel_confirmation_staff_remarks != null && itinerary_data.hotel_confirmation_staff_remarks != '' ? itinerary_data.hotel_confirmation_staff_remarks : "", + supplier_confirmation_number: itinerary_data != null && itinerary_data.supplier_confirmation_number != null && itinerary_data.supplier_confirmation_number != '' ? itinerary_data.supplier_confirmation_number : "" + } + this.confirmationForm = this.fb.group({ + booking_id: [obj.booking_id], + // hotel_confirmation_number: [obj.hotel_confirmation_number], + hotel_confirmation_number:this.fb.array([]), + supplier_confirmation_number:[obj.supplier_confirmation_number], + hotel_confirmation_number_date: [obj.hotel_confirmation_number_date], + hotel_confirmation_staff_name: [obj.hotel_confirmation_staff_name], + hotel_confirmation_staff_remarks: [obj.hotel_confirmation_staff_remarks], + }); + let formarray = this.confirmationForm.controls['hotel_confirmation_number'] as FormArray; + if(itinerary_data?.room_list?.length > 0){ + itinerary_data.room_list.forEach(data=>{ + formarray.push( + this.fb.group({ + room_name:data.room_name, + room_id:data.hotel_room_id, + confirmation_no:data.hotel_confirmation_number, + }) + ) + }) + }else if(itinerary_data){ + formarray.push( + this.fb.group({ + room_name:itinerary_data.room_name, + room_id:itinerary_data.hotel_room_id, + confirmation_no:itinerary_data.hotel_confirmation_number, + }) + ) + } + } + + // open(content: any) { + // this.modalReference = this.modalService + // .open(content, { ariaLabelledBy: "" }) + // .result.then( + // (result) => { + // this.closeResult = `Closed with: ${result}`; + // }, + // (reason) => { + // this.closeResult = `Dismissed ${this.getDismissReason(reason)}`; + // } + // ); + // } + openConfirmationNumberModal(content: any, itinerary_data) { + this.initConfirmationForm(itinerary_data); + this.isOpenAddConfirmationNumberModal = true; + } + openVendorInvoiceNumberModal(id,invoice) { + this.isOpenAddVendorInvoiceNumberModal = true; + this.VendorInvoiceForm = this.fb.group({ + booking_id:id, + vendor_invoice_number:[invoice,Validators.compose([Validators.required])] + }) + } + saveConfirmationNumber() { + let obj = this.confirmationForm.value; + let postdata = { + booking_id:obj.booking_id, + supplier_confirmation_number:obj.supplier_confirmation_number, + hotel_confirmation_number_date:obj.hotel_confirmation_number_date, + hotel_confirmation_staff_name:obj.hotel_confirmation_staff_name, + hotel_confirmation_staff_remarks:obj.hotel_confirmation_staff_remarks, + hotel_rooms:[] + } + let hotel_confirm_number = []; + obj.hotel_confirmation_number.forEach(data=>{ + hotel_confirm_number.push( + { + hotel_room_id:data.room_id, + hotel_confirmation_number:data.confirmation_no + } + ); + }) + postdata.hotel_rooms = hotel_confirm_number; + this.APIServ.saveConfirmationNumber(postdata).subscribe((data) => { + if(data?.resp){ + this.isOpenAddConfirmationNumberModal = false; + if(this.active_tab == 2){ + this.getCostingTabDetails(); + }else { + this.getItineraryTabDetails(); + } + } + }); + } + saveNotes() { + if (this.notesform.status == 'INVALID') { + this.validationServ.showValidationsMsg(this.notesform); + return; + } + let obj = { + booking_refrence_number: this.trip_id, + booking_notes_free_text: this.notesform.get('Note').value, + }; + this.APIServ.saveNotesDetail(obj).subscribe((data) => { + if (data) { + this.getBookingNoteDetails(); + this.commonserv.showMessage(data["resp"], data["respMsg"]); + // this.modalService.dismissAll(); + } else { + this.commonserv.showMessage(data["resp"], data["respMsg"]); + } + this.isOpenAddNote = false; + }); + } + + getPriceDetailType(breakupDetails, priceType) { + try { + let price = breakupDetails.PriceDetails.filter( + (el) => el.PriceDetailType == priceType + )[0].Price; + return price; + } catch { + return 0; + } + } + + + map_booking_status(booking_status, payment_status) { + if (booking_status != null) { + if (booking_status == 3) { + return 'Confirmed'; + } + else if (booking_status == 4) { + return 'Cancelled'; + } + else if ((booking_status == 0 || booking_status == 2) && payment_status != null) { + return 'Pending'; + } + else if (booking_status == 6) { + return 'Reserved'; + } + else { + return 'In Progress'; + } + } else { + return 'In Progress'; + } + } + map_room_status(status) { + if (status != null) { + switch (status) { + case '0': { + return 'In Progress'; + } + case '2': { + return 'Failed'; + } + case '3': { + return 'Confirmed'; + } + case '4': { + return 'Cancelled'; + } + case '6': { + return 'Reserved'; + } + default: { + return 'In Progress'; + } + } + } else { + return 'In Progress'; + } + } + map_payment_status(status, is_authorised) { + if (status != null && status != "") { + switch (status) { + case "PAID": { + return is_authorised ? 'Paid (Authorized)' : 'Paid'; + } + case "PENDING": { + return 'Pending'; + } + case "FAILED": { + return 'Failed'; + } + case "PARTLYPAID": { + return 'Partly Paid'; + } + default :{ + return 'Not Attempt'; + } + } + } else { + return 'Not Attempt'; + } + } + + // + // + // + displayModal: boolean; + + displayBasic: boolean; + + displayBasic2: boolean; + + bookingIdIndex = 0; + + displayMaximizable: boolean; + + displayPosition: boolean; + + position: string; + + isOpenSendEmailModal: boolean = false; + isOpenAddBookingCancelModal: boolean = false; + selectedItinerary = []; + showModalDialog() { + this.displayModal = true; + } + bookingHistoryModal() { + this.bookingHistory = true; + } + bookingIdModal() { + this.bookingDetails = true; + } + ReleaseModalBtn(ind) { + this.ReleaseModal = true; + this.bookingIdIndex = ind; + } + closeModalBtn() { + this.ReleaseModal = false; + } + closeAccountPayStatusBtn() { + this.UpdAccountPayStatus = false; + } + closeUpdateAccountingInvoice() { + this.UpdateInStatus = false; +} + UpdateAccountingInvoice() { + this.UpdateInStatus = true; + } + UpdAccountPayStatusBtn() { + this.UpdAccountPayStatus = true; + } + rateBreakupModal(obj_booking) { + let obj = []; + if (obj_booking.room_rate_list != null) { + obj_booking.room_rate_list.map(room => { + obj.push({ + room_name: room.room_name, + nightly_rate: room.nightly_rate != null ? this.mapNightlyRate(JSON.parse(room.nightly_rate)) : null + }); + }); + } + this.supplierNightlyRate = obj; + console.log(this.supplierNightlyRate); + this.rateBreakup = true; + } + mapNightlyRate(nightly_rate) { + let obj = []; + nightly_rate.map(rate => { + let obj_base_price = rate.PriceDetails.find(x => x.PriceDetailType == 'BasePrice'); + let obj_agency_currency = this.currency_list.find(x => x.currency_code == obj_base_price.Currency); + let agency_decimal_definer = obj_agency_currency ? obj_agency_currency.currency_deci_definer : '2'; + + let obj_supplier_currency = this.currency_list.find(x => x.currency_code == obj_base_price.SourceCurrency); + let supplier_decimal_definer = obj_supplier_currency ? obj_supplier_currency.currency_deci_definer : '2'; + obj.push({ + date: rate.date, + supplier_currency: obj_base_price.SourceCurrency, + supplier_amount: this.commonserv.amountDefiner(obj_base_price.PriceInSourceCurrency, supplier_decimal_definer), + roe: this.commonserv.amountDefiner(obj_base_price.ExchangeRate, agency_decimal_definer), + agency_currency: obj_base_price.Currency, + base_price: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "BasePrice"), agency_decimal_definer), + markup_surcharge_amount: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "Surcharge"), agency_decimal_definer), + // discount_surcharge_amount: this.commonserv.amountDefiner(rate.discount_surcharge_amount, agency_decimal_definer), + markup_amount: this.commonserv.amountDefiner(((this.getPriceDetailType(rate, "Markup") * 10000000) + (this.getPriceDetailType(rate, "AdditionalMarkUpPrice") * 10000000)) / 10000000, agency_decimal_definer), + transaction_fee: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "TransactionFee"), agency_decimal_definer), + discount: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "Discount"), agency_decimal_definer), + input_tax: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "InputTax"), agency_decimal_definer), + output_tax: this.commonserv.amountDefiner(this.getPriceDetailType(rate, "OutputTax"), agency_decimal_definer), + total: this.commonserv.amountDefiner(rate.net, agency_decimal_definer), + }); + }); + return obj; + } + showBasicDialog() { + this.displayBasic = true; + } + + showBasicDialog2() { + this.displayBasic2 = true; + } + + showMaximizableDialog() { + this.displayMaximizable = true; + } + + showPositionDialog(position: string) { + this.position = position; + this.displayPosition = true; + } + back_to_listing() { + this.router.navigate(['/BookingManagement/HotelBooking/Search']); + } + // add required validtion + // updated by Abdul Razzak on 13 mar 2024 + //updated by Arfat Qureshi on 18 mar 2024, added language and whatsapp property in send mail pop up + openSendEmailModal(document_number, document_type) { + this.mailForm = this.fb.group({ + document_number: [document_number], + document_type: [document_type], + email_id: this.validationServ.email, + languageId: document_type == 'Itinerary' ? this.validationServ.required : '', + is_wapp : false + }); + //set the default email Id of user in the send mail field + if(this.booking_customer_data){ + this.mailForm.get('email_id').setValue(this.booking_customer_data['guest_email_address']); + } + this.selected__mail_document_type = document_type; + this.isOpenSendEmailModal = true; + } + openSendAddNote() { + this.isOpenAddNote = true; + this.notesform.reset(); + this.notesform.markAsUntouched(); + } + OpenCancellationPolicyModal(itinerary, isOpen) { + try { + console.log(itinerary); + let cancellation_policy = itinerary.cancellation_policy; + //let cancellation_policy = [{ "from_type": "supplier", "room_name": "Double room ? Disability access", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398246022", "no_of_rooms": 1 }, { "from_type": "supplier", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398247445", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398247445", "no_of_rooms": 1 }, { "from_type": "supplier", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398248361", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "Double room ? Disability access", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398246022", "no_of_rooms": 1 }, { "from_type": "supplier", "room_name": "Double room ? Disability access", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398246022", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 2, "deadline_date_from": "2022-09-21", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-25", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 100, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398248361", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398248361", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "Double room ? Disability access", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398246022", "no_of_rooms": 1 }, { "from_type": "supplier", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398248361", "no_of_rooms": 1 }, { "from_type": "supplier", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398247445", "no_of_rooms": 1 }, { "from_type": "agent", "room_name": "DOUBLE STANDARD", "cancellation_policy_text": null, "sequence_no": 1, "deadline_date_from": "2022-08-22", "deadline_time_from": "00:00:00", "deadline_date_to": "2022-09-21", "deadline_time_to": "00:00:00", "currency": "USD", "amount": 0, "is_roomwise_policy": true, "format_type": "Flat", "hotel_room_details_id": "2208231504398247445", "no_of_rooms": 1 }]; + //let cancellation_policy = [{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218409642","no_of_rooms":1},{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218410665","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218409642","no_of_rooms":1},{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218409642","no_of_rooms":1},{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218408033","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218410665","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218409642","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218408033","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218408033","no_of_rooms":1},{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":1,"deadline_date_from":"2022-08-22","deadline_time_from":null,"deadline_date_to":"2022-08-29","deadline_time_to":null,"currency":"USD","amount":0,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218408033","no_of_rooms":1},{"from_type":"supplier","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218410665","no_of_rooms":1},{"from_type":"agent","room_name":"Standard Double Room,1 King Bed","cancellation_policy_text":null,"sequence_no":2,"deadline_date_from":"2022-08-29","deadline_time_from":null,"deadline_date_to":"2022-09-13","deadline_time_to":null,"currency":"USD","amount":100,"is_roomwise_policy":false,"format_type":"Percentage","hotel_room_details_id":"2208231413218410665","no_of_rooms":1}]; + console.log(cancellation_policy); + let room_list = []; + if (cancellation_policy) { + if (cancellation_policy.some(x => x.is_roomwise_policy)) { + this.is_roomwise_policy = true; + let room_group_list = _.groupBy(cancellation_policy, function (d) { return d.hotel_room_details_id; }); + for (let item in room_group_list) { + let selected_room = room_group_list[item]; + + let agent_cancellation_policy = selected_room.filter(x => x.from_type == 'agent').sort(function (a, b) { return a.sequence_no - b.sequence_no }); + let supplier_cancellation_policy = selected_room.filter(x => x.from_type == 'supplier').sort(function (a, b) { return a.sequence_no - b.sequence_no }); + + for (let index = 0; index < selected_room[0].no_of_rooms; index++) { + room_list.push({ + room_name: selected_room[0].room_name, + timezone: cancellation_policy[0].timezone, + agent_cancellation_policy: this.mapCancellationPolicy(agent_cancellation_policy), + supplier_cancellation_policy: this.mapCancellationPolicy(supplier_cancellation_policy) + }); + } + } + } else { + this.is_roomwise_policy = false; + let room_group_list = _.groupBy(cancellation_policy, function (d) { return d.hotel_room_details_id; }); + for (let item in room_group_list) { + let selected_room = room_group_list[item]; + let agent_cancellation_policy = selected_room.filter(x => x.from_type == 'agent').sort(function (a, b) { return a.sequence_no - b.sequence_no }); + let supplier_cancellation_policy = selected_room.filter(x => x.from_type == 'supplier').sort(function (a, b) { return a.sequence_no - b.sequence_no }); + room_list.push({ + room_name: cancellation_policy[0].room_name, + timezone: cancellation_policy[0].timezone, + agent_cancellation_policy: this.mapCancellationPolicy(agent_cancellation_policy), + supplier_cancellation_policy: this.mapCancellationPolicy(supplier_cancellation_policy) + }); + break; + } + } + } + this.selectedItinerary = room_list; + } catch { + this.selectedItinerary = []; + } + isOpen ? this.isOpenCancellationPolicyModal = true : ''; + } + mapCancellationPolicy(cancellation_policy) { + let resp = []; + cancellation_policy.map(item => { + if (item.format_type == 'Percentage' || item.format_type == 'Flat' || item.format_type == 'Night' || item.format_type == 'Nights') { + let obj_currency = item.format_type == 'Flat' && item.currency != null && item.currency != '' ? this.currency_list.find(x => x.currency_code == item.currency) : null; + let decimal_definer = obj_currency ? obj_currency.currency_deci_definer : '2'; + resp.push({ + from_date: (item.format_type == 'Percentage' || item.format_type == 'Flat' || item.format_type == 'Night' || item.format_type == 'Nights') && item.deadline_date_from != null && item.deadline_date_from != '' ? moment(item.deadline_date_from).format('DD MMM YYYY hh:mm A') : '', + to_date: (item.format_type == 'Percentage' || item.format_type == 'Flat' || item.format_type == 'Night' || item.format_type == 'Nights') && item.deadline_date_to != null && item.deadline_date_to != '' ? moment(item.deadline_date_to).format('DD MMM YYYY hh:mm A') : '', + from_time: (item.format_type == 'Percentage' || item.format_type == 'Flat'|| item.format_type == 'Night' || item.format_type == 'Nights') ? this.commonserv.UtcToLocaleTime(item.deadline_time_from,'hh:mm a') : '', + to_time: (item.format_type == 'Percentage' || item.format_type == 'Flat' || item.format_type == 'Night' || item.format_type == 'Nights') ? this.commonserv.UtcToLocaleTime(item.deadline_time_to, 'hh:mm a') : '', + text: item.cancellation_policy_text, + format_type: item.format_type, + timezone: item.timezone, + currency: this.getFormatType(item), + amount: item.format_type == 'Flat' ? this.commonserv.amountDefiner(item.amount, decimal_definer) : parseInt(item.amount) + }); + } else { + resp.push({ + from_date: '', + to_date: '', + from_time: '', + to_time: '', + text: item.cancellation_policy_text, + format_type: 'Text', + currency: '', + amount: '' + }); + } + }); + + return { + format_type: cancellation_policy[0].format_type, + policy: resp, + } + } + IsEmailLoader = false; + + getFormatType(item) { + let type = ''; + if(item.format_type == 'Flat') { + type = item.currency; + }else if(item.format_type == 'Percentage') { + type = '%'; + }else if(item.format_type == 'Night' || item.format_type == 'Nights') { + let night = parseInt(item.amount); + if(night > 1) type = 'Nights'; + else type = 'Night'; + } + return type; + } + // updated by Abdul Razzak on 13 mar 2024 + sendDocumentMail() { + this.IsEmailLoader = true; + let formData = this.mailForm.value; + + if (this.mailForm.status == 'INVALID') { + this.validationServ.showValidationsMsg(this.mailForm); + this.IsEmailLoader = false; + return; + } + let url = ''; + if (formData.document_type == 'Itinerary') { + let itineraryReqObj = { + "BookingRefNo": this.trip_id, + "CustomEmail": formData.email_id, + "isB2B": false, + "autoTrigger": false, + "languageId": formData.languageId + }; + this.APIServ.sendItineraryDocumentMail(itineraryReqObj).subscribe((data: any) => { + if (data) { + this.IsEmailLoader = false; + if (data.resp) { + this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Itinerary sent to your mail id' }); + this.isOpenSendEmailModal = false; + } else { + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + } + } + }, (error) => { + this.IsEmailLoader = false; + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + this.isOpenSendEmailModal = false; + }); + } else if (formData.document_type == 'Invoice') { + this.APIServ.sendInvoiceDocumentMail(formData.document_number, formData.email_id).subscribe((data: any) => { + if (data) { + this.IsEmailLoader = false; + if (data.resp) { + this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Invoice sent to your mail id' }); + this.isOpenSendEmailModal = false; + } else { + this.IsEmailLoader = false; + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + } + } + }, (error) => { + this.IsEmailLoader = false; + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + this.isOpenSendEmailModal = false; + }); + } else if (formData.document_type == 'Voucher') { + let ReqObj = { + "BookingRefNo": this.trip_id, + "CustomEmail": formData.email_id, + "isB2B": false, + "autoTrigger": false, + "languageId": formData.languageId + }; + this.APIServ.sendVoucherDocumentMail(ReqObj).subscribe((data: any) => { + if (data) { + this.IsEmailLoader = false; + if (data.resp) { + this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Voucher sent to your mail id' }); + this.isOpenSendEmailModal = false; + } else { + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + } + } + }, (error) => { + this.IsEmailLoader = false; + this.messageService.add({ severity: 'error', summary: 'Failed', detail: 'Internal server error' }); + this.isOpenSendEmailModal = false; + }); + } + + } + + + updateStatus(BookingId, ind) { + if (this.statusArr.controls[ind].status == 'INVALID') { + this.validationServ.showValidationsMsg(this.statusArr.controls[ind]); + return; + }; + let val = this.StatusGroup.get('statusArr').value; + let hotelBookingModify = { + booking_id: BookingId, + status_id: val[ind].status + }; + this.APIServ.UpdateBooking(hotelBookingModify).subscribe((res) => { + if (res) { + this.messageService.add({ + severity: res['resp'] ? 'success' : 'error', + detail: res['respMsg'], + }); + this.dialogStatus[ind] = false; + this.getItineraryTabDetails(); + } + }); + }; + + closeCancelDialog() { + this.checkBookingCancel = false; + this.isOpenAddBookingCancelModal = false; + } + + //Standalone features + featureList = { + FC_64 :false, + FC_81 :false, + FC_85 :false, + } + getFeatures(pageId) { + this.ApiServ.AdminGet("/MenuMasterNew/GetAllFeatureCode/2110180851430030870/" + pageId).subscribe(res => { + this.features = res; + if (this.features && this.features.length > 0) { + this.features.forEach(e => { + if (this.featureList[e.feature_code] === false) this.featureList[e.feature_code] = true; + }); + }; + }) + } + + checkFeature(f_Code) { + return this.features.some(z => z.feature_code == f_Code); + } + + //Created by Arfat Qureshi Get all langugae by OrgId + GetAllLAng(){ + return this.ApiServ.AdminGet('/LanguageMapping/GetLanguagesByOrgId') + } + SaveInvoiceNumber(){ + if(this.VendorInvoiceForm.status == 'VALID'){ + let val = this.VendorInvoiceForm.getRawValue(); + let obj = { + booking_id: val.booking_id, + vendor_invoice_number: val.vendor_invoice_number, + }; + this.ApiServ.AdminGoPost('/Invoice/UpdateInvoiceVendor',obj).subscribe(data=>{ + if(data){ + this.commonserv.showMessage(data['Resp'],data['Message']); + if(data.Resp){ + this.isOpenAddVendorInvoiceNumberModal = false; + this.getCostingTabDetails(); + } + } + }) + }else { + this.VendorInvoiceForm.markAsTouched(); + } + } +} diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking.component.html b/src/app/modules/booking-management/hotel-booking/hotel-booking.component.html new file mode 100644 index 0000000..4541678 --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking.component.ts b/src/app/modules/booking-management/hotel-booking/hotel-booking.component.ts new file mode 100644 index 0000000..c35bbde --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-hotel-booking', + templateUrl: './hotel-booking.component.html', +}) +export class HotelBookingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/booking-management/hotel-booking/hotel-booking.module.ts b/src/app/modules/booking-management/hotel-booking/hotel-booking.module.ts new file mode 100644 index 0000000..0f05846 --- /dev/null +++ b/src/app/modules/booking-management/hotel-booking/hotel-booking.module.ts @@ -0,0 +1,73 @@ +import { InputMaskModule } from 'primeng/inputmask'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatTabsModule } from '@angular/material/tabs'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { CalendarModule } from 'primeng/calendar'; +import { DialogModule } from 'primeng/dialog'; +import { TableModule } from "primeng/table"; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { InputTextModule } from "primeng/inputtext"; +import { RippleModule } from 'primeng/ripple'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from "primeng/toolbar"; +import { ConfirmationService, MessageService } from 'primeng/api'; +import { HotelBookingSearchComponent } from './hotel-booking-search/hotel-booking-search.component'; +import { HotelBookingComponent } from './hotel-booking.component'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { TreeModule } from 'primeng/tree'; +import { RatingModule } from 'primeng/rating'; +import { HotelBookingViewComponent } from './hotel-booking-view/hotel-booking-view.component'; +import { TabViewModule } from 'primeng/tabview'; +import { MatButtonModule } from '@angular/material/button'; +import { HotelBookingManagementService } from 'src/app/core/services/HotelServices/hotel_booking_management.service'; +// +const routes: Routes = [ + { + path: 'Search', + component: HotelBookingSearchComponent, + }, + { + path: 'View', + component: HotelBookingViewComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; +@NgModule({ + declarations: [HotelBookingComponent, HotelBookingSearchComponent,HotelBookingViewComponent], + imports: [ + CommonModule, + NgSelectModule, + FormsModule, + ReactiveFormsModule, + CalendarModule, + InputTextModule, + InputNumberModule, + TreeModule, + RatingModule, + ButtonModule, + ToolbarModule, + InputMaskModule, + MatCheckboxModule, + TableModule, + // angular material + DialogModule, + RippleModule, + ToastModule, + TabViewModule, + MatMenuModule, + MatTabsModule, + MatButtonModule, + RouterModule.forChild(routes), + ], + providers: [ MessageService, ConfirmationService, HotelBookingManagementService], +}) +export class HotelBookingModule {} diff --git a/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.html b/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.html new file mode 100644 index 0000000..7dd7b74 --- /dev/null +++ b/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.html @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.ts b/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.ts new file mode 100644 index 0000000..23faab3 --- /dev/null +++ b/src/app/modules/common/custom-sidebar/custom-sidebar-item/custom-sidebar-item.component.ts @@ -0,0 +1,38 @@ +import { trigger, state, style, transition, animate } from '@angular/animations'; +import { Component, Input } from '@angular/core'; +import { ActiveSidebarService } from 'src/app/core/services/active-sidebar.service'; + +@Component({ + selector: 'custom-sidebar-item', + templateUrl: './custom-sidebar-item.component.html', + animations: [ + trigger('submenuAnimation', [ + state('closed', style({ + height: '0px', + opacity: 0, + overflow: 'hidden', + })), + state('open', style({ + height: '*', + opacity: 1, + overflow: 'hidden', + })), + transition('closed => open', [ + animate('300ms ease-in-out') + ]), + transition('open => closed', [ + animate('200ms ease-in-out') + ]) + ]) + ] +}) +export class CustomSidebarItemComponent { + @Input() menuItems: any[] = []; // Input for the nested menu items + @Input() isMobile: boolean = false; // Input for the nested menu items + + constructor(public checkSidebar: ActiveSidebarService) { } + + toggleSubMenu(item: any) { + item.expanded = !item.expanded; // Toggle the 'isOpen' property + } +} diff --git a/src/app/modules/common/custom-sidebar/custom-sidebar.component.html b/src/app/modules/common/custom-sidebar/custom-sidebar.component.html new file mode 100644 index 0000000..64af185 --- /dev/null +++ b/src/app/modules/common/custom-sidebar/custom-sidebar.component.html @@ -0,0 +1,48 @@ +
    + +
    + + + + + + + + + + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/common/custom-sidebar/custom-sidebar.component.ts b/src/app/modules/common/custom-sidebar/custom-sidebar.component.ts new file mode 100644 index 0000000..cd01bad --- /dev/null +++ b/src/app/modules/common/custom-sidebar/custom-sidebar.component.ts @@ -0,0 +1,212 @@ +import { ChangeDetectorRef, Component, ElementRef, Renderer2, ViewChild } from '@angular/core'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ActiveSidebarService } from 'src/app/core/services/active-sidebar.service'; +import { API } from 'src/app/core/services/api.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; +import { MenuItem } from 'primeng/api'; +import { securityFunctions } from 'src/app/core/common/security'; +import { trigger, state, style, transition, animate } from '@angular/animations'; +import { filter } from 'rxjs'; +import { NavigationEnd, Router } from '@angular/router'; + +@Component({ + selector: 'custom-sidebar', + templateUrl: './custom-sidebar.component.html', + animations: [ + trigger('submenuAnimation', [ + state('closed', style({ + height: '0px', + opacity: 0, + overflow: 'hidden', + })), + state('open', style({ + height: '*', + opacity: 1, + overflow: 'hidden', + })), + transition('closed => open', [ + animate('300ms ease-in-out') + ]), + transition('open => closed', [ + animate('200ms ease-in-out') + ]) + ]) + ] +}) +export class CustomSidebarComponent { + @ViewChild('logoImage') logoImage: ElementRef; + flag: boolean = true; + // mobile resposive start + isMobile = false; + // mobile resposive end + constructor( + public ChcekSidebar: ActiveSidebarService, + public MobileBreakpoints: BreakpointsService, + private cd: ChangeDetectorRef, // mobile resposive end, + private ApiSer: API, + public commonF: CommonFunctionService, + private renderer: Renderer2, + public router: Router + ) { + // mobile resposive start + this.MobileBreakpoints.IsMobile.subscribe({ + next: (val) => { + this.isMobile = val; + }, + }); + // mobile resposive end + } + + asideItems!: MenuItem[]; + ngOnInit(): void { + this.isMobile == true + ? (this.ChcekSidebar.activeSide = '') + : (this.ChcekSidebar.activeSide = 'IsActive'); + this.getMenus().subscribe(res => { + if (res) { + this.commonF.CheckActiveTabMenus(res); + this.BindMenu(res); + const currentUrl = this.router.url; + this.expandAndActivateRecursive(this.asideItems, currentUrl, true); + } + }) + this.router.events + .pipe(filter(event => event instanceof NavigationEnd)) // Filter to get NavigationEnd event + .subscribe((data) => { + this.resetMenuItems(this.asideItems); + // this.expandAndActivateRecursive(this.asideItems, this.router.url, true); + }); + this.cd.detectChanges(); + + } + getMenuss() { + let LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null; + return this.ApiSer.AdminGet(`/MenuMasterNew/GetMenuMasterNewsByOrgId/2405170833594899108/${LoginUserData.user_id}`) + } + getMenus() { + let LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null; + return this.ApiSer.AdminGet('/MenuMasterNew/GetAllMenuByUserId/' + LoginUserData.user_id + '/2405170833594899108') + } + BindMenu(list) { + let aisemenu = []; + let FliterList = list.sort(function (a, b) { return a.sequence - b.sequence; }); + let AllParentlist = list.filter(e => e.parent_id == ''); + AllParentlist.forEach(e => { + if (e.menu_type == '2305170833594899101' && !e.is_tab_wise_menu) { + aisemenu.push({ + label: e.menu_name, + icon: e.ng_icon == null ? 'pi pi-fw pi-pencil' : '' + e.ng_icon, + items: [] + }); + } else if (!e.is_hide_in_side_menu) { + aisemenu.push({ label: e.menu_name, icon: ' ', page_data: e.page_data ? JSON.parse(e.page_data) : [], routerLink: '/' + e.ui_controller + '/' + e.ui_action, command: (event) => { this.isMobile ? this.ChcekSidebar.SideBar('IsActive') : '' } }); + } + let index = aisemenu.length - 1; + let submenu = FliterList.filter(s => s.parent_id == e.menu_id); + if (submenu.length > 0) { + this.subMenu(aisemenu[index], submenu, FliterList); + } + }); + this.asideItems = aisemenu; + }; + + subMenu(menu, FilterSubmenu, Allmenu) { + if (FilterSubmenu.length > 0) { + FilterSubmenu.forEach(e => { + if (e.menu_type == '2305170833594899101' && !e.is_tab_wise_menu) { + menu.items.push({ + label: e.menu_name, + icon: 'pi pi-fw pi-pencil', + items: [] + }); + } else if (!e.is_hide_in_side_menu) { + menu.items.push( + { label: e.menu_name, icon: ' ', page_data: e.page_data ? JSON.parse(e.page_data) : [], routerLink: '/' + e.ui_controller + '/' + e.ui_action, command: (event) => { this.isMobile ? this.ChcekSidebar.SideBar('IsActive') : '' } } + ); + } + let index = menu.items.length - 1; + let submenu = Allmenu.filter(a => a.parent_id == e.menu_id && !e.is_tab_wise_menu); + if (submenu.length > 0) { + this.subMenu(menu.items[index], submenu, Allmenu); + } + }); + }; + }; + headerHeight; // Default height + isHeightSet: boolean = false; // Flag to check if actual height is set + adjustHeaderSize() { + requestAnimationFrame(() => { + this.headerHeight = this.commonF.getHeaderSize(this.logoImage); + if (this.headerHeight > 0) { // Check if the height is valid + this.isHeightSet = true; + } + this.cd.detectChanges(); // Trigger change detection + }); + } + + toggleSubMenu(selectedItem: any) { + this.asideItems.forEach(item => item.expanded = item.label === selectedItem.label ? !item.expanded : false); + } + + private expandAndActivateRecursive(items: MenuItem[], targetUrl: string, isBeforeActive: boolean = true): boolean { + let menu = true; + if (items) { + for (const [i, item] of items.entries()) { + if (item.routerLink) { + if (item['page_data'].some(z => targetUrl.includes(z.page_url.replaceAll('/$', '')))) { + item.expanded = true; + item.styleClass = 'SidebarMenulink'; + menu = false; + for (let ind = i + 1; ind < items.length; ind++) { + if (items[ind].items) { + items[ind].items.forEach(sub_item => sub_item.styleClass = '') + } + } + return true; + } + } else if (item.items) { + if (this.expandAndActivateRecursive(item.items, targetUrl, isBeforeActive)) { + item.expanded = true; + item.styleClass = 'parent-menu-active'; + for (let ind = i + 1; ind < items.length; ind++) { + if (items[ind].items) { + items[ind].items.forEach(sub_item => sub_item.styleClass = '') + } + } + // this.RemoveSubmenuActive(items,index+1); + return true; + } else { + item.styleClass = ''; + } + } + if (menu) { + item.styleClass = 'submenu-before-active'; + } + } + } + // Get the active panel (the expanded one) + const activePanel = document.querySelector('.menu'); + const selected_panel = activePanel.querySelector('.active-panel') + selected_panel?.classList.remove("active-panel") + const panel = activePanel.querySelector('.p-highlight')?.closest('.p-panelmenu-panel'); + + // Add 'active-panel' class to the currently active panel + if (panel) { + this.renderer.addClass(panel, 'active-panel'); + } + return false; + } + private resetMenuItems(items: MenuItem[]) { + if (items) { + for (const [index, item] of items.entries()) { + item.expanded = false; + item.expanded = false; // Reset expanded state + item.styleClass = ''; // Clear any existing style classes + if (item.items) { + this.resetMenuItems(item.items); // Recursively reset child items + } + } + this.expandAndActivateRecursive(items, this.router.url, true) + } + } +} diff --git a/src/app/modules/common/footer/footer.component.html b/src/app/modules/common/footer/footer.component.html new file mode 100644 index 0000000..9ab27b9 --- /dev/null +++ b/src/app/modules/common/footer/footer.component.html @@ -0,0 +1,7 @@ + diff --git a/src/app/modules/common/footer/footer.component.ts b/src/app/modules/common/footer/footer.component.ts new file mode 100644 index 0000000..9e8f65a --- /dev/null +++ b/src/app/modules/common/footer/footer.component.ts @@ -0,0 +1,24 @@ +import { Component } from "@angular/core"; +import * as moment from "moment"; +import { securityFunctions } from "src/app/core/common/security"; + +@Component({ + templateUrl: './footer.component.html', + selector: 'app-footer' +}) +export class FooterComponent { + date; + venderGroupName = ''; + ngOnInit(): void { + this.getyear(); + } + agencyData + getyear() { + const d = new Date(); + this.date = moment(d).format('YYYY'); + this.agencyData = securityFunctions.getSessionStorage('VData'); + if (this.agencyData) { + this.venderGroupName = JSON.parse(this.agencyData).vendor_group_name; + } + }; +} \ No newline at end of file diff --git a/src/app/modules/common/header/header.component.html b/src/app/modules/common/header/header.component.html new file mode 100644 index 0000000..19b53cb --- /dev/null +++ b/src/app/modules/common/header/header.component.html @@ -0,0 +1,119 @@ +
    + +
    + + + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/common/header/header.component.ts b/src/app/modules/common/header/header.component.ts new file mode 100644 index 0000000..270c0fa --- /dev/null +++ b/src/app/modules/common/header/header.component.ts @@ -0,0 +1,127 @@ +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { ChangeDetectorRef, Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { PrimeNGConfig } from 'primeng/api'; +import { Subject, takeUntil } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ActiveSidebarService } from 'src/app/core/services/active-sidebar.service'; +import { API } from 'src/app/core/services/api.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; + +@Component({ + templateUrl: './header.component.html', + selector: 'app-header', +}) +export class HeaderComponent implements OnInit { + @ViewChild('logoImage') logoImage: ElementRef; + + isMobile!: boolean; + destroyed = new Subject(); + MobileShow = true; + MobileHide = true; + topBarMenu = false; + activeAside; + + constructor( + public ChcekSidebar: ActiveSidebarService, + // mobile resposive start + breakpointObserver: BreakpointObserver, + public MobileBreakpoints: BreakpointsService, + private cd: ChangeDetectorRef, + public commonF: CommonFunctionService, + private ApiSer: API, + private renderer: Renderer2, + public titleService: Title + // mobile resposive end + ) { + // mobile resposive start + this.MobileBreakpoints.IsMobile.subscribe({ + next: (val) => { + this.isMobile = val; + }, + }); + breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]) + .pipe(takeUntil(this.destroyed)) + .subscribe((result) => { + if ( + result.breakpoints["(max-width: 599.98px)"] || + result.breakpoints["(min-width: 600px) and (max-width: 959.98px)"] + ) { + this.isMobile = true; + this.MobileShow = true; + this.MobileHide = false; + } else { + this.isMobile = false; + this.MobileShow = false; + this.MobileHide = true; + } + }); + // mobile resposive end + } + + // topBar() { + // this.ChcekSidebartopBarMenu = !this.topBarMenu; + // } + userName; + lastLogin; + ngOnInit(): void { + this.userName = sessionStorage.getItem('userName') + this.lastLogin = sessionStorage.getItem('lastLogin'); + this.isMobile == true + ? (this.ChcekSidebar.activeSide = '') : (this.ChcekSidebar.activeSide = 'IsActive'); this.cd.detectChanges(); + if (sessionStorage.getItem("logo")) { + const favicon = document.getElementById('favIcon') as HTMLLinkElement; + let res = JSON.parse(sessionStorage.getItem("logo")); + if (res != null) if (res["logo"] != null) { + this.orgLogo = res["logo"]; + this.commonF.logo = this.orgLogo + sessionStorage.setItem("logo", JSON.stringify(res)); + this.titleService.setTitle('Inventory Management | ' + res.org_name) + document.documentElement.style.setProperty('--primary-theme', res['primary_color']); + document.documentElement.style.setProperty('--secondary-theme', res['secondary_color']); + this.renderer.setAttribute(favicon, 'href', res['favicon'] ? res['favicon'] : './assets/images/TMC.svg'); + } else { + this.orgLogo = "https://cdn-aos.b-cdn.net/Static/Email/TMC.svg"; + this.commonF.logo = this.orgLogo + } + } else { + this.getLogo() + } + + } + orgLogo + getLogo() { + const favicon = this.renderer.selectRootElement('link[rel="icon"]', true); + this.ApiSer.AdminGet('/ForgotPassword/GetOrgLogo').subscribe((res) => { + if (res != null) if (res["logo"] != null) { + this.orgLogo = res["logo"]; + this.commonF.logo = this.orgLogo + sessionStorage.setItem("logo", JSON.stringify(res)); + this.titleService.setTitle('Inventory Management | ' + res.org_name) + document.documentElement.style.setProperty('--primary-theme', res['primary_color']); + document.documentElement.style.setProperty('--secondary-theme', res['secondary_color']); + this.renderer.setAttribute(favicon, 'href', res['favicon'] ? res['favicon'] : './assets/images/TMC.svg'); + } else { + this.orgLogo = "https://cdn-aos.b-cdn.net/Static/Email/TMC.svg"; + this.commonF.logo = this.orgLogo + } + }) + } + asideBar(ele) { + this.activeAside = ele; + } + topBar() { + this.topBarMenu = !this.topBarMenu; + } + headerHeight; // Default height + isHeightSet: boolean = false; // Flag to check if actual height is set + adjustHeaderSize() { + requestAnimationFrame(() => { + this.headerHeight = this.commonF.getHeaderSize(this.logoImage); + if (this.headerHeight > 0) { // Check if the height is valid + this.isHeightSet = true; + } + this.cd.detectChanges(); // Trigger change detection + }); +} +} diff --git a/src/app/modules/common/sidebar/sidebar.component.html b/src/app/modules/common/sidebar/sidebar.component.html new file mode 100644 index 0000000..df8a1fb --- /dev/null +++ b/src/app/modules/common/sidebar/sidebar.component.html @@ -0,0 +1,37 @@ +
    +
    +
    + +
    + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/src/app/modules/common/sidebar/sidebar.component.ts b/src/app/modules/common/sidebar/sidebar.component.ts new file mode 100644 index 0000000..9e2593c --- /dev/null +++ b/src/app/modules/common/sidebar/sidebar.component.ts @@ -0,0 +1,193 @@ +import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { MenuItem } from 'primeng/api'; +import { ActiveSidebarService } from 'src/app/core/services/active-sidebar.service'; +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { Subject, takeUntil } from 'rxjs'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; +import { API } from 'src/app/core/services/api.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +@Component({ + templateUrl: './sidebar.component.html', + selector: 'side-bar', +}) +export class SideBarComponent implements OnInit { + @ViewChild('logoImage') logoImage: ElementRef; + + router: any; + flag: boolean = true; + // mobile resposive start + isMobile = false; + // mobile resposive end + constructor( + public ChcekSidebar: ActiveSidebarService, + public MobileBreakpoints: BreakpointsService, + private cd: ChangeDetectorRef, // mobile resposive end, + private ApiSer: API, + public commonF: CommonFunctionService, + ) { + // mobile resposive start + this.MobileBreakpoints.IsMobile.subscribe({ + next: (val) => { + this.isMobile = val; + }, + }); + // mobile resposive end + } + + asideItems!: MenuItem[]; + ngOnInit(): void { + + // this.asideItems = [ + // { + // label: 'Bookings', + // icon: 'pi pi-pw pi-file', + // items: [ + // { + // label: 'Search Hotel Booking', + // icon: 'pi', + // routerLink: '/BookingManagement/HotelBooking/Search', + // }, + // { + // label: 'Search Experience Booking', + // icon: 'pi', + // routerLink: '/BookingManagement/ExperienceBooking/Search', + // }, + // ], + // }, + // { + // label: 'Services', + // icon: 'pi pi-fw pi-th-large', + // items: [ + // { + // label: 'Hotels', + // icon: 'pi ', + // routerLink: '/Services/HotelServices/Search', + // }, + // { + // label: 'Activity', + // icon: 'pi ', + // items: [ + // { + // label: 'Experience', + // icon: 'pi ', + // routerLink: '/Services/ActivityServices/ExpServices/Search', + // }, + // { + // label: 'Hotel Zone', + // icon: 'pi ', + // routerLink: '/Services/ActivityServices/HotelZone/Search', + // }, + // ], + // }, + // { + // label: 'Flights', + // icon: 'pi ', + // routerLink: '/Services/FlightServices/Search', + // }, + // { + // label: 'Flight Inventory', + // icon: 'pi ', + // routerLink: '/Services/FlightInventory/Search', + // }, + // { + // label: 'Flight Inventory Report', + // icon: 'pi ', + // routerLink: 'Services/FlightInventoryReport/Search', + // }, + // ], + // }, + // { + // label: 'User Configuration', + // icon: 'pi pi-fw pi-users', + // items: [ + // { + // label: 'Role Management', + // icon: 'pi ', + // routerLink: '/UserConfiguration/RoleManagement/Search', + // }, + // { + // label: 'User Management', + // icon: 'pi ', + // routerLink: '/UserConfiguration/UserManagement/Search', + // }, + // ], + // }, + // ]; + this.isMobile == true + ? (this.ChcekSidebar.activeSide = '') + : (this.ChcekSidebar.activeSide = 'IsActive'); + this.getMenus().subscribe(res => { + if (res) { + this.commonF.CheckActiveTabMenus(res); + this.BindMenu(res); + } + }) + this.cd.detectChanges(); + + } + getMenuss() { + let LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null; + return this.ApiSer.AdminGet(`/MenuMasterNew/GetMenuMasterNewsByOrgId/2405170833594899108/${LoginUserData.user_id}`) + } + getMenus() { + let LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null; + return this.ApiSer.AdminGet('/MenuMasterNew/GetAllMenuByUserId/' + LoginUserData.user_id + '/2405170833594899108') + } + BindMenu(list) { + let aisemenu = []; + let FliterList = list.sort(function (a, b) { return a.sequence - b.sequence; }); + let AllParentlist = list.filter(e => e.parent_id == ''); + AllParentlist.forEach(e => { + if (e.menu_type == '2305170833594899101' && !e.is_tab_wise_menu) { + aisemenu.push({ + label: e.menu_name, + icon: e.ng_icon == null ? 'pi pi-fw pi-pencil' : 'pi pi-fw ' + e.ng_icon, + items: [] + }); + } else if(!e.is_hide_in_side_menu){ + aisemenu.push({ label: e.menu_name, icon: ' ', routerLink: '/' + e.ui_controller + '/' + e.ui_action, command: (event) => { this.isMobile ? this.ChcekSidebar.SideBar('IsActive') : '' } }); + } + let index = aisemenu.length - 1; + let submenu = FliterList.filter(s => s.parent_id == e.menu_id); + if (submenu.length > 0) { + this.subMenu(aisemenu[index], submenu, FliterList); + } + }); + this.asideItems = aisemenu; + }; + + subMenu(menu, FilterSubmenu, Allmenu) { + if (FilterSubmenu.length > 0) { + FilterSubmenu.forEach(e => { + if (e.menu_type == '2305170833594899101' && !e.is_tab_wise_menu) { + menu.items.push({ + label: e.menu_name, + icon: 'pi pi-fw pi-pencil', + items: [] + }); + } else if(!e.is_hide_in_side_menu){ + menu.items.push( + { label: e.menu_name, icon: ' ', routerLink: '/' + e.ui_controller + '/' + e.ui_action, command: (event) => { this.isMobile ? this.ChcekSidebar.SideBar('IsActive') : '' } } + ); + } + let index = menu.items.length - 1; + let submenu = Allmenu.filter(a => a.parent_id == e.menu_id && !e.is_tab_wise_menu); + if (submenu.length > 0) { + this.subMenu(menu.items[index], submenu, Allmenu); + } + }); + }; + }; + headerHeight; // Default height + isHeightSet: boolean = false; // Flag to check if actual height is set + adjustHeaderSize() { + requestAnimationFrame(() => { + this.headerHeight = this.commonF.getHeaderSize(this.logoImage); + if (this.headerHeight > 0) { // Check if the height is valid + this.isHeightSet = true; + } + this.cd.detectChanges(); // Trigger change detection + }); +} +} diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.html b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.html new file mode 100644 index 0000000..5393dfb --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.html @@ -0,0 +1,231 @@ + + +
    +
    +
    +

    Add Activity Add-On

    +
    +
    + +
    +
    + +
    +
    + + + + Please enter add-on name + +
    +
    + + +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + + {{ lang.LanguageName }} + +
    + + Please select default language + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + Add-On Image + + +
    + + Note: Upload JPEG/PNG under 1MB. + +
    +
    +
    + + +
    +
    +
    +
    +
    Preview
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + +
    +
    +
    +

    Apply Rate On

    +
    + +
    +
    +
    + Select + {{ opt.key }} +
    + + Please select apply rate option + +
    +
    + + +
    +
    + + + +
    +
    +
    +

    Currency

    +
    + +
    +
    +
    + {{ curr.currency_code }} +
    + + Please select currency + +
    +
    + + +
    +
    + + + + Please enter adult rate + +
    +
    + + +
    +
    + + + + Please enter child rate + +
    +
    + + +
    +
    + + + + Please enter youth rate + +
    +
    + + +
    +
    + + + + Please enter senior + +
    +
    + + +
    +
    + + + + Please enter amount + +
    +
    + + +
    +
    + + + +
    +
    +
    +

    Vendor

    +
    + +
    +
    +
    + {{data.vehicleVendorName}} +
    +
    +
    +
    +
    + +
    + +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.ts b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.ts new file mode 100644 index 0000000..c19a5ac --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-add/activity-add-on-add.component.ts @@ -0,0 +1,244 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-activity-add-on-add', + templateUrl: './activity-add-on-add.component.html', +}) +export class ActivityAddOnAddComponent { +Edit_Id: string; + AddOnForm: FormGroup; + AllLang: any[] = []; + currencyList: any[] = []; + applyRateOnList = [ + { key: 'Per Person', value: 'PERPERSON' }, + { key: 'Per Service', value: 'PERSERVICE' }, + ]; + vendorList: any[] = []; + fileInfo = []; + fileArr = []; + editResp: any; + + constructor( + private fb: FormBuilder, + public validServ: ValidationService, + private apiserv: API, + private commonMasterSer: CommonFunctionService, + private router: Router, + private activateRoute: ActivatedRoute + ) {} + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initForm(); + this.getAllLanguages(); + this.getCurrencyList(); + this.getVendorList(); + if (this.Edit_Id) { + this.getById(); + } + } + + getAllLanguages() { + this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId').subscribe(data => { + if (data) { + this.AllLang = data; + } + }); + } + + getCurrencyList() { + // Replace with actual API if needed + this.apiserv.AdminGet('/CurrencyMaster/GetAllCurrencies').subscribe(d => { + if (d) this.currencyList = d; + }); + } + + getVendorList() { + this.apiserv.Get('/ActivityVehicle/GetVehicleVendor').subscribe(res => { + if (res && res.status) { + this.vendorList = res.data; + } + }); + } + + initForm() { + this.AddOnForm = this.fb.group({ + addOn: this.validServ.required, + defaultLanguageCode: this.validServ.required, + description: '', + addonImage: '', + addonImageUrl: '', + applyRateOn: this.validServ.required, + currency: this.validServ.required, + activityAddonVendorId: '' + }); + } + + SelectImage(event: any, fileUpload: any, controlName: string) { + const file = event.currentFiles[0]; + if (file && file.size < 1048576 && ['image/jpeg', 'image/png'].includes(file.type)) { + const reader = new FileReader(); + reader.readAsText(file); // Check for script tags + reader.onload = (e) => { + const binaryString = e.target?.result as string; + const hasScript = this.commonMasterSer.hasScriptTagInBinary(binaryString); + if (hasScript) { + fileUpload.clear(); + this.commonMasterSer.showMessage(false, 'Invalid file (contains script tag)'); + return; + } + + // Set file and preview URL + this.AddOnForm.get(controlName).setValue(file); + const urlReader = new FileReader(); + urlReader.readAsDataURL(file); + urlReader.onload = () => { + this.AddOnForm.get('addonImageUrl').setValue(urlReader.result?.toString()); + }; + }; + } else { + this.commonMasterSer.showMessage(false, 'File must be JPG/PNG under 1MB'); + fileUpload.clear(); + } + } + + RemoveImage() { + this.AddOnForm.get('addonImage').setValue(''); + this.AddOnForm.get('addonImageUrl').setValue(''); + } + + getById() { + this.apiserv.Get(`/ActivityAddon/GetById/${this.Edit_Id}`).subscribe(res => { + if (res && res.status) { + this.editResp = res.data; + this.HandleApplyRateOn(this.editResp.applyRateOn) + this.AddOnForm.get('addOn').setValue(this.editResp.activityAddonDetails.addOn); + this.AddOnForm.get('defaultLanguageCode').setValue(this.editResp.defaultLanguageCode); + this.AddOnForm.get('description').setValue(this.editResp.activityAddonDetails.description); + this.AddOnForm.get('applyRateOn').setValue(this.editResp.applyRateOn); + this.AddOnForm.get('currency').setValue(this.editResp.currency); + this.AddOnForm.get('adult')?.setValue(this.editResp.adult); + this.AddOnForm.get('child')?.setValue(this.editResp.child); + this.AddOnForm.get('youth')?.setValue(this.editResp.youth); + this.AddOnForm.get('senior')?.setValue(this.editResp.senior); + this.AddOnForm.get('amount')?.setValue(this.editResp.amount); + this.AddOnForm.get('activityAddonVendorId').setValue(this.editResp.activityAddonVendorId || ''); + + if (this.editResp.addonImage) { + this.AddOnForm.get('addonImage').setValue(this.editResp.addonImage); + this.AddOnForm.get('addonImageUrl').setValue(this.editResp.addonImage); + } + } + }); + } + + SaveUpdateAddOn() { + if (this.AddOnForm.invalid) { + this.validServ.showValidationsMsg(this.AddOnForm); + setTimeout(() => this.validServ.scrollToError(), 50); + return; + } + + const formVal = this.AddOnForm.getRawValue(); + const postData = { + activityAddonId: this.Edit_Id ?? '', + defaultLanguageCode: formVal.defaultLanguageCode, + applyRateOn: formVal.applyRateOn, + currency: formVal.currency, + adult: formVal.adult, + child: formVal.child, + youth: formVal.youth, + senior: formVal.senior, + amount: formVal.amount, + activityAddonVendorId: formVal.activityAddonVendorId, + activityAddonDetails: { + addOn: formVal.addOn, + description: formVal.description, + languageCode: formVal.defaultLanguageCode, + activityAddonId: this.Edit_Id ?? '', + activityAddonDetailId: this.editResp?.activityAddonDetails?.activityAddonDetailId || '' + } + }; + + let addonImageUrl = ''; + if (formVal.addonImage && typeof formVal.addonImage === 'object') { + const ext = formVal.addonImage.name.split('.').pop(); + this.fileArr.push(formVal.addonImage); + this.fileInfo.push({ + fileName: `Extranet/Activity/AddOn/ActivityAddonId/addonImage.${ext}`, + pathToSave: 'OrganizationData/ORGID' + }); + addonImageUrl = `${environment.cdnFileUrl}OrganizationData/ORGID/Extranet/Activity/AddOn/ActivityAddonId/addonImage.${ext}?t=${moment().format('yyMMddHHmmssfffffff')}`; + } else { + addonImageUrl = formVal.addonImage; + } + + postData['addonImage'] = addonImageUrl; + + const url = this.Edit_Id ? 'Update' : 'Save'; + this.apiserv.Post(`/ActivityAddon/${url}`, postData).subscribe(resp => { + if (resp?.status) { + if (this.fileInfo.length > 0) { + this.saveImg(this.fileInfo, this.fileArr, resp.data).subscribe(uploadRes => { + if (uploadRes?.resp) { + this.BackButton(); + } + this.commonMasterSer.showMessage(uploadRes.resp, uploadRes.respMsg || 'Saved successfully'); + }); + } else { + this.BackButton(); + } + this.commonMasterSer.showMessage(true, resp.message); + } else { + this.commonMasterSer.showMessage(false, resp?.message || 'Save failed'); + } + }); + } + + saveImg(fileInfo: any[], fileArr: File[], edit_id: string) { + if (!fileInfo.length || !fileArr.length) { + return of({ resp: true, respMsg: 'No files to upload' }); + } + + const formData = new FormData(); + fileArr.forEach(file => formData.append('files', file)); + const processedFileInfo = JSON.stringify(fileInfo).replace(/ActivityAddonId/g, edit_id); + formData.append('fileInfo', processedFileInfo); + + return this.apiserv.PostFile('/FileUpload/SaveFile', formData); + } + + BackButton() { + this.router.navigateByUrl('ActivityConfiguration/ActivityAddOn/Search'); + } + + HandleApplyRateOn(value){ + if(value === "PERPERSON"){ + this.AddOnForm.addControl('adult', this.fb.control('', Validators.required)); + this.AddOnForm.addControl('child', this.fb.control('', Validators.required)); + this.AddOnForm.addControl('youth', this.fb.control('', Validators.required)); + this.AddOnForm.addControl('senior', this.fb.control('', Validators.required)); + this.AddOnForm.removeControl('amount'); + }else if(value === "PERSERVICE"){ + this.AddOnForm.addControl('amount', this.fb.control('', Validators.required)); + this.AddOnForm.removeControl('child'); + this.AddOnForm.removeControl('youth'); + this.AddOnForm.removeControl('adult'); + this.AddOnForm.removeControl('senior'); + }else { + this.AddOnForm.removeControl('child'); + this.AddOnForm.removeControl('youth'); + this.AddOnForm.removeControl('adult'); + this.AddOnForm.removeControl('amount'); + this.AddOnForm.removeControl('senior'); + } + } +} diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.html b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.html new file mode 100644 index 0000000..9579923 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.html @@ -0,0 +1 @@ +

    activity-add-on-edit works!

    diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.ts b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.ts new file mode 100644 index 0000000..a24dc47 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-edit/activity-add-on-edit.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-add-on-edit', + templateUrl: './activity-add-on-edit.component.html', +}) +export class ActivityAddOnEditComponent { + +} diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.html b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.html new file mode 100644 index 0000000..4e4d209 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.html @@ -0,0 +1,124 @@ + + + +
    +
    +
    +

    Manage Translation

    +
    +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +
    +

    Translate To

    +
    + +
    +
    +
    + {{ lang.LanguageName }} +
    + + Please select a language to translate to + +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    +

    Default Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Selected Language Content

    +
    +
    +
    +
    +
    +
    + + + + Please enter translated add-on name + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    + + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.ts b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.ts new file mode 100644 index 0000000..8665c48 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-language/activity-add-on-language.component.ts @@ -0,0 +1,125 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +@Component({ + selector: 'app-activity-add-on-language', + templateUrl: './activity-add-on-language.component.html', +}) +export class ActivityAddOnLanguageComponent { +Edit_Id: string; + AddOnLangForm: FormGroup; + AllLang: any[] = []; + editResp: any; + + constructor( + private fb: FormBuilder, + public validServ: ValidationService, + private apiserv: API, + public commonMasterSer: CommonFunctionService, + private router: Router, + private activateRoute: ActivatedRoute + ) {} + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initForm(); + this.loadInitialData(); + } + + initForm() { + this.AddOnLangForm = this.fb.group({ + defaultLanguageCode: [''], + languageCode: this.validServ.required, + defaultAddOn: [''], + defaultDescription: [''], + addOn: this.validServ.required, + description: [''], + activityAddonDetailId: [''] + }); + } + + loadInitialData() { + forkJoin({ + languages: this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId'), + addonData: this.Edit_Id ? this.apiserv.Get(`/ActivityAddon/GetById/${this.Edit_Id}`) : of(null) + }).subscribe(res => { + if (res.languages) { + this.AllLang = [...res.languages]; + } + + if (res.addonData?.status) { + this.editResp = res.addonData.data; + const defaultLangCode = this.editResp.defaultLanguageCode; + + // Set default language name + const defaultLang = this.AllLang.find(lang => lang.LanguageCode === defaultLangCode); + this.AddOnLangForm.get('defaultLanguageCode').setValue(defaultLang?.LanguageName || defaultLangCode); + + // Set default content + this.AddOnLangForm.get('defaultAddOn').setValue(this.editResp.activityAddonDetails.addOn); + this.AddOnLangForm.get('defaultDescription').setValue(this.editResp.activityAddonDetails.description); + + // Remove default language from dropdown + this.AllLang = this.AllLang.filter(lang => lang.LanguageCode !== defaultLangCode); + } + }); + } + + getDataByLang() { + const langCode = this.AddOnLangForm.get('languageCode').value; + if (!langCode || !this.Edit_Id) return; + + this.apiserv.Get(`/ActivityAddon/GetActivityAddonDetailsByIdAndLangCode/${this.Edit_Id}/${langCode}`).subscribe(res => { + if (res && res.status && res.data) { + this.AddOnLangForm.patchValue({ + addOn: res.data.addOn, + description: res.data.description, + activityAddonDetailId: res.data.activityAddonDetailId + }); + } else { + // Reset for new translation + this.AddOnLangForm.patchValue({ + addOn: '', + description: '', + activityAddonDetailId: '' + }); + } + }); + } + + saveTranslation() { + if (this.AddOnLangForm.invalid) { + this.validServ.showValidationsMsg(this.AddOnLangForm); + setTimeout(() => this.validServ.scrollToError(), 50); + return; + } + + const formVal = this.AddOnLangForm.getRawValue(); + + const postData = { + activityAddonDetailId: formVal.activityAddonDetailId || '', + activityAddonId: this.Edit_Id, + languageCode: formVal.languageCode, + addOn: formVal.addOn, + description: formVal.description || '', + }; + + this.apiserv.Post('/ActivityAddon/ManageTranslationActivityAddonDetail', postData).subscribe(resp => { + if (resp?.status) { + this.commonMasterSer.showMessage(true, resp.message || 'Translation saved successfully'); + this.BackButton(); + } else { + this.commonMasterSer.showMessage(false, resp?.message || 'Save failed'); + } + }); + } + + BackButton() { + this.router.navigateByUrl('ActivityConfiguration/ActivityAddOn/Search'); + } + +} diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.html b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.html new file mode 100644 index 0000000..2e22938 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.html @@ -0,0 +1,128 @@ +
    +
    +
    +

    Activity Add-On Search

    +
    + +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    + + +
    +
    + +
    + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + + {{ col.header }} + + + Action + + + + + + {{ data.addOn }} + {{ data.description }} + {{ data.applyRateOn }} + {{ data.currency }} + {{ data.activityAddonId }} + {{ data.activityAddonVendor }} + + + {{ data.status }} + + + {{ data.updatedBy }} + {{ data.Custom_updated_on }} + + + + + + + + + + + + + + No data found + + +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.ts b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.ts new file mode 100644 index 0000000..3be580d --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on-search/activity-add-on-search.component.ts @@ -0,0 +1,95 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; +@Component({ + selector: 'app-activity-add-on-search', + templateUrl: './activity-add-on-search.component.html', +}) +export class ActivityAddOnSearchComponent { + Result; + cols: any[]; + searchForm: FormGroup; + + constructor( + public fb: FormBuilder, + private apiserv: API, + public commonMasterSer: CommonFunctionService, + private router: Router + ) {} + + ngOnInit(): void { + this.cols = [ + { field: 'addOn', header: 'Add-On' }, + { field: 'description', header: 'Description' }, + { field: 'applyRateOn', header: 'Rate Type' }, + { field: 'currency', header: 'Currency' }, + { field: 'activityAddonId', header: 'Add-On Id' }, + { field: 'activityAddonVendor', header: 'Vendor' }, + { field: 'status', header: 'Status' }, + { field: 'updatedBy', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + + this.initForm(); + } + + initForm() { + this.searchForm = this.fb.group({ + addOn: '' + }); + } + + Search() { + const formVal = this.searchForm.getRawValue(); + const reqObj = { + addOn: formVal.addOn ? formVal.addOn.trim() : '' + }; + + this.apiserv.Post('/ActivityAddon/GetAll', reqObj).subscribe(res => { + if (res && res.status) { + this.Result = res.data ? res.data : []; + if (this.Result.length > 0) { + this.Result.forEach(item => { + item['status'] = item.isActive ? 'Active' : 'Deactive'; + item['Custom_updated_on'] = this.commonMasterSer.convertDateWithTimeToShow(item.updatedOn); + }); + } + } else { + this.Result = []; + // this.commonMasterSer.showMessage(false, res?.message || 'Failed to load data'); + } + }); + } + + Reset() { + this.searchForm.reset(); + this.Result = []; + } + + Edit(id: string) { + this.router.navigateByUrl(`/ActivityConfiguration/ActivityAddOn/Edit/${id}`); + } + + ManageLang(id: string) { + this.router.navigateByUrl(`/ActivityConfiguration/ActivityAddOn/Language/${id}`); + } + + updateStatus(id: string, currentStatus: boolean) { + const obj = { + id: id, + status: !currentStatus + }; + + this.apiserv.Post('/ActivityAddon/UpdateStatus', obj).subscribe(res => { + if (res && res.status) { + this.commonMasterSer.showMessage(true, res.message || 'Status updated successfully'); + this.Search(); // Refresh list + } else { + this.commonMasterSer.showMessage(false, res?.message || 'Failed to update status'); + } + }); + } +} diff --git a/src/app/modules/services/activity-config/activity-add-on/activity-add-on.module.ts b/src/app/modules/services/activity-config/activity-add-on/activity-add-on.module.ts new file mode 100644 index 0000000..4b7c4ad --- /dev/null +++ b/src/app/modules/services/activity-config/activity-add-on/activity-add-on.module.ts @@ -0,0 +1,66 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ActivityAddOnAddComponent } from './activity-add-on-add/activity-add-on-add.component'; +import { ActivityAddOnEditComponent } from './activity-add-on-edit/activity-add-on-edit.component'; +import { ActivityAddOnLanguageComponent } from './activity-add-on-language/activity-add-on-language.component'; +import { ActivityAddOnSearchComponent } from './activity-add-on-search/activity-add-on-search.component'; + +const routes: Routes = [ + { + path: 'Search', + component: ActivityAddOnSearchComponent, + }, + { + path: 'Add', + component: ActivityAddOnAddComponent, + }, + { + path: 'Language/:RuleId', + component: ActivityAddOnLanguageComponent, + }, + { + path: 'Edit/:RuleId', + component: ActivityAddOnAddComponent, + }, +] + +@NgModule({ + declarations: [ + ActivityAddOnSearchComponent, + ActivityAddOnAddComponent, + ActivityAddOnLanguageComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes) + ] +}) +export class ActivityAddOnModule { } diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.html b/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.html new file mode 100644 index 0000000..cbcc13f --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.html @@ -0,0 +1,78 @@ + +
    +
    +
    +

    Add Vehicle Master

    +
    +
    +
    +
    +
    +
    + + + + Please enter category name + +
    +
    +
    +
    + + + +
    +
    +
    +

    Parent Category

    +
    + +
    +
    +
    + Select + {{data.categoryName}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + + {{ lang.LanguageName }} + +
    + + Please select default language + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.ts b/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.ts new file mode 100644 index 0000000..563f288 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-add/activity-category-add.component.ts @@ -0,0 +1,107 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-activity-category-add', + templateUrl: './activity-category-add.component.html', +}) +export class ActivityCategoryAddComponent { + Edit_Id: string; + ActivityCategoryForm: FormGroup; + AllLang: any[] = []; + AllParentCategory: any[] = []; + editResp; + + constructor( + private fb: FormBuilder, + public validServ: ValidationService, + private apiserv: API, + private commonMasterSer: CommonFunctionService, + private router: Router, + private activateRoute: ActivatedRoute + ) {} + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initForm(); + this.getAllLanguages(); + this.getParentCategory(); + if (this.Edit_Id) { + this.getById(); + } + } + + initForm() { + this.ActivityCategoryForm = this.fb.group({ + defaultLanguageCode: this.validServ.required, + categoryName: this.validServ.required, + parentCategoryId: '', + activityCategoryDetailsId:'' + }); + } + + getAllLanguages() { + this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId').subscribe(data => { + if (data) { + this.AllLang = data; + } + }); + } + + getById() { + this.apiserv.Get(`/ActivityCategory/GetById/${this.Edit_Id}`).subscribe(res => { + if (res && res.status) { + this.editResp = res.data; + this.ActivityCategoryForm.get('categoryName').setValue(this.editResp.activityCategoryDetails.categoryName); + this.ActivityCategoryForm.get('defaultLanguageCode').setValue(this.editResp.defaultLanguageCode); + this.ActivityCategoryForm.get('parentCategoryId').setValue(this.editResp.parentCategoryId); + } + }); + } + getParentCategory() { + this.apiserv.Get(`/ActivityCategory/GetAllCategory`).subscribe(res => { + if (res && res.status) { + this.AllParentCategory = res.data; + } + }); + } + + + BackButton() { + this.router.navigateByUrl('ActivityConfiguration/ActivityCategory/Search'); + } + + SaveUpdateCategory() { + if (this.ActivityCategoryForm.invalid) { + this.validServ.showValidationsMsg(this.ActivityCategoryForm); + setTimeout(() => this.validServ.scrollToError(), 50); + return; + } + + const formVal = this.ActivityCategoryForm.getRawValue(); + const postdata = { + defaultLanguageCode:formVal.defaultLanguageCode, + parentCategoryId:formVal.parentCategoryId || '', + activityCategoryId:this.Edit_Id || '', + activityCategoryDetails : { + activityCategoryDetailsId : formVal.activityCategoryDetailsId, + activityCategoryId: this.Edit_Id || '', + categoryName:formVal.categoryName, + languageCode:formVal.defaultLanguageCode, + } + }; + const url = this.Edit_Id ? 'Update' : 'Save'; + this.apiserv.Post(`/ActivityCategory/${url}`, postdata).subscribe(resp => { + if (resp?.status) { + this.commonMasterSer.showMessage(resp.status, resp.respMsg); + } else { + this.commonMasterSer.showMessage(false, resp?.message || 'Save failed'); + } + }); + } + +} diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.html b/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.html new file mode 100644 index 0000000..229009d --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.html @@ -0,0 +1 @@ +

    activity-category-edit works!

    diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.ts b/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.ts new file mode 100644 index 0000000..1ba4433 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-edit/activity-category-edit.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-category-edit', + templateUrl: './activity-category-edit.component.html', +}) +export class ActivityCategoryEditComponent { + +} diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.html b/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.html new file mode 100644 index 0000000..a6f336c --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.html @@ -0,0 +1,89 @@ + +
    +
    +
    +

    Manage Translation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Translate To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Default Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Selected Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.ts b/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.ts new file mode 100644 index 0000000..602d034 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-language/activity-category-language.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-category-language', + templateUrl: './activity-category-language.component.html', +}) +export class ActivityCategoryLanguageComponent { + +} diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.html b/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.html new file mode 100644 index 0000000..e24f7c2 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.html @@ -0,0 +1,175 @@ +
    +
    +
    +

    Activity Category Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Parent Category

    +
    + +
    +
    +
    + Select + {{data.categoryName}} +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + + Category Name + + + + Parent Category + + + + Category Id + + + + Status + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + {{ data.categoryName }} + {{ data.parentCategoryName }} + {{ data.activityCategoryId }} + + + {{ data.status }} + + + {{ data.createdBy }} + {{ data.Custom_created_on }} + {{ data.updatedBy }} + {{ data.Custom_updated_on }} + + + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.ts b/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.ts new file mode 100644 index 0000000..36def36 --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category-search/activity-category-search.component.ts @@ -0,0 +1,101 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service' +@Component({ + selector: 'app-activity-category-search', + templateUrl: './activity-category-search.component.html', +}) +export class ActivityCategorySearchComponent { + + Result; + AllParentCategory; + cols; + categorySearchForm: FormGroup; + + constructor( + public fb: FormBuilder, + private apiserv: API, + public commonMasterSer: CommonFunctionService, + private router: Router + ) {} + + ngOnInit(): void { + this.cols = [ + { field: 'categoryName', header: 'Category Name' }, + { field: 'parentCategoryName', header: 'Parent Category' }, + { field: 'activityCategoryId', header: 'Category Id' }, + { field: 'status', header: 'Status' }, + { field: 'createdBy', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updatedBy', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + + this.initform(); + this.getParentCategory(); + } + + getParentCategory() { + this.apiserv.Get(`/ActivityCategory/GetAllCategory`).subscribe(res => { + if (res && res.status) { + this.AllParentCategory = res.data; + } + }); + } + + initform() { + this.categorySearchForm = this.fb.group({ + categoryName: '', + parentCategoryId: '' + }); + } + + Search() { + let val = this.categorySearchForm.getRawValue(); + let ReqObj = { + categoryName: val.categoryName ? val.categoryName : '', + parentCategoryId: val.parentCategoryId ? val.parentCategoryId : '' + }; + + this.apiserv.Post('/ActivityCategory/GetAll', ReqObj).subscribe(res => { + if (res) { + this.Result = res.data ? res.data : []; + if (res.data && res.status) { + this.Result.forEach(e => { + e['status'] = e.isActive ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this.commonMasterSer.convertDateWithTimeToShow(e.updatedOn); + e['Custom_created_on'] = e['createdOn'] ? this.commonMasterSer.convertDateWithTimeToShow(e.createdOn) : e['createdOn']; + }); + } + } + }); + } + + Reset() { + this.categorySearchForm.reset(); + } + + Edit(id: string) { + this.router.navigateByUrl(`ActivityConfiguration/ActivityCategory/Edit/${id}`); + } + + ManageLang(id: string) { + this.router.navigateByUrl(`ActivityConfiguration/ActivityCategory/Language/${id}`); + } + + updateStatus(id: string, val: boolean) { + let obj = { + id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ActivityCategory/UpdateStatus', obj).subscribe(res => { + if (res) { + this.commonMasterSer.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + +} diff --git a/src/app/modules/services/activity-config/activity-category/activity-category.module.ts b/src/app/modules/services/activity-config/activity-category/activity-category.module.ts new file mode 100644 index 0000000..47e15db --- /dev/null +++ b/src/app/modules/services/activity-config/activity-category/activity-category.module.ts @@ -0,0 +1,66 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ActivityCategoryAddComponent } from './activity-category-add/activity-category-add.component'; +import { ActivityCategoryEditComponent } from './activity-category-edit/activity-category-edit.component'; +import { ActivityCategoryLanguageComponent } from './activity-category-language/activity-category-language.component'; +import { ActivityCategorySearchComponent } from './activity-category-search/activity-category-search.component'; + +const routes: Routes = [ + { + path: 'Search', + component: ActivityCategorySearchComponent, + }, + { + path: 'Add', + component: ActivityCategoryAddComponent, + }, + { + path: 'Language', + component: ActivityCategoryLanguageComponent, + }, + { + path: 'Edit', + component: ActivityCategoryEditComponent, + }, +] + +@NgModule({ + declarations: [ + ActivityCategorySearchComponent, + ActivityCategoryAddComponent, + ActivityCategoryLanguageComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes) + ] +}) +export class ActivityCategoryModule { } diff --git a/src/app/modules/services/activity-config/activity-config.module.ts b/src/app/modules/services/activity-config/activity-config.module.ts new file mode 100644 index 0000000..7c7efcd --- /dev/null +++ b/src/app/modules/services/activity-config/activity-config.module.ts @@ -0,0 +1,44 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: 'HotelZone', + loadChildren: () => + import('./hotel-zone/hotel-zone.module').then( + (m) => m.HotelZoneModule + ), + }, + { + path: 'VehicleMaster', + loadChildren: () => + import('./vehicle-master/vehicle-master.module').then( + (m) => m.VehicleMasterModule + ), + }, + { + path: 'ActivityCategory', + loadChildren: () => + import('./activity-category/activity-category.module').then( + (m) => m.ActivityCategoryModule + ), + }, + { + path: 'ActivityAddOn', + loadChildren: () => + import('./activity-add-on/activity-add-on.module').then( + (m) => m.ActivityAddOnModule + ), + }, +] + + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + RouterModule.forChild(routes) + ] +}) +export class ActivityConfigModule { } diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.html b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.html new file mode 100644 index 0000000..d6625e0 --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.html @@ -0,0 +1,230 @@ + +
    +
    +
    +

    Add Hotel Zones

    +
    +
    +
    +
    +
    +
    + + + Please + enter zone name +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select country +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + {{item.cityName }}, {{item.countryName}} + +
    + Please + select city +
    +
    +
    + + +
    + + + + +
    Hotel Selection
    + +
    + +
    + + +
    +
    + + + + +
    +
    +
    +
    + + + + + + + Hotel Name + + + + Hotel Star Category + + + + Address + + + + City + + + + + + + + {{data.hotelName}} + {{data.starRating}} + {{data.address}} + {{data.city}} + + +
    +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + +
    + Hotel Name + + Hotel Star Category + + Address + + City +
    {{data.hotelName}}{{data.starRating}}{{data.address}}{{data.city}}
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.ts b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.ts new file mode 100644 index 0000000..f6414db --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-add/hotel-zone-add.component.ts @@ -0,0 +1,223 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { PaginatorState } from 'primeng/paginator'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-hotel-zone-add', + templateUrl: './hotel-zone-add.component.html', +}) +export class HotelZoneAddComponent implements OnInit { + visible: boolean = false; + + hotelZoneForm:FormGroup; + ddLoader = { + country:false, + city:false, + }; + CountryList:any[] = []; + cityList=[]; + timer:any; + citySelection = true; + hotelList = []; + Edit_Id; + editResp; + selectedHotelList = []; + selectedHotelCheck = []; + SelectedHotels = []; + + constructor(public fb:FormBuilder, public validServ:ValidationService, private apiserv:API, private commonMasterSer:CommonFunctionService, private router:Router, private activateRoute:ActivatedRoute){ + + } + showDialog() { + this.SelectedHotels = []; + this.hotelList.forEach(hotelDet=>{ + if(hotelDet.check){ + this.SelectedHotels.push(hotelDet); + } + }) + this.visible = true; + } + first: number = 0; + + rows: number = 10; + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initform(); + if(this.Edit_Id){ + this.GetById(); + } + } + + onPageChange(event: PaginatorState) { + this.first = event.first ?? 0; + this.rows = event.rows ?? 10; + } + + GetById(){ + this.apiserv.Get(`/ActivityHotelZone/GetById/${this.Edit_Id}`).subscribe(res => { + if (res && res.status) { + this.editResp = res.data; + let country_obj = { + country_code : this.editResp.country, + country_name:this.editResp.countryName + } + let city_obj = { + cityCode:this.editResp.city, + countryName:this.editResp.countryName, + cityName:this.editResp.cityName, + } + this.CountryList.push(country_obj); + this.cityList.push(city_obj); + + this.hotelZoneForm.get('Country').setValue(this.editResp.country); + this.hotelZoneForm.get('City').setValue(this.editResp.city); + this.hotelZoneForm.get('ZoneName').setValue(this.editResp.zoneName); + this.hotelZoneForm.get('ZoneName').disable(); + this.getHotelsByCity(true); + } + }); + } + + initform(){ + this.hotelZoneForm = this.fb.group({ + ZoneName:this.validServ.required, + Country:this.validServ.required, + City:this.validServ.required, + selectAll:false, + filterInput:'' + }) + } + + getCountryList(event) { + if (event.value.length >= 2) { + this.ddLoader.country = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader.country = false; + } + }); + }, 500); + } + } + + getCityList(event) { + if (event.value.length >= 2) { + this.ddLoader.city = true; + clearTimeout(this.timer); + let req = { + "cityName": event.value, + "languageCode": "EN", + "lattitude": "0", + "longitude": "0", + "CountryCode": this.hotelZoneForm.get('Country').value || '', + } + this.timer = setTimeout(() => { + this.apiserv.PostGo(`/Hotel/GetHotelCities`, req).subscribe(res => { + if (res) { + this.cityList = res.cities; + this.ddLoader.city = false; + } + }); + }, 500); + } + } + + checkCountrySelection(){ + let val = this.hotelZoneForm.get('Country').value; + this.hotelZoneForm.get('City').setValue(''); + if(val){ + this.citySelection = false; + }else { + this.citySelection = true; + } + this.getHotelsByCity(); + } + + getHotelsByCity(check?){ + let cityVal =this.hotelZoneForm.get('City').value; + let countryVal =this.hotelZoneForm.get('City').value; + if(countryVal && cityVal){ + this.selectedHotelList = []; + this.apiserv.Get(`/ActivityHotelZone/GetHotelByCityCode/${cityVal}`).subscribe(res => { + if (res) { + this.hotelList = res.data; + this.hotelList.forEach(hotelDet=>{ + hotelDet['check'] = check ? this.editResp.hotels.includes(hotelDet.hotelId) :false; + }) + this.selectedHotelCheck = new Array(res.data.length).fill(false); + } + }); + }else { + this.hotelList = []; + } + } + + checkHotelSelection(hotelId){ + this.hotelList.forEach(hotelDet=>{ + if(hotelDet.hotelId === hotelId){ + hotelDet['check'] = !hotelDet['check']; + } + }); + if(this.hotelList.every(hotelDet=> hotelDet['check'] )){ + this.hotelZoneForm.get('selectAll').setValue(true); + }else { + this.hotelZoneForm.get('selectAll').setValue(false); + } + } + + SelectDeselectHotels(){ + let val = this.hotelZoneForm.get('selectAll').value; + this.hotelList.forEach(hotelDet=>{ + hotelDet['check'] = val; + }); + } + + saveUpdateHotelZone(){ + if(!this.hotelList.some(hotelDet=> hotelDet['check'] )){ + this.commonMasterSer.showMessage(false, 'Please select a hotel'); + return; + } + if(this.hotelZoneForm.status == "INVALID"){ + this.validServ.showValidationsMsg(this.hotelZoneForm); + setTimeout(() => { + this.validServ.scrollToError(); + }, 50); + } else if(this.hotelZoneForm.status == "VALID"){ + let formVal = this.hotelZoneForm.getRawValue(); + let PostData = { + HotelZoneId: this.Edit_Id ?? '', + ZoneName: formVal.ZoneName, + Country:formVal.Country, + City:formVal.City, + Hotels:'', + }; + let hotel_arr = []; + this.hotelList.forEach(hotelDet=>{ + if(hotelDet['check']){ + hotel_arr.push(hotelDet.hotelId); + } + }) + PostData.Hotels = hotel_arr.join(','); + let url = this.Edit_Id ? `Update` : `Save` + this.apiserv.Post(`/ActivityHotelZone/${url}`, PostData).subscribe(res=>{ + if(res){ + this.commonMasterSer.showMessage(res.status, res.message); + this.BackButton(); + } + }) + } + } + + + BackButton(){ + this.router.navigateByUrl(`ActivityConfiguration/HotelZone/Search`); + } +} diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.html b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.html new file mode 100644 index 0000000..c85104d --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.html @@ -0,0 +1 @@ +

    hotel-zone-edit works!

    diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.ts b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.ts new file mode 100644 index 0000000..3374027 --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-edit/hotel-zone-edit.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-hotel-zone-edit', + templateUrl: './hotel-zone-edit.component.html', +}) +export class HotelZoneEditComponent { + +} diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.html b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.html new file mode 100644 index 0000000..50f5e61 --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.html @@ -0,0 +1,227 @@ +
    +
    +
    +

    Hotel Zones Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Hotel Name

    +
    + +
    +
    +
    + + {{item.hotelName }} {{item.cityName }}, {{item.countryName }} + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + {{item.cityName }}, {{item.countryName }} + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Zone Name + + + + Country + + + + City + + + + Number of Hotel + + + + Zone Id + + + + Status + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + {{data.zoneName}} + + {{data.country}} + {{data.city}} + {{data.hotels}} + {{data.hotelZoneId}} + + + {{data.status}} + + + {{data.createdBy}} + {{data.Custom_created_on}} + {{data.updatedBy}} + {{data.Custom_updated_on}} + + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.ts b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.ts new file mode 100644 index 0000000..6c58181 --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone-search/hotel-zone-search.component.ts @@ -0,0 +1,173 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { TableModule } from 'primeng/table'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-hotel-zone-search', + templateUrl: './hotel-zone-search.component.html', +}) +export class HotelZoneSearchComponent implements OnInit { + + hotelZoneSearchForm: FormGroup; + + ddLoader = { + city: false, + Country: false, + hotel_list: false, + }; + timer; + HotelList; + CountryList; + CityList; + Result; + cols; + constructor(public fb: FormBuilder, private apiserv: API, public commonMasterSer: CommonFunctionService, private router: Router) { + + } + + ngOnInit(): void { + this.cols = [ + { field: 'zoneName', header: 'Zone Name' }, + { field: 'country', header: 'Country' }, + { field: 'city', header: 'City' }, + { field: "hotels", header: 'Number of Hotel' }, + { field: 'hotelZoneId', header: 'Zone Id' }, + { field: 'status', header: 'Status' }, + { field: 'createdBy', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updatedBy', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.initform(); + } + + initform() { + this.hotelZoneSearchForm = this.fb.group({ + ZoneName: '', + HotelName: '', + Country: '', + City: '', + }); + } + + + GetHotels(event) { + if (event.value.length >= 2) { + let obj = { + languageCode: 'en', + cityName: event.value, + lattitude: '0', + longitude: '0', + } + this.ddLoader['hotel_list'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost(`/Hotel/GetHotels`, obj).subscribe(res => { + if (res) { + this.HotelList = res.hotels; + this.ddLoader['hotel_list'] = false; + } + }); + }, 500); + } + } + + getCountryList(event) { + if (event.value.length >= 2) { + this.ddLoader['Country'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader['Country'] = false; + } + }); + }, 500); + } + } + + getHotelCitySearch(event) { + if (event.value.length >= 2) { + let reqObj = { + cityName: event.value, + languageCode: 'en', + lattitude: '0', + longitude: '0' + } + this.ddLoader.city = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost("/Hotel/GetHotelCities", reqObj).subscribe(res => { + if (res) { + this.CityList = res.cities; + this.ddLoader.city = false; + } + }); + }, 500); + } + if (!event.value) { + this.CityList = []; + } + }; + + Search(){ + let val = this.hotelZoneSearchForm.getRawValue(); + let ReqObj = { + ZoneName: val.ZoneName ? val.ZoneName : '', + HotelName: val.HotelName ? val.HotelName : '', + Country: val.Country ? val.Country : '', + City: val.City ? val.City : '', + } + this.apiserv.Post('/ActivityHotelZone/GetAll', ReqObj).subscribe(res => { + if (res) { + this.Result = res.data ? res.data :[]; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.isActive ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this.commonMasterSer.convertDateWithTimeToShow(e.updatedOn); + e['Custom_created_on'] = e['createdOn'] ? this.commonMasterSer.convertDateWithTimeToShow(e.createdOn) : e['createdOn']; + }); + // customSort(event: SortEvent) { + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updatedOn).getTime() - new Date(a.updatedOn).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updatedOn).getTime() - new Date(a.updatedOn).getTime(); + }); + // } + } + } + }) + } + Reset(){ + this.hotelZoneSearchForm.reset(); + } + + Edit(Id){ + this.router.navigateByUrl(`ActivityConfiguration/HotelZone/Edit/${Id}`); + } + updateStatus(id, val) { + let obj = { + id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ActivityHotelZone/UpdateStatus', obj).subscribe(res => { + if (res) { + this.commonMasterSer.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } +} diff --git a/src/app/modules/services/activity-config/hotel-zone/hotel-zone.module.ts b/src/app/modules/services/activity-config/hotel-zone/hotel-zone.module.ts new file mode 100644 index 0000000..cee4b5a --- /dev/null +++ b/src/app/modules/services/activity-config/hotel-zone/hotel-zone.module.ts @@ -0,0 +1,67 @@ +import { Component, NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { HotelZoneSearchComponent } from './hotel-zone-search/hotel-zone-search.component'; +import { HotelZoneAddComponent } from './hotel-zone-add/hotel-zone-add.component'; +import { HotelZoneEditComponent } from './hotel-zone-edit/hotel-zone-edit.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { PaginatorModule } from 'primeng/paginator'; + +const routes: Routes = [ + { + path: 'Search', + component: HotelZoneSearchComponent, + }, + { + path: 'Add', + component: HotelZoneAddComponent, + }, + { + path: 'Edit/:RuleId', + component: HotelZoneAddComponent, + }, +] + + +@NgModule({ + declarations: [ + HotelZoneSearchComponent, + HotelZoneAddComponent, + HotelZoneAddComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + FormsModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + PaginatorModule, + CalendarModule, + ToastModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes) + ] +}) +export class HotelZoneModule { } diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.html b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.html new file mode 100644 index 0000000..9f675d2 --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.html @@ -0,0 +1,268 @@ + +
    +
    +
    +

    Add Vehicle Master

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Type

    +
    + +
    +
    +
    + Select + {{vehicleType.key}} +
    + Please + select vehicle type +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + {{lang.LanguageName}} +
    + Please + select default language +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Passenger Capacity

    +
    + +
    +
    +
    + {{capacity}} +
    + Please + select max passenger capcity +
    +
    +
    +
    + + + Please + enter max luggage capcity +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Transfer Type

    +
    + +
    +
    +
    + Select + Private + Shared +
    + Please + select vehicle transfer type +
    +
    +
    +
    + + + +
    +
    +
    +

    Fuel Type

    +
    + +
    +
    +
    + Select + Petrol + Diesel + CNG + Electric +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Vendor

    +
    + +
    +
    +
    + Select + {{data.vehicleVendorName}} +
    +
    +
    +
    +
    +
    + Display Vehicle Image + + +
    + Note: Upload jpeg/png with max file size upto + 500kb. Height + 200px and Width 800px. +
    +
    +
    +
    +
    +
    +
    +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    + Vehicle Images + + +
    + Note: Upload jpeg/png with max file size upto + 500kb. Height + 200px and Width 800px. +
    +
    +
    +
    +
    +
    +
    +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.ts b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.ts new file mode 100644 index 0000000..620407e --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-add/vehicle-master-add.component.ts @@ -0,0 +1,252 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-vehicle-master-add', + templateUrl: './vehicle-master-add.component.html', +}) +export class VehicleMasterAddComponent implements OnInit { + Edit_Id: string; + VehicleForm: FormGroup; + AllLang; + transferVendorList; + fileInfo = []; + fileArr = []; + vehicleTypeList = [ + { key: 'Standard', value: 'STANDARD' }, + { key: 'Sedan', value: 'SEDAN' }, + { key: 'Minivan', value: 'MINIVAN' }, + { key: 'Minbus', value: 'MINBUS' }, + { key: 'Luxury Sedan', value: 'LUXURYSEDAN' }, + { key: 'Luxury Minivan', value: 'LUXURYMINIVAN' }, + { key: 'SUV', value: 'SUV' }, + { key: 'Minicoach', value: 'MINICOACH' }, + { key: 'Bus', value: 'BUS' } + ]; + passCapacityList = Array.from({ length: 100 }, (_, i) => i + 1); + editResp: any; + + constructor(public fb: FormBuilder, public validServ: ValidationService, private apiserv: API, private commonMasterSer: CommonFunctionService, private router: Router, private activateRoute: ActivatedRoute) { + + } + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initform(); + this.GetAllLAng(); + this.GetTransferVendor() + if (this.Edit_Id) { + this.GetById(); + } + } + GetAllLAng() { + this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId').subscribe(data => { + if (data) { + this.AllLang = data; + } + }) + } + GetTransferVendor() { + this.apiserv.Get('/ActivityVehicle/GetVehicleVendor').subscribe(res => { + if (res) { + this.transferVendorList = res.data; + } + }) + } + + initform() { + this.VehicleForm = this.fb.group({ + vehicleType: this.validServ.required, + defaultLanguageCode: this.validServ.required, + maxPassengerCapacity: this.validServ.required, + maxLuggageCapacity: this.validServ.required, + vehicleNumberPlate: '', + vehicleTransferType: this.validServ.required, + displayVehicleImage: '', + displayVehicleImageUrl: '', + vehicleImages: this.fb.control([]), + vehicleImagesUrl: this.fb.control([]), + fuelType: '', + vehicleName: '', + VehicleDescription: '', + vehicleVendorId: '', + }) + } + + SelectImage(e, filedata, contol) { + if (e.currentFiles.length != 0) { + for (let i = 0; i < e.files.length; i++) { + let file = e.files[i]; + if (file.size < 1048576 && (file.type == 'image/png' || file.type == 'image/jpeg')) { + const reader = new FileReader(); + console.log(file) + reader.readAsText(file); // Read as binary data + reader.onload = (res) => { + const binaryString = res.target.result as string; + const hasScriptTag = this.commonMasterSer.hasScriptTagInBinary(binaryString); + if (hasScriptTag) { + filedata.clear(); + this.commonMasterSer.showMessage(false, 'Invalid file (contains script tag)'); + } else { + //base 64 + if (contol == 'displayVehicleImage') { + this.VehicleForm.get(contol).setValue(file); + } else { + this.VehicleForm.get(contol).value.push(file); + } + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + if (contol == 'displayVehicleImage') { + this.VehicleForm.get('displayVehicleImageUrl').setValue(reader.result.toString()); + } else { + this.VehicleForm.get('vehicleImagesUrl').value.push(reader.result.toString()); + } + } + }; + } + } + } + } + + } + RemoveImage(ind, contol) { + if (contol == 'displayVehicleImage') { + this.VehicleForm.get(contol).setValue(''); + this.VehicleForm.get('displayVehicleImageUrl').setValue(''); + } else { + let image_url_list = this.VehicleForm.get(contol).value; + image_url_list.splice(ind, 1); + let image_display_url_list = this.VehicleForm.get('vehicleImagesUrl').value; + image_display_url_list.splice(ind, 1); + } + } + + GetById() { + this.apiserv.Get(`/ActivityVehicle/GetById/${this.Edit_Id}`).subscribe(res => { + if (res && res.status) { + this.editResp = res.data; + this.VehicleForm.get('vehicleType').setValue(this.editResp.vehicleType); + this.VehicleForm.get('defaultLanguageCode').setValue(this.editResp.defaultLanguageCode); + this.VehicleForm.get('maxPassengerCapacity').setValue(this.editResp.maxPassengerCapacity); + this.VehicleForm.get('maxLuggageCapacity').setValue(this.editResp.maxLuggageCapacity); + this.VehicleForm.get('vehicleNumberPlate').setValue(this.editResp.vehicleNumberPlate); + this.VehicleForm.get('vehicleTransferType').setValue(this.editResp.vehicleTransferType); + this.VehicleForm.get('fuelType').setValue(this.editResp.fuelType); + this.VehicleForm.get('vehicleName').setValue(this.editResp.activityVehicleDetails.vehicleName); + this.VehicleForm.get('vehicleVendorId').setValue(this.editResp.activityVehicleDetails.vehicleVendorId || ''); + this.VehicleForm.get('VehicleDescription').setValue(this.editResp.activityVehicleDetails.VehicleDescription); + if (this.editResp.vehicleImages) { + let Images_Arr = this.editResp.vehicleImages.split(','); + Images_Arr.forEach(data => { + this.VehicleForm.get('vehicleImages').value.push(data); + this.VehicleForm.get('vehicleImagesUrl').value.push(data); + }) + } + if (this.editResp.displayVehicleImage) { + this.VehicleForm.get('displayVehicleImage').setValue(this.editResp.displayVehicleImage); + this.VehicleForm.get('displayVehicleImageUrl').setValue(this.editResp.displayVehicleImage); + } + } + }) + } + + SaveUpdateVehicleDet() { + if (this.VehicleForm.status == "INVALID") { + this.validServ.showValidationsMsg(this.VehicleForm); + setTimeout(() => { + this.validServ.scrollToError(); + }, 50); + } else if (this.VehicleForm.status == "VALID") { + let formVal = this.VehicleForm.getRawValue(); + let postData = { + vehicleType: formVal.vehicleType, + ActivityVehicleId: this.Edit_Id ?? '', + defaultLanguageCode: formVal.defaultLanguageCode, + maxPassengerCapacity: formVal.maxPassengerCapacity.toString(), + maxLuggageCapacity: formVal.maxLuggageCapacity, + vehicleNumberPlate: formVal.vehicleNumberPlate, + vehicleTransferType: formVal.vehicleTransferType, + displayVehicleImage: formVal, + vehicleImages: formVal, + fuelType: formVal.fuelType, + vehicleVendorId: formVal.vehicleVendorId, + activityVehicleDetails: { + vehicleName: formVal.vehicleName, + VehicleDescription: formVal.VehicleDescription, + LanguageCode: formVal.defaultLanguageCode, + ActivityVehicleId: this.Edit_Id ?? '', + activityVehicleDetailsId: this.editResp ?this.editResp.activityVehicleDetails.activityVehicleDetailsId :'' + }, + } + let vehicleImages_arr = [] + formVal.vehicleImages.forEach((img_data, img_Ind) => { + if (typeof (img_data) == 'object' && img_data) { + let image_type = img_data.name.split('.'); + this.fileArr.push(img_data); + this.fileInfo.push({ 'fileName': "Extranet/Activity/Vehicle/ActivityVehicleId/vehicleImages_" + img_Ind + '.' + image_type[image_type.length - 1], 'pathToSave': 'OrganizationData/ORGID' }); + let image_url = `${environment.cdnFileUrl}OrganizationData/ORGID/Extranet/Activity/Vehicle/ActivityVehicleId/vehicleImages_${img_Ind}.${image_type[image_type.length - 1]}?t=${moment(new Date()).format("yyMMddHHmmssfffffff")}`; + vehicleImages_arr.push(image_url) + } else { + vehicleImages_arr.push(img_data); + } + }) + let thumbnail_image_url = ''; + if (typeof (formVal.displayVehicleImage) == 'object' && formVal.displayVehicleImage) { + let image_type = formVal.displayVehicleImage.name.split('.'); + this.fileArr.push(formVal.displayVehicleImage); + this.fileInfo.push({ 'fileName': "Extranet/Activity/Vehicle/ActivityVehicleId/DisplayImg" + '.' + image_type[image_type.length - 1], 'pathToSave': 'OrganizationData/ORGID' }); + thumbnail_image_url = `${environment.cdnFileUrl}OrganizationData/ORGID/Extranet/Activity/Vehicle/ActivityVehicleId/DisplayImg.${image_type[image_type.length - 1]}?t=${moment(new Date()).format("yyMMddHHmmssfffffff")}`; + } else { + thumbnail_image_url = formVal.displayVehicleImage; + } + postData['vehicleImages'] = vehicleImages_arr.length > 0 ? vehicleImages_arr.join(',') : ''; + postData['displayVehicleImage'] = thumbnail_image_url; + let url = this.Edit_Id ? `Update` : 'Save'; + this.apiserv.Post(`/ActivityVehicle/${url}`, postData).subscribe(resp => { + if (resp) { + if (this.fileInfo.length > 0 && resp.status) { + this.saveImg(this.fileInfo, this.fileArr, resp.data).subscribe(res => { + if (res && res.resp) { + this.BackButton(); + } + this.commonMasterSer.showMessage(resp.resp, resp.message) + }) + } else if (resp.status) { + this.BackButton(); + } + this.commonMasterSer.showMessage(resp.status, resp.message); + + } + }) + } + } + + saveImg(fileInfo, fileArr, edit_id) { + if (fileInfo && fileInfo.length > 0 && fileArr && fileArr.length > 0) { + var formdata = new FormData(); + fileArr.forEach((x) => { + formdata.append("files", x); + }); + let file_info_list = JSON.stringify(fileInfo).replaceAll('ActivityVehicleId', edit_id); + formdata.append("fileInfo", file_info_list); + return this.apiserv.PostFile("/FileUpload/SaveFile", formdata); + } else { + return of({ + resp: true, + respMsg: "No images to save" + }); + } + } + BackButton() { + this.router.navigateByUrl(`ActivityConfiguration/VehicleMaster/Search`); + } + +} diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.html b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.html new file mode 100644 index 0000000..19af44e --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.html @@ -0,0 +1,109 @@ + +
    +
    +
    +

    Manage Translation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + {{lang.LanguageName}} +
    + Please + select language +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Default Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Selected Language Content

    +
    +
    +
    +
    +
    +
    + + + Please + enter vehicle name +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.ts b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.ts new file mode 100644 index 0000000..ee9cf03 --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-language/vehicle-master-language.component.ts @@ -0,0 +1,111 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-vehicle-master-language', + templateUrl: './vehicle-master-language.component.html', +}) +export class VehicleMasterLanguageComponent implements OnInit { + Edit_Id: string; + VehicleManageLangForm:FormGroup; + AllLang: any; + editResp: any; + + + constructor(public fb: FormBuilder, public validServ: ValidationService, private apiserv: API, private commonMasterSer: CommonFunctionService, private router: Router, private activateRoute: ActivatedRoute) { + + } + + ngOnInit(): void { + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initform(); + this.GetAll(); + } + + GetAll(){ + forkJoin( + this.GetAllLAng(), + this.GetById(this.Edit_Id) + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllLang = res[0]; + if(res[1] && res[1].status){ + this.editResp = res[1].data; + this.VehicleManageLangForm.get('defaultvehicleName').setValue(this.editResp.activityVehicleDetails.vehicleName); + this.VehicleManageLangForm.get('defaultVehicleDescription').setValue(this.editResp.activityVehicleDetails.vehicleDescription); + const index = this.AllLang.findIndex(lang => lang.LanguageCode === this.editResp.defaultLanguageCode); + this.VehicleManageLangForm.get('defaultLanguageCode').setValue(this.AllLang[index].LanguageName); + if(index !== -1){ + this.AllLang.splice(index, 1); + } + } + } + }) + } + GetAllLAng() { + return this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId') + } + + initform() { + this.VehicleManageLangForm = this.fb.group({ + defaultvehicleName: '', + defaultVehicleDescription: '', + defaultLanguageCode: '', + languageCode: this.validServ.required, + vehicleName: this.validServ.required, + vehicleDescription: '', + activityVehicleDetailsId:'' + }) + } + + GetById(Editid) { + if (Editid) + return this.apiserv.Get('/ActivityVehicle/GetById/' + Editid) + else + return of(null) + }; + + saveTranslation(){ + if (this.VehicleManageLangForm.status == "INVALID") { + this.validServ.showValidationsMsg(this.VehicleManageLangForm); + setTimeout(() => { + this.validServ.scrollToError(); + }, 50); + } else if (this.VehicleManageLangForm.status == "VALID") { + let formVal = this.VehicleManageLangForm.getRawValue(); + let postData = { + activityVehicleDetailsId:formVal.activityVehicleDetailsId ?? '', + activityVehicleId:this.Edit_Id, + languageCode:formVal.languageCode, + vehicleName:formVal.vehicleName, + VehicleDescription:formVal.VehicleDescription ?? '', + } + this.apiserv.Post('/ActivityVehicle/ManageTranslationActivityVehicleDetails', postData).subscribe(resp=>{ + this.commonMasterSer.showMessage(resp.status, resp.message) + if(resp.status){ + this.BackButton(); + } + }) + } + } + + getDataByLang(){ + let langCode = this.VehicleManageLangForm.get('languageCode').value; + this.apiserv.Get(`/ActivityVehicle/GetActivityVehicleDetailsByIdAndLangCode/${this.Edit_Id}/${langCode}`).subscribe(res=>{ + if(res && res.data){ + this.VehicleManageLangForm.get('vehicleName').setValue(res.data.vehicleName); + this.VehicleManageLangForm.get('vehicleDescription').setValue(res.data.vehicleDescription); + this.VehicleManageLangForm.get('activityVehicleDetailsId').setValue(res.data.activityVehicleDetailsId); + } + }) + } + + BackButton() { + this.router.navigateByUrl(`ActivityConfiguration/VehicleMaster/Search`); + } +} diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.html b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.html new file mode 100644 index 0000000..1f05927 --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.html @@ -0,0 +1,234 @@ +
    +
    +
    +

    Vehicle Search

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Type

    +
    + +
    +
    +
    + Select + {{vehicleType.key}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Transfer Type

    +
    + +
    +
    +
    + Select + Private + Shared +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Vehicle Id + + + + Vehicle Type + + + + Max Passenger Capacity + + + + Max Luggage Capacity + + + + Vehicle Supplier + + + + Vehicle Transfer Type + + + + Vehicle Name + + + + Vehicle Number Plate + + + + Fuel Type + + + + Status + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + {{data.activityVehicle_id}} + + {{data.vehicleType}} + {{data.maxPassengerCapacity}} + {{data.maxLuggageCapacity}} + + {{data.vehicleTransferType}} + {{data.vehicleName}} + {{data.vehicleNumberPlate}} + {{data.fuelType}} + + + {{data.status}} + + + {{data.createdBy}} + {{data.Custom_created_on}} + {{data.updatedBy}} + {{data.Custom_updated_on}} + + + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.ts b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.ts new file mode 100644 index 0000000..2a281ba --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master-search/vehicle-master-search.component.ts @@ -0,0 +1,102 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-vehicle-master-search', + templateUrl: './vehicle-master-search.component.html', +}) +export class VehicleMasterSearchComponent implements OnInit { + + Result; + cols; + vehicleSearchForm:FormGroup; + vehicleTypeList = [ + { key: 'Standard', value: 'STANDARD' }, + { key: 'Sedan', value: 'SEDAN' }, + { key: 'Minivan', value: 'MINIVAN' }, + { key: 'Minbus', value: 'MINBUS' }, + { key: 'Luxury Sedan', value: 'LUXURYSEDAN' }, + { key: 'Luxury Minivan', value: 'LUXURYMINIVAN' }, + { key: 'SUV', value: 'SUV' }, + { key: 'Minicoach', value: 'MINICOACH' }, + { key: 'Bus', value: 'BUS' } + ]; + + constructor(public fb: FormBuilder, private apiserv: API, public commonMasterSer: CommonFunctionService, private router: Router) {} + + ngOnInit(): void { + this.cols = [ + { field: 'activityVehicle_id', header: 'Vehicle Id' }, + { field: 'vehicleType', header: 'Vehicle Type' }, + { field: 'maxPassengerCapacity', header: 'Max Passenger Capacity' }, + { field: 'maxLuggageCapacity', header: 'Max Luggage Capacity' }, + { field: 'maxLuggageCapacity', header: 'Vehicle Supplier' }, + { field: 'vehicleTransferType', header: 'Vehicle Transfer Type' }, + { field: 'vehicleName', header: 'Vehicle Name' }, + { field: 'vehicleNumberPlate', header: 'Vehicle Number Plate' }, + { field: 'fuelType', header: 'Fuel Type' }, + { field: 'status', header: 'Status' }, + { field: 'createdBy', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updatedBy', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.initform(); + } + + initform(){ + this.vehicleSearchForm = this.fb.group({ + vehicleType:'', + vehicleTransferType:'', + maxPassengerCapacity:'', + maxLuggageCapacity:'' + }) + } + + Search(){ + let val = this.vehicleSearchForm.getRawValue(); + let ReqObj = { + vehicleType: val.vehicleType ? val.vehicleType : '', + vehicleTransferType: val.vehicleTransferType ? val.vehicleTransferType : '', + maxPassengerCapacity: val.maxPassengerCapacity ? val.maxPassengerCapacity : '', + maxLuggageCapacity: val.maxLuggageCapacity ? val.maxLuggageCapacity : '', + } + this.apiserv.Post('/ActivityVehicle/GetAll', ReqObj).subscribe(res => { + if (res) { + this.Result = res.data ? res.data :[]; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.isActive ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this.commonMasterSer.convertDateWithTimeToShow(e.updatedOn); + e['Custom_created_on'] = e['createdOn'] ? this.commonMasterSer.convertDateWithTimeToShow(e.createdOn) : e['createdOn']; + }); + } + } + }) + } + + Reset(){ + this.vehicleSearchForm.reset(); + } + Edit(Id){ + this.router.navigateByUrl(`ActivityConfiguration/VehicleMaster/Edit/${Id}`); + } + ManageLang(Id){ + this.router.navigateByUrl(`ActivityConfiguration/VehicleMaster/Language/${Id}`); + } + updateStatus(id, val) { + let obj = { + id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ActivityVehicle/UpdateStatus', obj).subscribe(res => { + if (res) { + this.commonMasterSer.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } +} diff --git a/src/app/modules/services/activity-config/vehicle-master/vehicle-master.module.ts b/src/app/modules/services/activity-config/vehicle-master/vehicle-master.module.ts new file mode 100644 index 0000000..fe403b3 --- /dev/null +++ b/src/app/modules/services/activity-config/vehicle-master/vehicle-master.module.ts @@ -0,0 +1,66 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { VehicleMasterAddComponent } from './vehicle-master-add/vehicle-master-add.component'; +import { VehicleMasterLanguageComponent } from './vehicle-master-language/vehicle-master-language.component'; +import { VehicleMasterSearchComponent } from './vehicle-master-search/vehicle-master-search.component'; + +const routes: Routes = [ + { + path: 'Search', + component: VehicleMasterSearchComponent, + }, + { + path: 'Add', + component: VehicleMasterAddComponent, + }, + { + path: 'Language/:RuleId', + component: VehicleMasterLanguageComponent, + }, + { + path: 'Edit/:RuleId', + component: VehicleMasterAddComponent, + }, +] + +@NgModule({ + declarations: [ + VehicleMasterSearchComponent, + VehicleMasterAddComponent, + VehicleMasterLanguageComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes) + ] +}) +export class VehicleMasterModule { } diff --git a/src/app/modules/services/activity-services/activity-services.module.ts b/src/app/modules/services/activity-services/activity-services.module.ts new file mode 100644 index 0000000..c67f425 --- /dev/null +++ b/src/app/modules/services/activity-services/activity-services.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +// import { ExpServicesComponent } from './exp-services/exp-services.component'; +const routes: Routes = [ + { + path: 'ExpServices', + loadChildren: () => + import('./exp-services/exp-services.module').then( + (m) => m.ExpServicesModule + ), + }, + { + path: 'HotelZone', + loadChildren: () => + import('./hotel-zone-services/hotel-zone-services.module').then( + (m) => m.HotelZoneServicesModule + ), + }, + + { + path: '', + pathMatch: 'full', + redirectTo: 'search', + }, +]; +@NgModule({ + declarations: [], + imports: [CommonModule, RouterModule.forChild(routes)], +}) +export class ActivityServicesModule {} diff --git a/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.html b/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.html new file mode 100644 index 0000000..2693514 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.html @@ -0,0 +1,236 @@ +
    + + Back +
    +
    Experience Manage Translation
    +
    +
    +
    +
    + + + +
    + +
    Service Language
    +
    + +
    +
    +
    +
    + + + +
    + +
    Service Language
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    Default Language Content
    +
    Selected Language Content
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + Day Wise Itinerary +
    +
    + Day Wise Itinerary +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.ts b/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.ts new file mode 100644 index 0000000..7da584a --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-manage-translation/exp-manage-translation.component.ts @@ -0,0 +1,196 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { ActivityContent } from 'src/app/core/models/Experience-Service/experience-manage-languag/experience-manage-lang.model'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-exp-manage-translation', + templateUrl: './exp-manage-translation.component.html', +}) +export class ExpManageTranslationComponent implements OnInit { + + constructor(private ApiServ: API, private router: Router, public MsgService : MessageService ,private route: ActivatedRoute, public fb: FormBuilder) { } + formdata: FormGroup + ServiceLanguages; + Languages; + ngOnInit(): void { + this.GetLOVLanguage(); + this.GetDefaultActivity(); + this.formdata = this.fb.group({ + language_code: [''], + def_language_code: [''], + activity_name: [''], + def_activity_name: [''], + departure_point: [''], + def_departure_point: [''], + meeting_point: [''], + def_meeting_point: [''], + drop_point: [''], + def_drop_point: [''], + activity_highlight: [''], + def_activity_highlight: [''], + activity_description: [''], + def_activity_description: [''], + activity_restriction: [''], + def_activity_restriction: [''], + activities_details: [''], + def_activities_details: [''], + activity_inclusion: [''], + def_activity_inclusion: [''], + activity_exclusion: [''], + def_activity_exclusion: [''], + additional_pick_up_details: [''], + def_additional_pick_up_details: [''], + daywise_itinerary: this.fb.array([]), + }) + } + + + /** + * @author Abdul Razzak + * to get LOV data + */ + GetLOVLanguage() { + let formdata = { + "lov_types": [{ "lov_type": "Language" }], + "lov_lang": "en" + } + this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + if (data) { + console.log(data) + this.ServiceLanguages = data['responseObject']['0']['keys']; + this.Languages = data['responseObject']['0']['keys']; + } + }); + }; + + // GetActivityContent() { + // this.ApiServ.Get('/Activity/GetActivityContent/') + // } + activity_id; + GetDefaultActivity() { + this.route.queryParams.subscribe(d => { + if (d['id']) { + this.activity_id = d['id'] + this.GetActivityDetails(d['id'],'','def_'); + } + }); + }; + + getactivity(){ + let lang = this.formdata.get('language_code').value; + this.GetActivityDetails(this.activity_id , lang , false); + } + GetActivityDetails(Id,lang,check){ + this.ApiServ.Get('/Activity/GetActivityContent/' + Id + '?LangCode=' + lang).subscribe(data => { + if (data) { + console.log(data,) + this.Setvalue(data.responseObject, check) + } + }); + } + Setvalue(data, check) { + let value = this.formdata.getRawValue() + Object.keys(value).forEach(e => { + let controlname = check ? check + e : e; + if ( e == 'activity_name' || e == 'departure_point' + || e == 'meeting_point' + || e == 'additional_pick_up_details' + || e == 'drop_point' || e == 'activity_highlight' || e == 'activity_description' + || e == 'activity_restriction' || e == 'activities_details' || e == 'activity_inclusion' || e == 'activity_exclusion' + ) { + this.formdata.get(controlname).setValue(data ? data[e] : ''); + }else if(e == 'language_code'){ + if(check){ + debugger + this.formdata.get(controlname).setValue(data ? data[e] : ''); + let list = this.Languages + let ind = this.Languages.findIndex(d => d.lov_value == data[e]); + list.splice(ind, 1); + this.Languages = [...list] + } + } else if (e == 'daywise_itinerary') { + if(data){ + let daywiseObj = JSON.parse(data[e]); + if (daywiseObj.length > 0 && daywiseObj) { + daywiseObj.forEach((e, l) => { + check ? this.CreateitineraryGroup(e) : ''; + let html = check ? check + 'Text_html' : 'Text_html'; + this.formdata.get('daywise_itinerary')['controls'][l].get(html).setValue(data ? e.Text_html : ''); + }) + } + } else this.cleardayswiseitinerary() + } + }) + } + + cleardayswiseitinerary(){ + this.formdata.get('daywise_itinerary')['controls'].forEach(e => { + e.get('Text_html').setValue(''); + }) + }; + + CreateitineraryGroup(data) { + let controller = this.formdata.get('daywise_itinerary') as FormArray; + controller.push(this.fb.group({ + Text_html: [], + def_Text_html: [], + city_code: [data.city_code], + country_code: [data.country_code], + })); + }; + + SaveActivityLang(){ + let value = this.formdata.getRawValue(); + let postdata = new ActivityContent(); + postdata.activity_id = this.activity_id; + postdata.activity_name = value.activity_name; + postdata.supplier_id = '1232'; + postdata.language_code = value.language_code; + postdata.departure_point = value.departure_point; + postdata.meeting_point = value.meeting_point; + postdata.additional_pick_up_details = value.additional_pick_up_details; + postdata.drop_point = value.drop_point; + postdata.activity_highlight = value.activity_highlight; + postdata.activity_description = value.activity_description; + postdata.activity_restriction = value.activity_restriction; + postdata.activities_details = value.activities_details; + postdata.activity_inclusion = value.activity_inclusion; + postdata.activity_exclusion = value.activity_exclusion; + let dayswiseitinerary = [] + + if(value.daywise_itinerary){ + value.daywise_itinerary.forEach(e => { + dayswiseitinerary.push({ + 'Text_html' : e.Text_html, + 'country_code' : e.country_code, + 'city_code' : e.city_code, + }) + }) + } + postdata.daywise_itinerary = JSON.stringify(dayswiseitinerary); + this.ApiServ.Post('/Activity/SaveContentDetails' ,postdata).subscribe((res) => { + if(res){ + this.showToastrMsg(res); + } + }); + }; + + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + }; + + btnClick() { + this.router.navigateByUrl("/Services/ActivityServices/ExpServices/Search"); + }; + +} + diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.html new file mode 100644 index 0000000..4bebddd --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.html @@ -0,0 +1,802 @@ +
    + + Back +
    +
    +
    Add Experience
    +
    +
    +
    + + + Please enter experience name + +
    +
    +
    +
    + + + + Please select experience category + +
    +
    + + + + Please select experience sub category + +
    +
    + +
    +
    + + + Please select + phone + code + +
    +
    + + Please enter + phone number + + accept only + number + +
    +
    +
    +
    +
    +
    + + + + Please select service language + +
    +
    + + + {{ item.lov_value }} + + Please select default language + +
    +
    + +
    +
    + + + Please select days + +
    +
    + + + Please select hours + +
    +
    + + + Please select minutes + +
    +
    +
    +
    +
    +
    + + + + Please + select country + +
    +
    + + + + Please select city + +
    +
    + + + +
    + +
    Starting City
    +
    + +
    +
    + Please select starting city + +
    +
    +
    +
    + + + + Please select pickup included + +
    +
    + + + + + Please select pickup point + +
    +
    + + + + + Please select hotel pickup + +
    +
    +
    + +
    + + + + +
    +
    +
    +
    +
    +
    + + + + + Please select hotels + +
    +
    + +
    + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + +
    +
    +
    + +
    +
    + + + Please enter departure point + +
    +
    + +
    + + + + +
    +
    +
    +
    +
    + + + Please enter meeting point +
    +
    + +
    +
    + + + Please select hours + +
    +
    + + + Please select minutes +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + + + Please enter drop off point + +
    +
    +
    +
    + + + + + Please select min travelers + +
    +
    + + + + + Please select Max travelers + +
    +
    + +
    + +
    Adult
    +
    +
    + +
    + + + + + +
    +
    +
    +
    + +
    Senior
    +
    +
    + +
    + + + + + + +
    +
    +
    +
    + +
    Youth
    +
    +
    + +
    + + + + + + +
    +
    +
    +
    + +
    Child
    +
    +
    + +
    + + + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + + + +
    +
    +
    +
    + +
    Child Seat Included
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    Day Wise Itinerary
    +
    +
    +
    +
    + +
    + +
    +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    + Please choose image +
    +
    + +
    + + +
    +
    +
    +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + + +
    +
    +
    +
    +
    +
    Traveler Required Information
    +
    +
    +
    + {{group.get('header_name').value }} + +
    +
    + {{item.get('requirement_name').value }} + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.ts new file mode 100644 index 0000000..e2803c7 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-add/exp-services-add.component.ts @@ -0,0 +1,971 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { Observable, ReplaySubject } from 'rxjs'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ActivityContent, experience_add } from 'src/app/core/models/Experience-Service/experience-sevice-add/experience-service-add.model'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-exp-services-add', + templateUrl: './exp-services-add.component.html', +}) +export class ExpServicesAddComponent implements OnInit { + + selectedCities: string[] = []; + uploadedFiles: any[] = []; + // + user_id = '2205290611511299310' + // + formData: FormGroup; + Experience_Type; + SubCategory; + Service_Language; + CategroyDetails; + activity_id; + AllHotelContent; + HotelPickupPointType; + HotelPickupType; + showThumbnailImg: boolean; + allCityDetials = []; + Allstartingcity = []; + sequence = []; + AdultNoArray = []; + childNoArray = []; + InfantNoArray = []; + SaveBtn = false; + AllCountry; + AllActivityHotelZone; + PhoneCode; + constructor( + private messageService: MessageService, + public ApiServ: API, + public Fb: FormBuilder, + private route: ActivatedRoute, + private router: Router, + public validationService: ValidationService, + public CommonVari: StaticDataService + ) { } + + + ngOnInit(): void { + + this.GetCountryPhone(); + this.agelength(); + this.showThumbnailImg = false + this.ngOinitForm(); + this.allCityDetials.push(''); + this.GetAllRequirementView(); + this.GetLOVLanguage(); + this.getexperienceCate(); + this.GetAllHotel(); + this.GetLOVHotelPickupPointType(); + this.GetLOVHotelPickupType(); + this.getCountry(); + this.PickupIncludes('No'); + this.GetAllActivityHotelZone(); + this.getID(); + } + + + ngOinitForm(){ + this.formData = this.Fb.group({ + activity_name: this.validationService.required, + category_id: this.validationService.required, + Sub_Category: this.validationService.required, + emergency_phone_nbr: this.validationService.mobNo, + emergency_phone_code: this.validationService.required, + default_lang_code: this.validationService.required, + _service_language: this.validationService.required, + service_days: this.validationService.required, + service_hours: this.validationService.required, + service_minutes: this.validationService.required, + country_code: this.validationService.required, + starting_city: this.validationService.required, + city_id: this.validationService.required, + is_pickup_included: this.validationService.required, + additional_pick_up_details: [''], + Requirment: this.Fb.array([]), + pickup_hotel: [''], + is_drop_included: ['No'], + drop_point: [''], + min_pax: this.validationService.required, + max_pax: this.validationService.required, + + is_adult: [true], + adult_age_from: this.validationService.required, + adult_age_to: this.validationService.required, + + is_senior: [false], + senior_age_from: [null], + senior_age_to: [null], + + is_youth: [false], + youth_age_from: [null], + youth_age_to: [null], + + is_child: [false], + child_age_from: [null], + child_age_to: [null], + + max_child_count: [''], + free_child_age_from: [null], + free_child_age_to: [null], + is_child_seat: [false], + Itinerary: this.Fb.array([ + ]), + activity_highlight: [''], + activity_description: [''], + activity_restriction: [''], + activities_details: [''], + activity_inclusion: [''], + activity_exclusion: [''], + VideoURL: this.Fb.array([ + this.Fb.group({ activity_videos: [''] }) + ]), + thumnailImg: this.validationService.required, + images: this.Fb.array([]), + }) + } + getCountry() { + this.ApiServ.Get('/Country/GetCountry').subscribe(data => { + if (data) { + this.AllCountry = data; + } + }); + }; + + GetStartingCity(check) { + let val = this.formData.getRawValue(); + let allcity = []; + val.city_id.forEach(e => { + let city = this.allCityDetials[0].filter(a => a.city_id == e) + allcity.push(...city); + }); + this.Allstartingcity = allcity; + if (val.city_id.length > 1) { + check ? this.formData.get('starting_city').setValue('') : ''; + } else { + this.formData.get('starting_city').setValue(val.city_id.join(',')) + } + }; + + getID() { + this.route.queryParams.subscribe(d => { + if (d['id']) { + this.activity_id = d['id'] + this.ApiServ.Get('/Activity/GetActivity/' + d['id']).subscribe(data => { + if (data) { + this.AllSetvalue(data['responseObject']); + } + }); + } + }); + }; + getcity(countryId, check, ind , startcity) { + this.allCityDetials[ind] = []; + this.allCityDetials[ind].push(...[]); + let countrycode; + if (check == 'set') countrycode = countryId; + else { + let country_code = []; + countryId.map(d => { + country_code.push(d.alpha_2_code); + }); + countrycode = country_code; + } + if (check == 'CountryManda') this.formData.get('city_id').setValue(''); + if (countrycode.length > 0) { + this.ApiServ.Get('/City/GetCity/' + countrycode.join(',')).subscribe(data => { + if (data) { + this.allCityDetials[ind] = []; + this.allCityDetials[ind].push(...data); + startcity ? this.GetStartingCity(false) : ''; + } + }); + } + }; + + getexperienceCate() { + this.ApiServ.Get('/ActivityCategoryMaster/GetAllCategory').subscribe(data => { + if (data) { + this.Experience_Type = data['responseObject'] + } + }); + }; + + GetCountryPhone() { + this.ApiServ.Get('/CountryPhone/GetCountryPhone').subscribe(data => { + if (data) { + this.PhoneCode = data + } + }); + }; + + AllSetvalue(d) { + let value = this.formData.getRawValue() + Object.keys(value).forEach(e => { + if (e == 'thumnailImg') { + this.formData.get(e).setValue(d['thumbnail_image']) + d['thumbnail_image'] != "" ? this.showThumbnailImg = true : this.showThumbnailImg = false + } else if (e == 'images') { + let multiImgs = JSON.parse(d['activity_images']) + this.setmultiimage(multiImgs); + } else if (e == 'category_id') { + this.formData.get(e).setValue(d['category_id']); + let sub_category_id = d['sub_category_id'].split(','); + this.GetSubCategory(d['category_id']); + setTimeout(() => { + this.formData.get('Sub_Category').setValue(sub_category_id); + }, 50); + } else if (e == "country_code") { + let value = d[e] ? d[e].split(",") : null; + this.getcity(value, 'set', 0 , true); + this.formData.get(e).setValue(value); + let city = d['city_id'] ? d['city_id'].split(",") : null; + this.formData.get('city_id').setValue(city); + + this.formData.get('starting_city').setValue(d['starting_city']); + } + else if (e == '_service_language') { + let value = d[e] ? d[e].split(",") : null; + this.formData.get(e).setValue(value); + } else if (e == 'default_lang_code') { + this.formData.get(e).setValue(d[e]); + } + else if (e == 'VideoURL') { + this.setUrlLink(d['activity_videos']); + } + else if (e == 'activity_name' || e == 'departure_point' || e == 'activity_highlight' + || e == 'activity_description' || e == 'activity_restriction' || e == 'activities_details' || + e == 'activity_exclusion' || e == 'activity_inclusion' || e == 'drop_point' || e == 'additional_pick_up_details') { + this.formData.get(e).setValue(d['activityContents'][0][e] ? d['activityContents'][0][e] : ""); + } + else if (e == 'is_drop_included') { + if (e == 'is_drop_included') { + this.formData.get(e).setValue(d[e] ? 'Yes' : 'No'); + this.dropoffvalid(d[e] ? 'Yes' : 'No'); + } + } else if (e == 'is_pickup_included') { + this.formData.get(e).setValue(d[e] ? 'Yes' : 'No'); + this.PickupIncludes(d[e] ? 'Yes' : 'No'); + if (!d[e]) { + this.formData.get('meeting_before_hour').setValue(d['meeting_before_hour']); + this.formData.get('meeting_before_minute').setValue(d['meeting_before_minute']); + this.formData.get('meeting_point').setValue(d['activityContents'][0]['meeting_point']); + } else if (d[e]) { + this.formData.get('_pickup_point_type').setValue(parseInt(d['_pickup_point_type'])) + this.PickupPointValid(); + if (d['_pickup_point_type'] == '2') { + this.formData.get('departure_point').setValue(d['activityContents'][0]['departure_point']) + this.formData.get('departure_hour').setValue(d['pickup_before_hour']) + this.formData.get('departure_minute').setValue(d['pickup_before_minute']) + } else if (d['_pickup_point_type'] == '1') { + this.formData.get('_hotel_pickup_type').setValue(parseInt(d['_hotel_pickup_type'])); + this.Hotel_Type_AddPickupValid(); + if (d['_hotel_pickup_type'] == '1') { + this.formData.get('All_Hotel_hour').setValue(d['pickup_before_hour']) + this.formData.get('All_Hotel_minute').setValue(d['pickup_before_minute']) + } else if (d['_hotel_pickup_type'] == '2') { + let pickup_hotel = d['pickup_hotel'].split(','); + this.formData.get('pickup_hotel').setValue(pickup_hotel); + this.formData.get('Specific_Hotel_hour').setValue(d['pickup_before_hour']); + this.formData.get('Specific_Hotel_minute').setValue(d['pickup_before_minute']); + } else if (d['_hotel_pickup_type'] == '3') { + let hotel_zone = d['hotel_zone'].split(','); + this.formData.get('hotel_zone').setValue(hotel_zone); + this.formData.get('hotel_zone_hour').setValue(d['pickup_before_hour']); + this.formData.get('hotel_zone_minute').setValue(d['pickup_before_minute']); + } + } + } + } else if (e == "is_adult" || e == "is_senior" || e == "is_youth" || e == "is_child") { + if (e == "is_adult" && d['is_adult']) { + this.formData.get(e).setValue(d[e]); + this.adultValid(d[e]); + this.formData.get('adult_age_from').setValue(d['adult_age_from']); + this.formData.get('adult_age_to').setValue(d['adult_age_to']); + } else if (e == "is_senior" && d['is_senior']) { + this.formData.get(e).setValue(d[e]); + this.SeniorValid(d[e]); + this.formData.get('senior_age_from').setValue(d['senior_age_from']); + this.formData.get('senior_age_to').setValue(d['senior_age_to']); + } else if (e == "is_youth" && d['is_youth']) { + this.formData.get(e).setValue(d[e]); + this.YouthValid(d[e]); + this.formData.get('youth_age_from').setValue(d['youth_age_from']); + this.formData.get('youth_age_to').setValue(d['youth_age_to']); + } else if (e == "is_child" && d['is_child']) { + this.formData.get(e).setValue(d[e]); + this.ChildValid(d[e]); + this.formData.get('child_age_from').setValue(d['child_age_from']); + this.formData.get('child_age_to').setValue(d['child_age_to']); + } + } else if (e == 'Requirment') { + let required = d['requirements'] ? d['requirements'].split(',') : false; + if (required) { + this.Requirment.controls.forEach(x => { + Object.keys(x['controls']).forEach(l => { + let check = required.filter(m => m == x.get('header_id').value); + if (check.length > 0) { + x.get('is_header').setValue(true); + x.get('requirements')['controls'].forEach(re => { + Object.keys(re['controls']).forEach(li => { + let check = required.filter(m => m == re.get('requirement_id').value); + if (check.length > 0) re.get('is_requirement').setValue(true); + }) + }); + } + }) + }) + } + } + else if (e == 'max_pax' || e == 'min_pax' || e == 'emergency_phone_nbr' || e == 'emergency_phone_code' || e == 'service_minutes' || + e == 'service_hours' || e == 'is_child_seat' || e == 'max_child_count' + || e == 'free_child_age_to' || e == 'free_child_age_from') { + this.formData.get(e).setValue(d[e]); + } else if (e == 'service_days') { + this.formData.get(e).setValue(d[e]); + this.DaysItineryForm(d[e]); + let obj = JSON.parse(d['activityContents'][0]['daywise_itinerary']); + obj.forEach((z, i) => { + Object.keys(z).forEach((q) => { + if (q == 'Text_html') { + this.Itinerary.controls[i].get(q).setValue(z[q]); + } else if (q == 'country_code') { + this.Itinerary.controls[i].get(q).setValue(z[q]); + this.getcity(z[q], 'set', i + 1 , false); + this.Itinerary.controls[i].get('city_code').setValue(z['city_code']); + } + }) + }) + } + }); + }; + + + setUrlLink(URL) { + let val = JSON.parse(URL); + val.map((valLi, i) => { + i != 0 ? this.addvideo() : ""; + this.VideoURl.controls[i].get('activity_videos').setValue(valLi.activity_videos); + }); + }; + setmultiimage(image) { + this.MultiImageGallery = []; + image.map((valLi, i) => { + this.addPackageImgGallery(); + this.ImgGallery.controls[i].get('image_url').setValue(valLi.image_url); + this.MultiImageGallery.push(valLi.image_url); + }); + } + + + // get form controls + + get allFormGroup() { + return this.formData.getRawValue(); + }; + get VideoURl() { + return this.formData.get('VideoURL') as FormArray; + }; + get Requirment() { + return this.formData.get('Requirment') as FormArray; + }; + // GetDetailsByID(id) { + // this.ApiServ.Get('/GetHotel/{Id}') + // } + + GetAllHotel() { + this.ApiServ.Get('/HotelContent/GetAllHotelContent').subscribe(data => { + if (data) { + this.AllHotelContent = data['responseObject']; + } + }); + }; + + GetSubCategory(value) { + this.formData.get('Sub_Category').setValue('') + this.ApiServ.Get('/ActivityCategoryMaster/GetSubCategory?Id=' + value).subscribe(data => { + if (data) { + this.SubCategory = data['responseObject'] + } + }); + }; + + GetLOVHotelPickupPointType() { + let formdata = { + "lov_types": [{ "lov_type": "HotelPickupPointType" }], + "lov_lang": "en" + } + this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + if (data) { + console.log(data) + this.HotelPickupPointType = data['responseObject']['0']['keys'] + console.log(this.HotelPickupPointType) + } + }); + }; + requirementCheck(check, formgroup) { + if (check) { + formgroup.get('requirements').controls.forEach(e => { + e.get('is_requirement').setValue(true); + }) + } else { + formgroup.get('requirements').controls.forEach(e => { + e.get('is_requirement').setValue(false); + }) + } + } + + + GetLOVHotelPickupType() { + let formdata = { + "lov_types": [{ "lov_type": "HotelPickupType" }], + "lov_lang": "en" + } + this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + if (data) { + console.log(data) + this.HotelPickupType = data['responseObject']['0']['keys'] + console.log(this.HotelPickupPointType) + } + }); + }; + + GetLOVLanguage() { + let formdata = { + "lov_types": [{ "lov_type": "Language" }], + "lov_lang": "en" + } + this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + if (data) { + console.log(data) + this.Service_Language = data['responseObject']['0']['keys'] + console.log(this.Service_Language) + } + }); + }; + + // save + + SaveFormData() { + let value = this.formData.getRawValue(); + if (this.formData.status == "INVALID") { + this.validationService.showValidationsMsg(this.formData); + const firstElementWithError = document.querySelector('.ng-invalid'); + if (firstElementWithError) { + firstElementWithError.scrollIntoView({ behavior: 'smooth' }); + } + return; + } + this.SaveBtn = true; + + let org_id = '2105311837100000021'; + let supplier_id = '2205221841391724322'; + + let dataArr = []; + let postArrayData = new ActivityContent(); + postArrayData.activity_name = value.activity_name; + postArrayData.meeting_point = value.is_pickup_included == 'No' ? value.meeting_point : ''; + postArrayData.drop_point = value.is_drop_included == 'Yes' ? value.drop_point : ""; + postArrayData.activity_highlight = value.activity_highlight; + postArrayData.activity_description = value.activity_description; + postArrayData.activity_restriction = value.activity_restriction; + postArrayData.activities_details = value.activities_details; + postArrayData.activity_inclusion = value.activity_inclusion; + postArrayData.activity_exclusion = value.activity_exclusion; + postArrayData.org_id = org_id; + let daysiternery = this.Itinerary.getRawValue(); + postArrayData.daywise_itinerary = JSON.stringify(daysiternery); + postArrayData.additional_pick_up_details = value.additional_pick_up_details; + + postArrayData.language_code = 'EN'; // + postArrayData.supplier_id = supplier_id; // + dataArr.push(postArrayData) + + // undefine hardcode + postArrayData.activity_content_id = ''; + postArrayData.activity_id = this.activity_id ? this.activity_id : ""; + postArrayData.created_by = 'Razzak'; + postArrayData.updated_by = 'Razzak'; + // + + // + let PostData = new experience_add(); + PostData.org_id = org_id; + PostData.category_id = value.category_id; + PostData._pickup_point_type = value.is_pickup_included == 'Yes' ? value._pickup_point_type.toString() : ''; + PostData._service_language = value._service_language.join(","); + PostData.default_lang_code = value.default_lang_code; + PostData.emergency_phone_code = value.emergency_phone_code; + PostData.emergency_phone_nbr = value.emergency_phone_nbr; + + PostData.service_days = value.service_days; + PostData.service_hours = value.service_hours; + PostData.service_minutes = value.service_minutes; + PostData.supplier_id = supplier_id; // + PostData.activity_id = this.activity_id ? this.activity_id : ""; + + // undefined hardcode + PostData.sub_category_id = value.Sub_Category.join(","); + PostData.activity_content_json = ''; + PostData.category_name = ''; + + this.Requirment.getRawValue(); + let AllReqirement = this.Requirment.getRawValue(); + let All_Id = []; + AllReqirement.forEach(e => { + if (e.is_header) { + All_Id.push(e.header_id); + if (e.requirements) { + e.requirements.forEach(d => { + d.is_requirement ? All_Id.push(d.requirement_id) : ''; + }); + }; + }; + }); + PostData.requirements = All_Id.length > 0 ? All_Id.join(',') : ''; + PostData.starting_city = value.starting_city; + // multi images + this.ImageGalleryArr = []; + value.images.map((galLi, i) => { + if (typeof (galLi.image_url) == 'object') { + this.fileArr.push(galLi.image_url); + this.fileInfo.push({ 'fileName': "Activity/Add_Act_Id_gallery_" + (i + 1) + "." + galLi.image_url.name.split('.')[1], 'pathToSave': 'ThemeImages/ORGID' }); + } + let imagedata = { + image_url: typeof (galLi.image_url) == 'object' ? environment.cdnFileUrl + "ThemeImages/ORGID/Activity/Add_Act_Id_gallery_" + (i + 1) + "." + galLi.image_url.name.split('.')[1] : galLi.image_url, + sequence: i + 1 + } + this.ImageGalleryArr.push(imagedata); + }); + PostData.activity_images = JSON.stringify(this.ImageGalleryArr); + + // thumnail images + + if (typeof (value.thumnailImg) == 'object') { + this.fileArr.push(value.thumnailImg); + this.fileInfo.push({ 'fileName': "Activity/Add_Act_Id." + value.thumnailImg.name.split('.')[1], 'pathToSave': 'ThemeImages/ORGID' }); + } + let thumnail_img = typeof (value.thumnailImg) == 'object' ? environment.cdnFileUrl + "ThemeImages/ORGID/Activity/Add_Act_Id." + value.thumnailImg.name.split('.')[1] : value.thumnailImg.split('.')[0]; + PostData.thumbnail_image = thumnail_img; + + PostData.created_by = '' + PostData.updated_by = '' + PostData.activity_videos = JSON.stringify(this.VideoURl.getRawValue()) + + PostData.country_code = value.country_code.join(","); + PostData.city_id = value.city_id.join(","); + + // condition based pickup before time + postArrayData.departure_point = ''; + PostData._hotel_pickup_type = ''; + PostData.pickup_hotel = ''; + PostData.hotel_zone = ''; + if (value.is_pickup_included == 'Yes') { + if (value._pickup_point_type == 2) { + postArrayData.departure_point = value.departure_point; + PostData.pickup_before_hour = value.departure_hour; + PostData.pickup_before_minute = value.departure_minute; + } else if (value._pickup_point_type == 1) { + PostData._hotel_pickup_type = value._hotel_pickup_type.toString(); + if (value._hotel_pickup_type == 1) { + PostData.pickup_before_hour = value.All_Hotel_hour; + PostData.pickup_before_minute = value.All_Hotel_minute; + } else if (value._hotel_pickup_type == 2) { + PostData.pickup_hotel = value.pickup_hotel.join(','); + PostData.pickup_before_hour = value.Specific_Hotel_hour; + PostData.pickup_before_minute = value.Specific_Hotel_minute; + } else if (value._hotel_pickup_type == 3) { + PostData.hotel_zone = value.hotel_zone.join(','); + PostData.pickup_before_minute = value.hotel_zone_hour; + PostData.pickup_before_hour = value.hotel_zone_minute; + } + } + } + + PostData.is_pickup_included = value.is_pickup_included == 'No' ? false : true; + PostData.meeting_before_hour = value.is_pickup_included == 'No' ? value.meeting_before_hour : 0; + PostData.meeting_before_minute = value.is_pickup_included == 'No' ? value.meeting_before_minute : 0; + ///// + PostData.is_drop_included = value.is_drop_included == 'No' ? false : true; + PostData.min_pax = value.min_pax; + PostData.max_pax = value.max_pax; + PostData.is_adult = value.is_adult; + PostData.adult_age_from = value.is_adult ? value.adult_age_from : 0; + PostData.adult_age_to = value.is_adult ? value.adult_age_to : 0; + PostData.is_senior = value.is_senior; + PostData.senior_age_from = value.is_senior ? value.senior_age_from : 0; + PostData.senior_age_to = value.is_senior ? value.senior_age_to : 0; + PostData.is_youth = value.is_youth; + PostData.youth_age_from = value.is_youth ? value.youth_age_from : 0; + PostData.youth_age_to = value.is_youth ? value.youth_age_to : 0; + PostData.is_child = value.is_child; + PostData.child_age_from = value.is_child ? value.child_age_from : 0; + PostData.child_age_to = value.is_child ? value.child_age_to : 0; + PostData.max_child_count = value.is_child ? value.max_child_count ? value.max_child_count : 0 : 0; + PostData.free_child_age_from = value.is_child ? value.free_child_age_from ? value.free_child_age_from : 0 : 0; + PostData.free_child_age_to = value.is_child ? value.free_child_age_to ? value.free_child_age_to : 0 : 0; + PostData.is_child_seat = value.is_child_seat; + PostData.activityContents = dataArr; + + + if (this.activity_id) { + this.ApiServ.Post('/Activity/UpdateActivity', PostData).subscribe(data => { + if (data) { + (data['status'] && this.fileInfo.length > 0) ? this.saveImg(data, this.fileArr, this.fileInfo) : this.showToastrMsg(data); + + } + }); + } else { + this.ApiServ.Post('/Activity/SaveActivity', PostData).subscribe(data => { + if (data) { + (data['status'] && this.fileInfo.length > 0) ? this.saveImg(data, this.fileArr, this.fileInfo) : this.showToastrMsg(data); + } + }); + } + } + + showToastrMsg(respData) { + this.messageService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + this.SaveBtn = false; + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + // ng select + + + + option = [ + { id: 0, name: 'Yes' }, + { id: 1, name: 'No' }, + ]; + + optionDropOff = [ + { id: 0, name: 'Yes' }, + { id: 1, name: 'No' }, + ]; + selectOption = this.option[0].name; + + onUpload(event: { files: any }) { + for (let file of event.files) { + this.uploadedFiles.push(file); + } + + this.messageService.add({ + severity: 'info', + summary: 'File Uploaded', + detail: '', + }); + } + + addvideo() { + this.VideoURl.push(this.Fb.group({ activity_videos: [''] })) + } + removevideo(index: number) { + this.VideoURl.removeAt(index) + } + + + // hours and minutes option dropdown + + agelength() { + for (let i = 0; i <= 100; i++) { + i >= 0 && i <= 18 ? this.childNoArray.push({ value: i }) : ""; + i >= 0 && i <= 2 ? this.InfantNoArray.push({ value: i }) : ""; + this.AdultNoArray.push({ value: i }) + i != 0 ? this.sequence.push(i) : '' + }; + }; + + + + GetAllRequirementView() { + this.ApiServ.Get('/ActivityRequirement/GetAllRequirementView').subscribe(res => { + if (res) { + let requirementObj = res.responseObject.sort((a, b) => a.header_sequence - b.header_sequence); + requirementObj.forEach((e, i) => { + let req_menu = e.requirements.sort((a, b) => a.sub_sequence - b.sub_sequence) + this.Requirment.push( + this.Fb.group({ + header_name: [e.header_name], + header_id: [e.header_id], + is_header: [false], + requirements: this.Fb.array([ + ]) + }) + ) + if (req_menu) { + req_menu.forEach(d => { + let form = this.Requirment.controls[i].get('requirements') as FormArray; + form.push(this.Fb.group({ + requirement_id: [d.requirement_id], + requirement_name: [d.requirement_name], + is_requirement: [false] + })) + }) + } + }) + } + }) + } + + + + + + /// images save + fileArr = []; + fileInfo = []; + + // + MultiImageGallery = []; + ImageGalleryArr = []; + get ImgGallery() { + return this.formData.get('images') as FormArray; + } + get Itinerary() { + return this.formData.get('Itinerary') as FormArray; + } + + + getMultiGalleryImg(e) { + console.log(e) + if (e.currentFiles.length != 0) { + for (let i = 0; i < e.files.length; i++) { + this.addPackageImgGallery(); + let file = e.files[i]; + this.ImgGallery.controls[this.MultiImageGallery.length + i].get('image_url').setValue(file) + //base 64 + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + this.MultiImageGallery.push(reader.result) + }; + } + } + } + emptyImgGallery(i) { + this.ImgGallery.removeAt(i); + this.MultiImageGallery.splice(i, 1); + console.log(this.MultiImageGallery) + } + + + addPackageImgGallery() { + this.ImgGallery.push( + this.Fb.group({ + image_url: [''], + sequence: [''] + }) + ) + } + ///// + getThumnailImg(e) { + this.onFileSelected(e) + if (e.currentFiles.length != 0) { + let file = e.files[0]; + this.showThumbnailImg = true + this.formData.get('thumnailImg').setValue(file); + } + }; + base64Output; + onFileSelected(event) { + this.convertFile(event.files[0]).subscribe(base64 => { + if (base64) { + this.base64Output = 'data:image/png;base64,' + base64; + console.log(this.base64Output); + } + }); + } + convertFile(file: File): Observable { + const result = new ReplaySubject(1); + const reader = new FileReader(); + reader.readAsBinaryString(file); + reader.onload = (event) => result.next(btoa(event.target.result.toString())); + return result; + } + + emptyThunailImg() { + this.base64Output = ''; + this.showThumbnailImg = false + this.formData.get('thumnailImg').setValue(''); + }; + + + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Search']); + } + saveImg(respData, file_arr, file_info) { + var formdata = new FormData(); + file_arr.forEach(x => { + formdata.append("files", x); + }) + let Id = this.activity_id ? this.activity_id : respData['responseObject'].activity_id; + let a = JSON.stringify(file_info).replaceAll('Add_Act_Id', Id); + formdata.append("fileInfo", a); + + this.ApiServ.PostFile('/FileUpload/SaveFile', formdata).subscribe(imdata => { + if (imdata['status']) { + this.showToastrMsg(respData) + } + }); + } + + // add validation + PickupIncludes(val) { + if (val == 'No') { + this.formData.addControl('meeting_point', this.Fb.control('', Validators.required)); + this.formData.addControl('meeting_before_hour', this.Fb.control(null, Validators.required)); + this.formData.addControl('meeting_before_minute', this.Fb.control(null, Validators.required)); + this.formData.removeControl('_pickup_point_type'); + } else { + this.formData.addControl('_pickup_point_type', this.Fb.control(1, [Validators.required])); + this.formData.removeControl('meeting_point'); + this.formData.removeControl('meeting_before_hour'); + this.formData.removeControl('meeting_before_minute'); + this.PickupPointValid(); + } + + } + PickupPointValid() { + let val = this.formData.getRawValue(); + if (val._pickup_point_type == 1) { + this.formData.removeControl('departure_point'); + this.formData.removeControl('departure_hour'); + this.formData.removeControl('departure_minute'); + this.formData.addControl('_hotel_pickup_type', this.Fb.control(1, Validators.required)); + this.Hotel_Type_AddPickupValid(); + } else { + this.formData.removeControl('_hotel_pickup_type'); + this.formData.addControl('departure_point', this.Fb.control('', Validators.required)); + this.formData.addControl('departure_hour', this.Fb.control(null, Validators.required)); + this.formData.addControl('departure_minute', this.Fb.control(null, Validators.required)); + this.Hotel_Type_AddPickupValid(); + } + } + Hotel_Type_AddPickupValid() { + let val = this.formData.getRawValue(); + this.formData.removeControl('All_Hotel_hour'); + this.formData.removeControl('All_Hotel_minute'); + this.formData.removeControl('pickup_hotel'); + this.formData.removeControl('Specific_Hotel_hour'); + this.formData.removeControl('Specific_Hotel_minute'); + this.formData.removeControl('hotel_zone'); + this.formData.removeControl('hotel_zone_hour'); + this.formData.removeControl('hotel_zone_minute'); + if (val._hotel_pickup_type == 1) { + this.formData.addControl('All_Hotel_hour', this.Fb.control(null, Validators.required)); + this.formData.addControl('All_Hotel_minute', this.Fb.control(null, Validators.required)); + } else if (val._hotel_pickup_type == 2) { + this.formData.addControl('pickup_hotel', this.Fb.control(null, Validators.required)); + this.formData.addControl('Specific_Hotel_hour', this.Fb.control(null, Validators.required)); + this.formData.addControl('Specific_Hotel_minute', this.Fb.control(null, Validators.required)); + } else if (val._hotel_pickup_type == 3) { + this.formData.addControl('hotel_zone', this.Fb.control(null, Validators.required)); + this.formData.addControl('hotel_zone_hour', this.Fb.control(null, Validators.required)); + this.formData.addControl('hotel_zone_minute', this.Fb.control(null, Validators.required)); + } + } + /// check box validation + adultValid(check) { + if (check) { + this.addvalid("adult_age_from", 'add'); + this.addvalid("adult_age_to", 'add'); + } else { + this.addvalid("adult_age_from", 'remove'); + this.addvalid("adult_age_to", 'remove'); + } + + } + SeniorValid(check) { + if (check) { + this.addvalid("senior_age_from", 'add'); + this.addvalid("senior_age_to", 'add'); + } else { + this.addvalid("senior_age_from", 'remove'); + this.addvalid("senior_age_to", 'remove'); + } + } + YouthValid(check) { + if (check) { + this.addvalid("youth_age_from", 'add'); + this.addvalid("youth_age_to", 'add'); + } else { + this.addvalid("youth_age_from", 'remove'); + this.addvalid("youth_age_to", 'remove'); + } + }; + ChildValid(check) { + if (check) { + this.addvalid("child_age_from", 'add'); + this.addvalid("child_age_to", 'add'); + } else { + this.addvalid("child_age_from", 'remove'); + this.addvalid("child_age_to", 'remove'); + } + }; + InfantValid(check) { + if (check) { + this.addvalid("infant_age_from", 'add'); + this.addvalid("infant_age_to", 'add'); + } else { + this.addvalid("infant_age_from", 'remove'); + this.addvalid("infant_age_to", 'remove'); + } + + }; + dropoffvalid(val) { + if (val == 'No') { + this.addvalid("drop_point", 'remove'); + } else { + this.addvalid("drop_point", 'add'); + } + }; + + addvalid(name, type) { + if (type == 'add') { + this.formData.controls[name].addValidators([Validators.required]); + this.formData.controls[name].updateValueAndValidity(); + } else { + this.formData.controls[name].clearValidators(); + this.formData.controls[name].updateValueAndValidity(); + this.formData.controls[name].markAsUntouched(); + } + }; + + GetAllActivityHotelZone() { + let SearchObj = { + city_id: '', + country_code: '', + zone_name: '', + } + this.ApiServ.Post('/ActivityHotelZone/GetAllActivityHotelZone', SearchObj).subscribe(res => { + if (res) { + this.AllActivityHotelZone = res.result.responseObject; + } + }) + } + + DaysItineryForm(ind) { + let val = this.formData.getRawValue(); + this.Itinerary.clear() + for (let i = 0; i < ind; i++) { + this.Itinerary.push(this.Fb.group({ + Text_html: [''], + country_code: [''], + city_code: [''], + })); + } + } + +} + diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.html new file mode 100644 index 0000000..7d562b9 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.ts new file mode 100644 index 0000000..f53ad12 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.component.ts @@ -0,0 +1,11 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-exp-services-manage', + templateUrl: './exp-services-manage.component.html', +}) +export class ExpServicesManageComponent implements OnInit { + constructor() {} + + ngOnInit(): void {} +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.module.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.module.ts new file mode 100644 index 0000000..f094743 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/exp-services-manage.module.ts @@ -0,0 +1,163 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { TabsComponent } from './tabs/tabs.component'; +import { OverviewComponent } from './tabs-content/Overview/Overview.component'; + +import { TabViewModule } from 'primeng/tabview'; +import { TreeModule } from 'primeng/tree'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FileUploadModule } from 'primeng/fileupload'; +import { ProductService } from 'src/app/core/services/product.service'; +import { ConfirmationService, MessageService } from 'primeng/api'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { CalendarModule } from 'primeng/calendar'; +// import { ExpServicesManageComponent } from './activity-services-manage.component'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { DialogModule } from 'primeng/dialog'; +import { RadioButtonModule } from 'primeng/radiobutton'; +import { ListboxModule } from 'primeng/listbox'; +import { CheckboxModule } from 'primeng/checkbox'; +import { DropdownModule } from 'primeng/dropdown'; +import { CarouselModule } from 'primeng/carousel'; +import { MenuModule } from 'primeng/menu'; +import { MatButtonModule } from '@angular/material/button'; +import { + MatRadioModule, + MAT_RADIO_DEFAULT_OPTIONS, +} from '@angular/material/radio'; +import { MatMenuModule } from '@angular/material/menu'; +import { FullCalendarModule } from '@fullcalendar/angular'; +import { ToastModule } from 'primeng/toast'; +import { MatCheckbox, MatCheckboxModule, MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox'; +import { ExpServicesManageComponent } from './exp-services-manage.component'; +import { SlotsComponent } from './tabs-content/slots/slots.component'; +import { AddOptionalAddOnComponent } from './tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component'; +import { OptionalAddOnsComponent } from './tabs-content/optional-addOns/optional-addOns.component'; +import { AddRateConfigComponent } from './tabs-content/rate-config/add-rate-config/add-rate-config.component'; +import { EditAllocationComponent } from './tabs-content/rate-config/edit-allocation/edit-allocation.component'; +import { EditCancelletionPolicyComponent } from './tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component'; +import { EditModifyRateComponent } from './tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component'; +import { RateConfigComponent } from './tabs-content/rate-config/rate-config.component'; +import { AddNewSeasonComponent } from './tabs-content/season-creation/add-new-season/add-new-season.component'; +import { SeasonCreationComponent } from './tabs-content/season-creation/season-creation.component'; +import { AddSlotsComponent } from './tabs-content/slots/add-slots/add-slots.component'; +import { EditDetailsComponent } from './tabs-content/rate-config/edit-details/edit-details.component'; +import { ModifyDetailsComponent } from './tabs-content/rate-config/modify-details/modify-details.component'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: '', + component: ExpServicesManageComponent, + }, + { + path: 'Add', + component: AddRateConfigComponent, + }, + { + path: 'EditCancelletionPolicy', + component: EditCancelletionPolicyComponent, + }, + { + path: 'EditDetails', + component: ModifyDetailsComponent, + }, + { + path: 'EditAllocation', + component: EditAllocationComponent, + }, + { + path: 'EditModifyRate', + component: EditModifyRateComponent, + }, + { + path: 'AddOptionalAddOn', + component: AddOptionalAddOnComponent, + }, + { + path: 'AddNewSeason', + component: AddNewSeasonComponent, + }, + { + path: 'AddSlots', + component: AddSlotsComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ + TabsComponent, + OverviewComponent, + SeasonCreationComponent, + RateConfigComponent, + OptionalAddOnsComponent, + ExpServicesManageComponent, + AddRateConfigComponent, + EditModifyRateComponent, + EditAllocationComponent, + EditCancelletionPolicyComponent, + AddOptionalAddOnComponent, + AddNewSeasonComponent, + SlotsComponent, + AddSlotsComponent, + EditDetailsComponent, + ModifyDetailsComponent, + ], + imports: [ + CommonModule, + TabViewModule, + TreeModule, + NgSelectModule, + FormsModule, + ReactiveFormsModule, + ToastModule, + FileUploadModule, + TranslateModule, + InputNumberModule, + InputTextModule, + CalendarModule, + CarouselModule, + TableModule, + ToolbarModule, + DialogModule, + TooltipModule, + ListboxModule, + CheckboxModule, + MatCheckboxModule, + DropdownModule, + MenuModule, + MatMenuModule, + MatButtonModule, + RadioButtonModule, + MatRadioModule, + FullCalendarModule, + RouterModule.forChild(routes), + ], + providers: [ + ProductService, + ConfirmationService, + StaticDataService, + MessageService, + TranslateService, + { + provide: MAT_RADIO_DEFAULT_OPTIONS, + useValue: { color: 'primary' }, + }, + { + provide: MAT_CHECKBOX_DEFAULT_OPTIONS, + useValue: { color: 'primary' }, + }, + ], +}) +export class ExpServicesManageModule {} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.html new file mode 100644 index 0000000..756cb2e --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.html @@ -0,0 +1,549 @@ +
    Overview
    +
    + +
    +
    + {{ActivityData.activityContents[0].activity_name}} +
    +
    +
    + +
    +
    +
    +
    Allocation
    +
    +
    +
    + + + +
    +
    + + + + {{ item.start_time | date : 'HH:mm'}} to {{item.end_time| date : 'HH:mm'}} + + +
    +
    +
    +
    + + + {{ date.day }} +
    + +
    +
    +
    + Allocated: + Booked: + Remaining: +
    +
    + +
    + + add_circle + + + + remove_circle + +
    +
    + {{Calender.get(convertproperadate(date)).get('booking_count').value}} + {{Calender.get(convertproperadate(date)).get('_allocation_type').value == '1' ? 'Free Sale' : + Calender.get(convertproperadate(date)).get('_allocation_type').value == '2' ? 'Stop Sale' : + Calender.get(convertproperadate(date)).get('remaining_count').value}} + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Season
    +
    + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Season Name + + + + Season Date Range + + + + Status + + + + Action + + + + + + + {{ season.activitySeason.season_name }} + + 12 Feb 2022 - 02 Mar 2022 + + + + {{ + season.activitySeason.is_active ? "Active" : "Deactive" + }} + + +
    + + + + + +
    + + +
    +
    +
    +
    +
    +
    Slots
    +
    + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Id + + + + Slot Start Time + + + + Slot End Time + + + + Cut-Off Time (in Hrs) + + + + Status + + + + Action + + + + + + + {{ AllSlotsData.activity_slot_id }} + + {{ + AllSlotsData.start_time | date: "H:mm" + }} + + + {{ + AllSlotsData.end_time | date: "H:mm" + }} + + + {{ + AllSlotsData.cut_off_time | date: "H:mm" + }} + + + + {{ AllSlotsData.is_active ? "Active" : "Deactive" }} + + +
    + + + + + +
    + + +
    + + + + No data found + + + +
    +
    +
    +
    +
    Rates
    +
    + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Option Name + + + + Nationality + + + + Date Range/Season + + + + Currency + + + + Slot + + + + Pickup Included + + + + Drop Off Included + + + + Status + + + Action + + + + + + {{rateDetails.option_name}} + {{rateDetails.nationality}} + + + {{rateDetails.date + == null ? '' : + item | date: 'dd MMM YYYY' }} {{ + + + i == 0 && rateDetails.date.split(',').length > 1? '-' : ''}} + + + {{rateDetails.currency_code}} + + {{item.date}} + + {{rateDetails.is_pickup_included ? "Yes" : "No"}} + {{rateDetails.is_drop_off_included? "Yes" : "No"}} + + {{ + rateDetails.is_active ? + 'Active' : 'Deactive' }} + + + +
    + + + + + + + + + +
    + + +
    +
    +
    +
    +
    +
    Optional Add-Ons
    +
    + + + + +
    + + + + + +
    +
    + +
    + + + + +
    +
    +
    +
    + + + + Add-On + + + + Description + + + + Rate Type + + + + Currency + + + + + Status + + + Action + + + + + {{ ons.add_on_name }} + {{ ons.add_on_description }} + {{ ons.rate_type }} + {{ ons.currency_code }} + + {{ ons.is_active ? "Active" : "Deactive" }} + + +
    + + + + + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.ts new file mode 100644 index 0000000..4ef0e54 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/Overview/Overview.component.ts @@ -0,0 +1,616 @@ + + +const colors: any = { + red: { + primary: '#ad2121', + secondary: '#FAE3E3', + }, + blue: { + primary: '#1e90ff', + secondary: '#D1E8FF', + }, + yellow: { + primary: '#e3bc08', + secondary: '#FDF1BA', + }, +}; + +import { + Component, + OnInit, + ViewChild +} from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as FileSaver from 'file-saver'; +import jsPDF from 'jspdf'; +import 'jspdf-autotable'; +import * as moment from 'moment'; +import { + MessageService +} from 'primeng/api'; +import { Table } from 'primeng/table/table'; +import { AllocationOverview } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model'; +import { ActivityAllContract, GetRateDetails } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model'; +import { GetActivitySlot } from 'src/app/core/models/Experience-Service/slot/add-slots-model'; +import { API } from 'src/app/core/services/api.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; +import { CommonService } from 'src/app/core/services/common.service'; +@Component({ + selector: 'Overview', + // changeDetection: ChangeDetectionStrategy.OnPush, + + templateUrl: './Overview.component.html', +}) +export class OverviewComponent implements OnInit { + // items!: MenuItem[]; + dateValue!: Date; + // responsive code + isMobile = false; + DateList: any[] = [] + responsiveOptions; + activityId; + // modal: any; + constructor( + // private confirmationService: ConfirmationService, + private messageService: MessageService, + // responsive constructor + public MobileBreakpoints: BreakpointsService, + // private cd: ChangeDetectorRef, // responsive constructor + public ApiServ: API, + public MsgService: MessageService, + private router: Router, + private fb: FormBuilder + ) { + // this.MobileBreakpoints.IsMobile.subscribe({ + // next: (val) => { + // this.isMobile = val; + // // this.cd.detectChanges(); + // }, + // }); + } + + date14!: Date; + + cities = [ + { id: 1, name: 'Vilnius' }, + { id: 2, name: 'Kaunas' }, + { id: 3, name: 'Pavilnys', disabled: true }, + { id: 4, name: 'Pabradė' }, + { id: 5, name: 'Klaipėda' }, + ]; + + cols!: any[]; + exportColumns!: any[]; + datelist; + formgroup: FormGroup; + OptAddData; + rateDetails; + ActivityData; + activityImages; + SeasonData; + AllocationDetails; + AllSlotsData; + AllSlots + ngOnInit() { + // this.cols = [ + // { field: 'code', header: 'Code', customExportHeader: 'Product Code' }, + // { field: 'name', header: 'Name' }, + // { field: 'category', header: 'Category' }, + // { field: 'quantity', header: 'Quantity' }, + // ]; + // this.exportColumns = this.cols.map((col) => ({ + // title: col.header, + // dataKey: col.field, + // })); + this.activityId = CommonService.getSessionStoage('activity_id'); + this.ngOinitForm(); + this.GetActivityData(); + this.GetallrateDetails(true); + this.SearchSeason(); + this.GetAllSlot(); + } + + /** + * @author Abdul Razzak + * to create form group + */ + ngOinitForm() { + this.formgroup = this.fb.group({ + slot_id: [''], + option_name: [''], + Calender: this.fb.group({ + }) + }); + } + + /** + * @author Abdul Razzak + * to get form controller + */ + get Calender() { + return this.formgroup.get('Calender') as FormGroup + } + + + /** + * @author Abdul razzak + * to get all allocation details + */ + getAllocationDetails() { + let value = this.formgroup.getRawValue(); + let postdata = new GetRateDetails(); + postdata.from_date = ''; + postdata.to_date = ''; + postdata.dates = ''; + postdata.slot_id = value.slot_id; + postdata.seasonId = []; + postdata.days = ''; + postdata.contract_id = value.option_name; + this.ApiServ.Post('/ActivityContract/GetAllocationDetails', postdata).subscribe(data => { + if (data) { + this.AllocationDetails = data.responseObject; + this.SetTimeAvali(this.AllocationDetails); + } + }); + }; + + // ------------------------------------------------ date overview ---------------------------------------- + + + updateinputvalue(group) { + // console.log('asfdgujvfi') + // this.SaveAllocation() + } + + /** + * @author Abdul Razzak + * for plus allocation count + * @param group + */ + handleMinus(group) { + let value = this.Calender.get(group).get('allocation_count').value - 1; + if (value >= 0) { + this.Calender.get(group).get('allocation_count').setValue(value); + this.SaveAllocation(this.Calender.get(group)); + } + } + + /** + * @author Abdul Razzak + * for minus allocation count + * @param group + */ + handlePlus(group) { + let value = this.Calender.get(group).get('allocation_count').value + 1; + this.Calender.get(group).get('allocation_count').setValue(value); + this.SaveAllocation(this.Calender.get(group)); + } + + /** + * @author Abdul Razzak + * for save allocation details + * @param group + */ + SaveAllocation(group) { + let value = group.getRawValue(); + let contractDetails = this.formgroup.getRawValue(); + let postdata = new AllocationOverview(); + postdata._allocation_type = value.allocation_count > 0 ? '3' : value._allocation_type; + postdata.allocation_count = value.allocation_count ? value.allocation_count : 0; + postdata.activity_allocation_id = value.activity_allocation_id; + postdata.activity_contract_id = contractDetails.option_name; + postdata.activity_slot_id = contractDetails.slot_id; + this.ApiServ.Post('/ActivityContract/UpdateAllocationViewTab', postdata).subscribe((res) => { + if (res) { + this.setvalue(res.responseObject, group) + } + }) + } + + /** + * @author Abdul Razzak + * for set value when allocation count plus and minus + * @param data + * @param group + */ + setvalue(data, group) { + group.get('allocation_count').setValue(data.allocation_count); + group.get('_allocation_type').setValue(data._allocation_type); + group.get('booking_count').setValue(data.booking_count); + group.get('remaining_count').setValue(data.remaining_count); + } + + /** + * for binding + * @param date + * @returns + */ + bindAllocationdate(date) { + let d = new Date(date.year, date.month, date.day); + let validate; + validate = false; + let format = moment(d).format('MM-DD-YYYY') + let valid = this.datelist.filter(e => e == format); + if (valid.length > 0) { + validate = true; + } + return validate; + } + + /** + * @author Abdul Razzak + * to convert date format MM-DD-YYYY + */ + convertproperadate(date) { + let d = new Date(date.year, date.month, date.day); + let format = moment(d).format('MM-DD-YYYY'); + return format + } + + /** + * @author Abdul Razzak + * to create form controls and set value + * @param allDate + */ + SetTimeAvali(allDate) { + this.datelist = allDate.map(e => moment(e._date).format('MM-DD-YYYY')); + allDate.map(e => { + let date = moment(e._date).format('MM-DD-YYYY'); + this.Calender.addControl(date, this.fb.group({ + activity_allocation_id: e.activity_allocation_id, + allocation_count: e.allocation_count, + booking_count: e.booking_count, + remaining_count: e.remaining_count, + _allocation_type: e._allocation_type, + })); + }); + } + + /** + * @author Abdul Razzak + * to stop sale in allocation + * @param group + */ + StopSale(group) { + group.get('_allocation_type').setValue('2'); + group.get('allocation_count').setValue(0); + this.SaveAllocation(group); + } + + + + // ----------------------------------------------------- ------------------------------------------------------ + /** + * @author Abdul Razzak + * to get activity details by Id + */ + GetActivityData() { + let activityid = CommonService.getSessionStoage('activity_id'); + this.ApiServ.Get('/Activity/GetActivity/' + activityid).subscribe((e) => { + if (e) { + this.ActivityData = e.responseObject; + this.activityImages = JSON.parse(e.responseObject.activity_images); + CommonService.setSessionStorage('Def_Lang_code', e.responseObject.default_lang_code); + this.GetActivityAddOn(); + } + }); + } + + // ----------------------------------------------------- Season Details ------------------------------------------------------ + + UpdateSeasonStatus(exp_id, status) { + let obj = { id: exp_id, status: status ? false : true, updatedBy: '' }; + this.ApiServ.Post('/ActivitySeason/UpdateStatus', obj).subscribe((data) => { + if (data) { + this.MsgService.add({ + severity: data['status'] ? 'success' : 'error', + detail: data['message'], + }); + this.SearchSeason(); + } + }); + } + + SearchSeason() { + this.ApiServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + this.activityId + '&seasonName=' + '').subscribe((e) => { + if (e) { + this.SeasonData = e['responseObject']; + } + }); + } + + EditSeason(sea_id) { + let obj = { id: sea_id }; + this.router.navigate(['/Services/ExpServices/Manage/AddNewSeason'], { + queryParams: obj, + }); + } + + exportseasonExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.SeasonData); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile( + excelBuffer, + 'Season_Data_export_' + new Date().getTime() + ); + }); + } + + exportseasonPdf() { + // const doc = new jsPDF(); + const doc = new jsPDF('p', 'pt'); + doc['autoTable'](this.exportColumns, this.SeasonData); + doc.save('Season_Data_export_' + new Date().getTime() + '.pdf'); + } + + // ----------------------------------------------------- Add Optional Add-Ons ------------------------------------------------------ + + + + + GetActivityAddOn() { + let obj = { + activityId: this.activityId, + _add_on_name: "", + _language_code: CommonService.getSessionStoage('Def_Lang_code') + } + this.ApiServ.Post('/ActivityAddOn/GetActivityAddOn', obj).subscribe(e => { + if (e) { + this.OptAddData = e['responseObject']; + } + }) + } + + EditOpt(pk_id) { + let obj = { id: pk_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/AddOptionalAddOn'], { queryParams: obj }) + } + + UpdateOptStatus(exp_id, status) { + let obj = { id: exp_id, status: status ? false : true, updatedBy: '' }; + this.ApiServ.Post('/ActivityAddOn/UpdateStatus', obj).subscribe((data) => { + if (data) { + this.MsgService.add({ + severity: data['status'] ? 'success' : 'error', + detail: data['message'], + }); + this.GetActivityAddOn(); + } + }); + } + + exportOptPdf() { + const doc = new jsPDF('p', 'pt'); + doc['autoTable'](this.exportColumns, this.OptAddData); + doc.save('Option_Add_Ons_export_' + new Date().getTime() + '.pdf'); + } + + exportOptExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.OptAddData); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'Option_Add_Ons'); + }); + } + + // ----------------------------------------------------- rate Details ------------------------------------------------------ + + EditCancelPoli(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditCancelletionPolicy'], { queryParams: obj }) + } + EditAllocation(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditAllocation'], { queryParams: obj }) + } + EditRateConfig(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditModifyRate'], { queryParams: obj }) + } + + EditDetails(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditDetails'], { queryParams: obj }) + } + + + UpdateRateStatus(ID, Status) { + let Obj = { + id: ID, + updatedBy: "", + "status": Status ? false : true + } + this.ApiServ.Post('/ActivityContract/UpdateStatus', Obj).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + this.GetallrateDetails(false); + } + }); + }; + + SoltsDetailsConvParse(data) { + let obj = data ? JSON.parse(data) : ''; + let html = []; + obj ? obj.forEach(e => html.push({ 'date': moment(e.start_time).format('hh:mm') + '-' + moment(e.end_time).format('hh:mm') })) : '' + return html + } + + GetallrateDetails(check) { + let activityid = CommonService.getSessionStoage('activity_id'); + let postdata = new ActivityAllContract(); + postdata.activity_id = activityid; + postdata.is_drop_off_included = false; + postdata.is_pickup_included = false; + postdata.option_name = ''; + this.ApiServ.Post('/ActivityContract/GetAllActivityRates', postdata).subscribe(data => { + if (data) { + this.rateDetails = data.responseObject; + if (check) { + this.formgroup.get('option_name').setValue(this.rateDetails[0].activity_contract_id); + this.GetSlotsById(this.rateDetails[0].activity_contract_id, true); + } + } + }) + } + + // ----------------------------------------------------- rate Details ------------------------------------------------------ + + + GetAllSlot() { + let post = new GetActivitySlot(); + post.activity_id = this.activityId; + post.from_hour = null; + post.from_minute = null; + post.to_hour = null; + post.to_minute = null; + console.log(post) + this.ApiServ.Post('/ActivitySlot/GetAllSlot', post).subscribe(res => { + if (res) { + this.AllSlotsData = res['responseObject']; + } + }); + } + + EditSlot(pk_id) { + let obj = { id: pk_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/AddSlots'], { queryParams: obj }); + } + + UpdateStatusSlot(slot_id, status) { + let obj = { Id: slot_id, Status: status ? false : true } + this.ApiServ.Post('/ActivitySlot/UpdateStatus', obj).subscribe(data => { + if (data) { + this.GetAllSlot(); + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + } + }) + } + + /** + * @author Abdul Razzak + * to get slot data by contract id + * @param Id + */ + GetSlotsById(Id, check) { + this.formgroup.get('slot_id').setValue('') + this.ApiServ.Get('/ActivityContract/GetSlotsById/' + Id).subscribe(res => { + if (res) { + this.AllSlots = res.responseObject; + if (check) { + this.formgroup.get('slot_id').setValue(this.AllSlots[0].activity_slot_id); + this.getAllocationDetails(); + } + } + }) + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ViewChild('dt') + table!: Table; + + // exportExcel() { + // import('xlsx').then((xlsx) => { + // console.log(xlsx); + // const worksheet = xlsx.utils.json_to_sheet(this.products); + // const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + // const excelBuffer: any = xlsx.write(workbook, { + // bookType: 'xlsx', + // type: 'array', + // }); + // this.saveAsExcelFile(excelBuffer, 'products'); + // }); + // } + + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } + + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.html new file mode 100644 index 0000000..e4bd82e --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.html @@ -0,0 +1,145 @@ +
    + + Back +
    +
    Add Optional Add-Ons
    +
    +
    +
    +
    + + + + Please enter add on + +
    +
    + + +
    +
    +
    + +
    + + +
      +
    • + {{ file.name }} - {{ file.size }} bytes +
    • +
    +
    +
    +
    +
    +
    +
    + +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    + + Please choose add on image + +
    +
    +
    +
    + + + + + Please select rate on + +
    +
    + + + + + Please select currency + +
    +
    + + + + Please enter numbers only + + + Please enter amount + +
    +
    + + + + Accept numbers only + + + Please enter adult amount + +
    + +
    + + + + Accept numbers only + + + Please enter youth amount + +
    +
    + + + + Accept numbers only + + + Please enter child amount + +
    +
    + + + + Accept numbers only + + + Please enter senior amount + +
    +
    +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.ts new file mode 100644 index 0000000..2f49578 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/add-optional-add-on/add-optional-add-on.component.ts @@ -0,0 +1,225 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ActivityAddOn, ActivityAddOnDetails } from 'src/app/core/models/optional-ons/optional-ons.model' +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-add-optional-add-on', + templateUrl: './add-optional-add-on.component.html', +}) +export class AddOptionalAddOnComponent implements OnInit { + uploadedFiles: any[] = []; + fileArr = []; + fileInfo = []; + AddOptForm: FormGroup; + showImgBox; + RateTypes; + Currency; + addOne_Id; + constructor( + private router: Router, + private ApiServ: API, + private MsgService: MessageService, + private route: ActivatedRoute, + public validationService: ValidationService, + private fb: FormBuilder + ) { } + + ngOnInit(): void { + this.initForm(); + this.GetRateType(); + this.GetCurrency(); + + this.route.queryParams.subscribe(obj => { + if (obj['id']) { + this.showImgBox = true; + this.ApiServ.Get('/ActivityAddOn/GetActivityAddOn/' + obj['id']).subscribe(d => { + this.SetValue(d['responseObject']); + + this.addOne_Id = obj['id']; + }); + } + }) + } + + SetValue(val) { + Object.keys(val).forEach(li => { + if (li == "rate" || li == "currency_code") { + this.AddOptForm.get(li).setValue(val[li]); + } else if (li == "_rate_type") { + this.AddOptForm.get(li).setValue(parseInt(val[li])); + this.RateTypesCheck(); + if (parseInt(val[li]) == 1) { + this.AddOptForm.get('adult_rate').setValue(val['adult_rate']); + this.AddOptForm.get('senior_rate').setValue(val['senior_rate']); + this.AddOptForm.get('youth_rate').setValue(val['youth_rate']); + this.AddOptForm.get('child_rate').setValue(val['child_rate']); + } else if (parseInt(val[li]) == 2) this.AddOptForm.get('per_service_rate').setValue(val['per_service_rate']); + } + if (li == 'activityAddOnDetails') { + this.setAddOnsDetail(val[li]); + } + }) + } + + setAddOnsDetail(val) { + val.map(obj => { + Object.keys(obj).forEach(li => { + if (li == "add_on_image" || li == "add_on_description" || li == "add_on_name" || li == 'activity_add_on_id') { + this.AddOptForm.get(li).setValue(obj[li]); + } + }) + }) + } + + GetRateType() { + this.ApiServ.Get('/LovMaster/GetLovByType/AddOnRateType').subscribe(obj => { + if (obj) { + this.RateTypes = obj['responseObject']; + } + }) + } + + GetCurrency() { + this.ApiServ.Get('/Currency/GetCurrency').subscribe(obj => { + if (obj) { + this.Currency = obj; + } + }) + } + + RateTypesCheck() { + let val = this.AddOptForm.getRawValue(); + if (val._rate_type == '1') { + this.AddOptForm.addControl('adult_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[0-9]*$/)])); + this.AddOptForm.addControl('senior_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[0-9]*$/)])); + this.AddOptForm.addControl('youth_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[0-9]*$/)])); + this.AddOptForm.addControl('child_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[0-9]*$/)])); + this.AddOptForm.removeControl('per_service_rate'); + } else if (val._rate_type == '2') { + this.AddOptForm.addControl('per_service_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + this.AddOptForm.removeControl('adult_rate'); + this.AddOptForm.removeControl('senior_rate'); + this.AddOptForm.removeControl('youth_rate'); + this.AddOptForm.removeControl('child_rate'); + } + } + + initForm() { + this.AddOptForm = this.fb.group({ + activity_add_on_id: [''], + add_on_name: this.validationService.required, + add_on_description: [''], + add_on_image: this.validationService.required, + supplier_id: ['2205221841391724322'], + _rate_type: this.validationService.required, + currency_code: this.validationService.required, + // per_service_rate: this.validationService.decimal, + }) + } + + getImage(e) { + if (e.currentFiles.length != 0) { + let file = e.files[0]; + this.AddOptForm.get('add_on_image').setValue(file); + } + } + + emptyValue() { + this.showImgBox = false; + this.AddOptForm.get('add_on_image').setValue(''); + } + + SaveOpt() { + if (this.AddOptForm.status == "INVALID") { + this.validationService.showValidationsMsg(this.AddOptForm); + return; + } + this.fileArr = []; + this.fileInfo = []; + let value = this.AddOptForm.getRawValue(); + this.showImgBox = false; + let ActAddOnModel = new ActivityAddOn(); + let ActAddOnDetailArr = new Array(); + let ActAddOnDetailObj = new ActivityAddOnDetails(); + debugger + ActAddOnModel._rate_type = value._rate_type.toString(); + ActAddOnModel.currency_code = value.currency_code; + ActAddOnModel.per_service_rate = value.per_service_rate ? parseInt(value.per_service_rate) : 0; + ActAddOnModel.activity_add_on_id = value.activity_add_on_id; + ActAddOnModel.supplier_id = value.supplier_id; + ActAddOnModel.org_id = '2105311837100000021'; + ActAddOnModel.is_deleted = false; + ActAddOnModel.activity_id = CommonService.getSessionStoage('activity_id'); + + if (value._rate_type == '1') { + ActAddOnModel.adult_rate = value.adult_rate; + ActAddOnModel.child_rate = value.child_rate; + ActAddOnModel.senior_rate = value.senior_rate; + ActAddOnModel.youth_rate = value.youth_rate; + } else if (value._rate_type == '2') ActAddOnModel.per_service_rate = value.per_service_rate; + + ActAddOnDetailObj.is_deleted = false; + ActAddOnDetailObj.org_id = '2105311837100000021'; + ActAddOnDetailObj.activity_id = CommonService.getSessionStoage('activity_id'); + ActAddOnDetailObj.add_on_description = value.add_on_description; + if (typeof (value.add_on_image) == 'object') { + this.fileArr.push(value.add_on_image); + this.fileInfo.push({ 'fileName': "AddOns/Add_Act_Id." + value.add_on_image.name.split('.')[1], 'pathToSave': 'ThemeImages/ORGID' }); + } + ActAddOnDetailObj.add_on_image = typeof (value.add_on_image) == 'object' ? environment.cdnFileUrl + "ThemeImages/ORGID/AddOns/Add_Act_Id." + value.add_on_image.name.split('.')[1] : value.add_on_image.split('?')[0]; + ActAddOnDetailObj.add_on_name = value.add_on_name; + ActAddOnDetailObj.language_code = CommonService.getSessionStoage('Def_Lang_code'); + ActAddOnDetailObj.supplier_id = value.supplier_id; + ActAddOnDetailArr.push(ActAddOnDetailObj) + ActAddOnModel.activityAddOnDetails = ActAddOnDetailArr; + if (this.addOne_Id) { + this.ApiServ.Post('/ActivityAddOn/UpdateActivityAddOn', ActAddOnModel).subscribe(data => { + if (data) { + (data['status'] && this.fileInfo.length > 0) ? this.saveImg(data, this.fileArr, this.fileInfo) : this.showToastrMsg(data); + } + }) + } else { + this.ApiServ.Post('/ActivityAddOn/SaveActivityAddOn', ActAddOnModel).subscribe(data => { + if (data) { + (data['status'] && this.fileInfo.length > 0) ? this.saveImg(data, this.fileArr, this.fileInfo) : this.showToastrMsg(data); + } + }) + } + } + + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + saveImg(respData, file_arr, file_info) { + var formdata = new FormData(); + file_arr.forEach(x => { + formdata.append("files", x); + }) + let Id = this.addOne_Id ? this.addOne_Id : respData['responseObject'].activity_add_on_id; + let a = JSON.stringify(file_info).replaceAll('Add_Act_Id', Id); + formdata.append("fileInfo", a); + + this.ApiServ.PostFile('/FileUpload/SaveFile', formdata).subscribe(imdata => { + if (imdata['status']) { + this.showToastrMsg(respData); + } + }) + } + + btnClick() { + this.router.navigateByUrl("/Services/ActivityServices/ExpServices/Manage"); + } + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.html new file mode 100644 index 0000000..6c69d75 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.html @@ -0,0 +1,130 @@ +
    +
    Optional Add-Ons
    + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + +
    + + + + +
    + + + + + +
    +
    + +
    + + + + +
    +
    +
    +
    + + + + Add-On + + + + Description + + + + Rate Type + + + + Currency + + + + + Status + + + Action + + + + + {{ ons.add_on_name }} + {{ ons.add_on_description }} + {{ ons.rate_type }} + {{ ons.currency_code }} + + {{ ons.is_active ? "Active" : "Deactive" }} + + +
    + + + + + +
    + + +
    + + + + No data found + + + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.ts new file mode 100644 index 0000000..047cce7 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/optional-addOns/optional-addOns.component.ts @@ -0,0 +1,118 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import * as FileSaver from 'file-saver'; +import { API } from 'src/app/core/services/api.service'; +import jsPDF from "jspdf"; +import "jspdf-autotable"; +import { MessageService } from 'primeng/api'; +import { CommonService } from 'src/app/core/services/common.service'; + +@Component({ + selector: 'optional-addOns', + templateUrl: './optional-addOns.component.html', +}) + +export class OptionalAddOnsComponent implements OnInit { + @Input() content + OptAddData; + add_on; + constructor( + private router: Router, + private ApiServ: API, + private MsgService: MessageService + ) { } + + cols!: any[]; + exportColumns!: any[]; + + ngOnInit(): void { + + // console.log(this.content.data) + this.cols = [ + { field: 'add_on_name', header: 'Add-On', customExportHeader: 'Option_Add_Ons_export_' + new Date().getTime() }, + { field: 'add_on_description', header: 'Description' }, + { field: 'rate_type', header: 'Rate Type' }, + { field: 'currency_code', header: 'Currency' }, + { field: 'rate', header: 'Amount' }, + { field: 'is_active', header: 'Status' }, + ]; + + this.exportColumns = this.cols.map((col) => ({ + title: col.header, + dataKey: col.field, + })); + } + + exportPdf() { + // const doc = new jsPDF(); + const doc = new jsPDF('p', 'pt'); + doc['autoTable'](this.exportColumns, this.OptAddData); + // doc.autoTable(this.exportColumns, this.products); + doc.save("Option_Add_Ons_export_" + new Date().getTime() + ".pdf"); + } + + Edit(pk_id) { + let obj = { id: pk_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/AddOptionalAddOn'], { queryParams: obj }) + } + + UpdateStatus(exp_id, status) { + let obj = { id: exp_id, status: status ? false : true, updatedBy: '' } + this.ApiServ.Post('/ActivityAddOn/UpdateStatus', obj).subscribe((data) => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + this.SearchExp(); + } + }); + } + + SearchExp() { + let activityid = CommonService.getSessionStoage('activity_id') + let obj = { + activityId: activityid, + _add_on_name: this.add_on ? this.add_on : "", + _language_code: CommonService.getSessionStoage('Def_Lang_code') + } + this.ApiServ.Post('/ActivityAddOn/GetActivityAddOn', obj).subscribe(e => { + if (e) { + this.OptAddData = e['responseObject']; + } + }) + } + + ResetExp() { + this.add_on = ''; + } + + exportExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.OptAddData); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'Option_Add_Ons'); + }); + } + + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.html new file mode 100644 index 0000000..b5dcb4a --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.html @@ -0,0 +1,1120 @@ +
    + + Back +
    +
    +
    Add Rate Config
    +
    +
    +
    + + +
    +
    + + + +
    +
    + + + +
    +
    + + + Please enter option name +
    +
    + + + Please select currency +
    +
    +
    Applicable Nationality
    +
    + +
    +
    + All Nationality +
    +
    + Specific Nationality +
    +
    +
    + + + + Please select nationality +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Exclude Nationality + +
    +
    +
    +
    + + + + Please select nationality +
    +
    +
    +
    +
    +
    +
    + + + + Please select period type +
    +
    +
    +
    +
    +
    + + + Please select start date + +
    +
    + + + + Please select end date +
    +
    + + +
    +
    +
    +
    +
    + +
    + + + + {{ activity_obj.activitySeason.season_name }} + + Please select + season +
    +
    +
    +
    + {{ activities[0].activitySeason.season_name }} +
    +
    + {{ date_range_obj.fromDate | date: "dd MMM YYYY" }} - + {{ date_range_obj.toDate | date: "dd MMM YYYY" }} +
    +
    +
    +
    +
    +
    + Pickup Included +
    +
    + Drop Off Included + +
    +
    +
    Experience Time Slot
    +
    +
    +
    +
    + + + {{ item.start_time | date : 'HH:mm'}} to {{item.end_time| date : 'HH:mm'}} + + + Please select + slot +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    +
    + Is Private Transfer Price Included + + Is Shared Transfer Price Included +
    +
    + +
    +
    +
    + + + + Please select + supplier +
    +
    + + + + + Please select + vehicle selection +
    +
    + + + +
    +
    +
    + + + Please select + supplier + Accept number only +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + + + +
    + +
    +
    + + + + Please select + supplier +
    +
    +
    + + + +
    +
    + + + Please enter + adult + accept number only + +
    +
    + + + Please enter + senior + accept number only + +
    +
    + + + Please enter + youth + accept number only + +
    +
    + + + Please enter + child + accept number only + +
    +
    +
    + + Show Slot-wise Cancellation Policy + +
    + +
    +
    +
    +
    Slots Pricing
    + +
    +
    + +
    + + + + Please select + apply rate on +
    +
    + + + + Please select + slots +
    + +
    + + + + {{ item.start_time | date : 'HH:mm'}} to {{item.end_time| date : 'HH:mm'}} + + + Please select + slots +
    +
    + + + + Please select + applicable days +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + Please + enter + from + accept + number only + +
    +
    +
    + + Please + enter + to + accept + number only + +
    +
    +
    +
    + + + Please + enter + pricing per pax + accept + number only + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + Please + enter + from + accept + number only + +
    +
    +
    + + Please + enter + to + accept + number only + +
    +
    +
    +
    + + + Please + enter + pricing per pax + accept + number only + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + Please + enter + from + accept + number only + +
    +
    +
    + + Please + enter + to + accept + number only + +
    +
    +
    +
    + + + Please + enter + pricing per pax + accept + number only + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + Please + enter + from + accept + number only + +
    +
    +
    + + Please + enter + to + accept + number only + +
    +
    +
    +
    + + + Please + enter + pricing per pax + accept + number only + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + Free Sale +
    + + + Please enter + allocation + accept number + only +
    +
    + + + Please enter + release days + accept number + only +
    +
    +
    +
    + +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + + Please + enter + adult + + accept + number + only + +
    +
    + + + Please + enter + senior + + accept number + only + +
    +
    + + + Please + enter + youth + + accept + number + only + +
    +
    + + + Please + enter + child + + accept + number + only + +
    +
    +
    + + Free Sale +
    + + + Please enter + allocation + accept number + only +
    +
    + + + Please enter + release days + accept number + only +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + Please + select vehicle supplier +
    +
    + + + + + Please + select vehicle +
    +
    + + +
    +
    + + + Please + select vehicle + accept number only + +
    + +
    +
    + + Free Sale +
    + + + Please enter + allocation + accept number + only +
    +
    + + + Please enter + release days + accept number + only +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    Cancelletion Policy
    +
    +
    +
    +
    +
    + + + + please selct + type + +
    +
    +
    +
    + + + Please + enter From + accept number + only + +
    +
    + + + Please + enter To + accept number + only + +
    +
    +
    +
    +
    +
    +
    + + + + Please + cancellation type +
    +
    +
    +
    +
    + + + Please + enter value + accept number only + +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    + Tourist Guide Included +
    + + + +
    +
    +
    +
    +
    Cancelletion Policy
    +
    +
    +
    +
    +
    + + + + please selct type + +
    +
    +
    +
    + + + Please + enter From + accept number only + +
    +
    + + + Please + enter To + accept number only + +
    +
    +
    +
    +
    +
    +
    + + + + Please + cancellation type +
    +
    +
    +
    +
    + + + Please + enter value + accept number only + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    No Show Policy
    +
    +
    +
    + + + + Please select No Show Type +
    +
    + + + Please enter value + accept number only +
    +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.ts new file mode 100644 index 0000000..9eb714e --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/add-rate-config/add-rate-config.component.ts @@ -0,0 +1,1206 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ActivityCancellationDetails, ActivityContract, ActivityDetails, ActivityPaxRate, ActivityPrivateTransfer, ActivitySharedTransfer, ActivityVehicleRate, AgeRange, AllocationDetails, DateRange, RateRange, SaveActivityContractDetails, SlotDetails, Slots, Specific } from 'src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model'; +import { GetActivitySlot } from 'src/app/core/models/Experience-Service/slot/add-slots-model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; +interface grp { + name: string; + code: string; +} +@Component({ + selector: 'app-add-rate-config', + templateUrl: './add-rate-config.component.html', +}) +export class AddRateConfigComponent implements OnInit { + minDate = new Date(); + RateConfigForm: FormGroup; + currencyList; + LangList = []; + slotList = []; + activityData; + include_nationality_list; + exclude_nationality_list; + all_nationality_list; + season_list = []; + fil_season_list = []; + PhoneCode; + allCityDetials; + AgeRange:FormGroup; + lovKeyDataObj = { + RatePeriodType: [], + RateSlotType: [], + CancellationPolicyType: [], + NoShowType: [], + Language: [], + RateConfigType: [], + DaySelect: [], + ActivityNoShowPolicyType: [], + ActivityCancellationPolicyType: [], + ActivityCancellationChargeType: [], + }; + Vehicle_Selection = [ + { id: 1, name: 'Mercedes S Class' }, + { id: 2, name: 'Coach 20 Seater' }, + { id: 3, name: 'Helicopter' } + ]; + Day = [ + { id: 1, name: 'Mon' }, + { id: 2, name: 'Tue' }, + { id: 3, name: 'Wed' }, + { id: 4, name: 'Thu' }, + { id: 5, name: 'Fri' }, + { id: 6, name: 'Sat' }, + { id: 0, name: 'Sun' }, + { id: 7, name: 'Select All' }, + ]; + DayList = this.Day[0].name; + TransferType = [ + { id: 1, name: 'Private' }, + { id: 2, name: 'Shared' }, + { id: 3, name: 'Without Transfer' }, + ]; + constructor( + public fb: FormBuilder, + public validationService: ValidationService, + public APIServ: API, + public CommonVari: StaticDataService, + public MsgService: MessageService, + private router: Router, + ) { } + + ngOnInit(): void { + this.GetAllCurrency(); + this.GetPhoneCode(); + this.GetAllNationality(); + this.GetAllActivitySeason(); + this.GetAllVehicleSupplier(); + this.getCountry(); + this.initRateConfigForm(); + // this.CancellationPlicyformCheck(false); + this.GetAllSlot(); + // this.GetAllVehicle(); + this.GetLOVKeys('RatePeriodType,RateSlotType,CancellationPolicyType,NoShowType,RateConfigType,Language,DaySelect,ActivityNoShowPolicyType,ActivityCancellationPolicyType,ActivityCancellationChargeType'); + this.AgeRange = this.fb.group({ + from_count: [''], + to_count: [''], + sequence: [''], + rate: [''], + }); + } + + // CONTROL + get DateControl() { + return this.RateConfigForm.get('datesForRates') as FormArray; + } + + get DaysControl() { + return this.RateConfigForm.get('contract_days') as FormArray; + } + + get SlotsDetail() { + return this.RateConfigForm.get('slotDetails') as FormArray; + } + + get CancelControl() { + return this.RateConfigForm.get('activityCancellationDetails') as FormArray; + } + + get SlotsControl() { + return this.RateConfigForm.get('slots') as FormArray; + } + + get privateTransferDataList() { + return this.RateConfigForm.get('privateTransferDataList') as FormArray; + } + + VehicleControl(i) { + return this.SlotsControl.controls[i].get('activityVehicleRate') as FormArray; + } + + PaxControl(i) { + return this.SlotsControl.controls[i].get('activityPaxRate') as FormArray; + } + get activityPaxRateGroup() { + return this.RateConfigForm.get('activityPaxRate') as FormGroup; + } + + TieredControl(i) { + return this.SlotsControl.controls[i].get('allSlotRateRange') as FormArray; + } + + AdultTControl(i, ind) { + return this.TieredControl(i).controls[ind].get("adultAgeRange") as FormArray; + } + + YouthTControl(i, ind) { + return this.TieredControl(i).controls[ind].get("youthAgeRange") as FormArray; + } + + SeniorTControl(i, ind) { + return this.TieredControl(i).controls[ind].get("seniorAgeRange") as FormArray; + } + + ChildTControl(i, ind) { + return this.TieredControl(i).controls[ind].get("childAgeRange") as FormArray; + } + + InfantTControl(i, ind) { + return this.TieredControl(i).controls[ind].get("infantAgeRange") as FormArray; + } + + + initRateConfigForm() { + this.RateConfigForm = this.fb.group({ + experience_name: [''], + org_id: ['2105311837100000021'], + supplier_id: ['2205221841391724322'], + pricing_slots: [''], + currency_code: this.validationService.required, + country_name: [''], + city_name: [''], + option_name: this.validationService.required, + rate_inclusion: [''], + contract_remark: [''], + _period_type: this.validationService.required, + is_pickup_included: [false], + is_drop_off_included: [false], + is_guide_included: [false], + + _nationality_type: ['1'], + is_exclude_nationality: [false], + + is_private_transfer_price_included: [false], + is_shared_transfer_price_included: [false], + is_slot_wise_cancellation_policy: [false], + _no_show_policy_type: this.validationService.required, + + slotDetails: this.fb.array([ + this.fb.group({ + slots: this.validationService.required, + transfer_type: [''], + }) + ]), + slots: this.fb.array([ + this.fb.group({ + applicableDays: this.validationService.required, + _rate_type: this.validationService.required, + _pricing_type: this.validationService.required, + SlotId: [''], + // activityPaxRate: + // this.fb.group({ + // date: [''], + // allocation_count: [''], + // release_days: [''], + // is_free_sales: [false], + // }), + // allSlotRateRange: this.fb.array([ + // this.fb.group({ + // allocation_count: [''], + // release_days: [''], + // is_free_sales: [false], + // }) + // ]), + // activityVehicleRate: + // this.fb.array([ + // this.fb.group({ + // rate: this.validationService.decimal, + // vehicleSupplier: this.validationService.required, + // vehicle: this.validationService.required, + // vehicle_max_occupancy: [''], + // allocation_count: [''], + // release_days: [''], + // is_free_sales: [false], + // }) + // ]), + // activityCancellationDetails: this.fb.array([ + // this.fb.group({ + // from: [''], + // to: [''], + // CP_Type: [''], + // CP_Value: [''], + // cancellation_Type: [''], + // }) + // ]) + }) + ]), + guide_languages: [''] + }); + this.CancellationPlicyformCheck(false); + } + + + addSlotForm() { + this.RateConfigForm.get('slots') + } + + AddContolsForRateType(val) { + if (val == 1) { + this.SlotsControl.controls.forEach((e, i) => { + let form = e as FormGroup + form.addControl('allSlotRateRange', this.fb.array([ + this.fb.group({ + allocation_count: this.validationService.mobNo, + release_days: this.validationService.mobNo, + is_free_sales: [false], + }) + ])); + this.addcontolsforpax(this.SlotsControl.controls[i], 'allSlotRateRange') + form.removeControl('activityVehicleRate') + form.removeControl('activityPaxRate') + }) + } else if (val == 2) { + this.SlotsControl.controls.forEach((e, i) => { + let form = e as FormGroup + form.addControl('activityPaxRate', + this.fb.group({ + date: [''], + allocation_count: this.validationService.mobNo, + release_days: this.validationService.mobNo, + is_free_sales: [false], + }) + ) + this.addcontolsforpax(this.SlotsControl.controls[i], 'activityPaxRate') + form.removeControl('activityVehicleRate'); + form.removeControl('allSlotRateRange'); + }) + } else if (val == 3) { + this.SlotsControl.controls.forEach((e, i) => { + let form = e as FormGroup + form.addControl('activityVehicleRate', + this.fb.array([ + this.fb.group({ + rate: this.validationService.decimal, + vehicleSupplier: this.validationService.required, + vehicle: this.validationService.required, + vehicle_max_occupancy: [''], + allocation_count: this.validationService.mobNo, + release_days: this.validationService.mobNo, + is_free_sales: [false], + }) + ]), + ); + this.addcontolsforpax(this.SlotsControl.controls[i], '') + form.removeControl('allSlotRateRange'); + form.removeControl('activityPaxRate'); + }) + } + } + + AddSharedTransferControls(check) { + if (check) { + this.RateConfigForm.addControl('vehicle_supplier_id', this.fb.control('', [Validators.required])); + if (this.PaxCheck.is_adult.value) this.RateConfigForm.addControl('adult_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.PaxCheck.is_senior.value) this.RateConfigForm.addControl('senior_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.PaxCheck.is_youth.value) this.RateConfigForm.addControl('youth_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.PaxCheck.is_child.value) this.RateConfigForm.addControl('child_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } else { + this.RateConfigForm.removeControl('vehicle_supplier_id'); + if (this.PaxCheck.is_adult.value) this.RateConfigForm.removeControl('adult_rate'); + if (this.PaxCheck.is_senior.value) this.RateConfigForm.removeControl('senior_rate'); + if (this.PaxCheck.is_youth.value) this.RateConfigForm.removeControl('youth_rate'); + if (this.PaxCheck.is_child.value) this.RateConfigForm.removeControl('child_rate'); + } + } + + AddactivityVehicleRateGroup(group) { + group.get('activityVehicleRate').push(this.fb.group({ + rate: this.validationService.decimal, + vehicleSupplier: this.validationService.required, + vehicle: this.validationService.required, + vehicle_max_occupancy: [''], + allocation_count: this.validationService.mobNo, + release_days: this.validationService.mobNo, + is_free_sales: [false], + })); + } + RemoveactivityVehicleRateGroup(group, ind) { + group.get('activityVehicleRate').removeAt(ind); + } + addSlotCancelPolicy(group) { + group.get('activityCancellationDetails').push(this.fb.group({ + cancellation_Type: [''], + from: [''], + to: [''], + CP_Type: [''], + CP_Value: [''], + })); + } + + + removeSlotCancelPolicy(group, ind) { + group.get('activityCancellationDetails').removeAt(ind); + } + CancellationPlicyformCheck(check) { + if (!check) { + this.RateConfigForm.addControl('activityCancellationDetails', this.fb.array([ + this.fb.group({ + from: this.validationService.mobNo, + to: this.validationService.mobNo, + CP_Type: this.validationService.required, + cancellation_Type: this.validationService.required, + }) + ])); + this.SlotsControl.controls.forEach(obj => { + let form = obj as FormGroup; + form.removeControl('activityCancellationDetails'); + }) + } else { + this.SlotsControl.controls.forEach(obj => { + let form = obj as FormGroup; + form.addControl('activityCancellationDetails', this.fb.array([ + this.fb.group({ + from: this.validationService.mobNo, + to: this.validationService.mobNo, + CP_Type: this.validationService.required, + cancellation_Type: this.validationService.required, + }) + ])) + }) + this.RateConfigForm.removeControl('activityCancellationDetails'); + } + } + + Cancellation_Type(group, ind) { + if (ind != 1) { + group.addControl('CP_Value', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } else { + group.removeControl('CP_Value'); + } + } + No_Show_Type(ind) { + if (ind != 1) { + this.RateConfigForm.addControl('no_show_charge_value', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } else { + this.RateConfigForm.removeControl('no_show_charge_value'); + } + } + AddPrivateTransferControls(check) { + if (check) { + this.RateConfigForm.addControl('privateTransferDataList', this.fb.array([ + this.fb.group({ + vehicle_supplier_id: this.validationService.required, + vehicle_id: this.validationService.required, + vehicle_occupancy: [''], + rate: this.validationService.decimal, + }) + ])) + } else { + this.RateConfigForm.removeControl('privateTransferDataList'); + } + } + AddPrivateTransferGroup() { + this.privateTransferDataList.push(this.fb.group({ + vehicle_supplier_id: this.validationService.required, + vehicle_id: this.validationService.required, + vehicle_occupancy: [''], + rate: this.validationService.decimal, + })) + } + + + + + + // ADD FUNCTION + AddSlots() { + let val = this.RateConfigForm.get('is_slot_wise_cancellation_policy').value; + if (val) { + this.SlotsControl.push( + this.fb.group({ + SlotId: [''], + applicableDays: [''], + activityCancellationDetails: this.fb.array([ + this.fb.group({ + cancellation_Type: [''], + from: [''], + to: [''], + CP_Type: [''], + CP_Value: [''], + }) + ]) + }) + ) + } else { + this.SlotsControl.push( + this.fb.group({ + SlotId: [''], + applicableDays: [''], + }) + ) + } + let formgroup = this.SlotsControl.controls[0].get('_rate_type').value; + this.AddContolsForRateType(formgroup); + } + + addcontolsforpax(formgroup, name) { + if (this.PaxCheck.is_adult.value) { + if (name == 'allSlotRateRange') { + formgroup.get('allSlotRateRange')['controls'][0].addControl('adultAgeRange', + this.fb.array([this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })]), + ); + } + if (name == 'activityPaxRate') { + formgroup.get('activityPaxRate').addControl('adult_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + } + if (this.PaxCheck.is_child.value) { + if (name == 'allSlotRateRange') { + formgroup.get('allSlotRateRange')['controls'][0].addControl('childAgeRange', + this.fb.array([this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })]), + ); + } + if (name == 'activityPaxRate') { + formgroup.get('activityPaxRate').addControl('senior_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + } + if (this.PaxCheck.is_senior.value) { + if (name == 'allSlotRateRange') { + formgroup.get('allSlotRateRange')['controls'][0].addControl('seniorAgeRange', + this.fb.array([this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })]), + ); + } + if (name == 'activityPaxRate') { + formgroup.get('activityPaxRate').addControl('youth_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + } + + if (this.PaxCheck.is_youth.value) { + if (name == 'allSlotRateRange') { + formgroup.get('allSlotRateRange')['controls'][0].addControl('youthAgeRange', + this.fb.array([this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })]), + ); + } + if (name == 'activityPaxRate') { + formgroup.get('activityPaxRate').addControl('child_rate', this.fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + } + + } + addDateCont() { + this.DateControl.push( + this.fb.group({ + start: this.validationService.required, + end: this.validationService.required + }) + ) + } + + addCancel() { + this.CancelControl.push(this.fb.group({ + from: this.validationService.mobNo, + to: this.validationService.mobNo, + CP_Type: this.validationService.required, + // CP_Value: [''], + // cancellation_Type: this.validationService.required, + })) + } + + addSlotsDetail() { + this.SlotsDetail.push( + this.fb.group({ + slots: this.validationService.required, + transfer_type: [''], + }) + ) + } + + AllSelectedSlots = [] + AddRateSlots(obj, ind) { + let id = this.AllSlot.filter(li => li.activity_slot_id == obj); + let newslot = this.AllSelectedSlots.filter(e => e.activity_slot_id == id[0].activity_slot_id); + if (newslot.length <= 0) { + this.AllSelectedSlots[ind] = []; + this.AllSelectedSlots[ind] = id[0]; + } + } + + selectedSlots(obj, ind) { + this.slotList = []; + // this.RateConfigForm.get('slotDetails').value.map(li => { + // if (li.startHour && li.startMin && li.endHour && li.endMin) { + // this.slotList.push(li) + // } + // }) + } + addAdultAge(i, ind) { + if (this.AdultTControl(i, ind).length <= 5) { + this.AdultTControl(i, ind).push(this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })) + } + } + + addYouthAge(i, ind) { + if (this.YouthTControl(i, ind).length <= 5) { + this.YouthTControl(i, ind).push(this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })) + } + } + + addChildAge(i, ind) { + if (this.ChildTControl(i, ind).length <= 5) { + this.ChildTControl(i, ind).push(this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })) + } + } + + addSeniordAge(i, ind) { + if (this.SeniorTControl(i, ind).length <= 5) { + this.SeniorTControl(i, ind).push(this.fb.group({ + from_count: this.validationService.mobNo, + to_count: this.validationService.mobNo, + sequence: [''], + rate: this.validationService.decimal, + })) + } + } + + // REMOVE FUNCTION + + removePrivateTransferGroup(ind) { + this.privateTransferDataList.removeAt(ind); + } + removeSlotCont(ind) { + this.SlotsControl.removeAt(ind) + } + + removeDateCont(ind) { + this.DateControl.removeAt(ind) + } + + removeCancel(i) { + this.CancelControl.removeAt(i) + } + + removeSlotsDetail(ind) { + this.SlotsDetail.removeAt(ind) + } + + removeAdultAge(i, ind, secI) { + this.AdultTControl(i, ind).removeAt(secI) + } + + removeYouthAge(i, ind, secI) { + this.YouthTControl(i, ind).removeAt(secI) + } + + removeChildAge(i, ind, secI) { + this.ChildTControl(i, ind).removeAt(secI) + } + + removeSeniordAge(i, ind, secI) { + this.SeniorTControl(i, ind).removeAt(secI) + } + + removeInfantAge(i, ind, secI) { + this.InfantTControl(i, ind).removeAt(secI) + } + + isExcludeNationality(check) { + if (check) { + this.RateConfigForm.addControl('excNationalityCodes', this.fb.control([], Validators.required)); + this.remove_nationality('include') + } else this.RateConfigForm.removeControl('excNationalityCodes'); + } + + isIncludeNationality(val) { + if (val == '2') { + this.RateConfigForm.addControl('incNationalityCodes', this.fb.control([], Validators.required)); + this.RateConfigForm.get('incNationalityCodes').setValue([]); + } else if (val == '1') { + this.RateConfigForm.removeControl('incNationalityCodes'); + this.remove_nationality('exclude'); + } + } + + + // FUNCTIONS + checkFunc(check, controlName, val, arr) { + check ? this.addvalid(controlName, 'add', val, arr) : this.addvalid(controlName, 'remove', val, arr) + } + + addvalid(name, type, val, arr) { + if (type == 'add') { + let checkCont = arr != 'arr' ? this.fb.control(val, [Validators.required]) : this.fb.array([val], [Validators.required]) + this.RateConfigForm.addControl(name, checkCont) + this.RateConfigForm.controls[name].updateValueAndValidity(); + } else this.RateConfigForm.removeControl(name); + }; + + periodType(val) { + if (val == '1') { + this.checkFunc(false, 'seasonIdsForRateDates', '', '') + this.checkFunc(true, 'datesForRates', this.fb.group({ start: this.validationService.required, end: this.validationService.required }), 'arr') + } else { + this.checkFunc(true, 'seasonIdsForRateDates', '', '') + this.checkFunc(false, 'datesForRates', '', '') + } + } + + SeasonFilter(val) { + this.fil_season_list = [] + val.map(num => { + this.fil_season_list.push(this.season_list.filter(obj => obj.activitySeason.activity_season_id == num)) + }) + } + + startDateChange(ind) { + this.DateControl.controls[ind].get('end').setValue(this.DateControl.controls[ind].value.start) + } + + daysChange(e) { + e.option.id == 7 ? this.DaysControl.setValue(this.Day.map(ul => ul.id)) : + this.DaysControl.value.map((li, i) => li == 7 ? this.DaysControl.value.splice(i, 1) : ''); + } + + SlotChange(e) { + if (e == 1) this.AddSlotsControlValidations('SlotId', false); + else if (e == 2) this.AddSlotsControlValidations('SlotId', true); + if (e == 1 && this.SlotsControl.value.length != 1) { + this.SlotsControl.controls.splice(1, this.SlotsControl.controls.length) + } + } + + AddSlotsControlValidations(name, check) { + if (check) { + this.SlotsControl.controls[0].get(name).addValidators([Validators.required]); + this.SlotsControl.controls[0].get(name).updateValueAndValidity(); + this.SlotsControl.controls[0].get(name).markAsUntouched(); + } else { + this.SlotsControl.controls[0].get(name).clearValidators(); + this.SlotsControl.controls[0].get(name).updateValueAndValidity(); + this.SlotsControl.controls[0].get(name).markAsUntouched(); + } + }; + + GetAllCurrency() { + this.APIServ.Get('/Currency/GetCurrency').subscribe(d => { + if (d) this.currencyList = d; + }); + } + + GetPhoneCode() { + this.APIServ.Get('/CountryPhone/GetCountryPhone').subscribe(data => { + if (data) this.PhoneCode = data; + }); + } + + + + GetAllNationality() { + this.APIServ.Get('/Country/GetCountry').subscribe(res => { + if (res) { + this.all_nationality_list = res; + this.include_nationality_list = res; + this.exclude_nationality_list = res; + } + }); + } + AllSlot; + GetAllSlot() { + let post = new GetActivitySlot(); + let activity_id = CommonService.getSessionStoage('activity_id'); + post.activity_id = activity_id; + post.from_hour = null; + post.from_minute = null; + post.to_hour = null; + post.to_minute = null; + this.APIServ.Post('/ActivitySlot/GetAllSlot', post).subscribe(res => { + if (res) { + this.AllSlot = res['responseObject']; + } + }); + } + AllCountry; + getCountry() { + this.APIServ.Get('/Country/GetCountry').subscribe(data => { + if (data) { + this.AllCountry = data; + } + }); + }; + + GetAllActivitySeason() { + this.APIServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + CommonService.getSessionStoage('activity_id')).subscribe(d => { + if (d && d.status) { + this.season_list = d.responseObject; + } + }); + } + AllVehicleSupplier; + GetAllVehicleSupplier() { + this.APIServ.Get('/Vehicle/GetAllVehicleSupplier').subscribe(res => { + if (res) { + this.AllVehicleSupplier = res.responseObject; + } + }); + } + + AllVehicleBySupplierId = { + Shared: [], + Slots: [] + };; + GetAllVehicleBySupplierId(Id, name, i) { + this.APIServ.Get('/Vehicle/GetAllVehicleBySupplier/' + Id).subscribe(res => { + if (res) { + this.AllVehicleBySupplierId[name][i] = [] + this.AllVehicleBySupplierId[name][i] = res.responseObject; + } + }); + } + Set_Max_Occcupancy(obj, formgroup) { + formgroup.get('vehicle_max_occupancy').setValue(obj.max_passenger_capacity); + } + + setprivateOccupancy(obj, formgroup) { + formgroup.get('vehicle_occupancy').setValue(obj.max_passenger_capacity); + } + + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + } + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.APIServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + this.GetActivityById(); + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + } + + PaxCheck = { + is_youth: { + form: '', + to: '', + value: false + }, + is_senior: { + form: '', + to: '', + value: false + }, + is_adult: { + form: '', + to: '', + value: false + }, + is_child: { + form: '', + to: '', + value: false + }, + } + GetActivityById() { + let activity_id = CommonService.getSessionStoage('activity_id'); + this.APIServ.Get('/Activity/GetActivity/' + activity_id).subscribe(d => { + if (d && d.status) { + if (d.responseObject.activityContents && d.responseObject.activityContents.length > 0) { + this.activityData = d.responseObject; + this.PaxCheck.is_adult.value = this.activityData.is_adult; + this.PaxCheck.is_adult.to = this.activityData.adult_age_to; + this.PaxCheck.is_adult.form = this.activityData.adult_age_from; + + this.PaxCheck.is_child.value = this.activityData.is_child; + this.PaxCheck.is_child.form = this.activityData.child_age_from; + this.PaxCheck.is_child.to = this.activityData.child_age_to; + + this.PaxCheck.is_senior.value = this.activityData.is_senior; + this.PaxCheck.is_senior.form = this.activityData.senior_age_from; + this.PaxCheck.is_senior.to = this.activityData.senior_age_to; + + this.PaxCheck.is_youth.value = this.activityData.is_youth; + this.PaxCheck.is_youth.form = this.activityData.youth_age_from; + this.PaxCheck.is_youth.to = this.activityData.youth_age_to; + this.initRateConfigForm(); + this.RateConfigForm.get('experience_name').setValue(d.responseObject.activityContents[0].activity_name); + let county = this.activityData.country_code.split(',') + this.RateConfigForm.get('country_name').setValue(county); + this.getcity(this.activityData.country_code); + let city = this.activityData.city_id.split(','); + this.RateConfigForm.get('city_name').setValue(city); + let lang = d.responseObject._service_language.split(','); + lang.map(ln => { + this.lovKeyDataObj['Language'].map(li => { + if (ln == li.lov_value) { + this.LangList.push(li) + } + }) + }) + + + + } + console.log(this.PaxCheck) + } + }); + } + FreeSalesCheck(group, check) { + if (!check) { + group.addControl('allocation_count', this.fb.control('', [Validators.required, Validators.pattern(/^[0-9]*$/)])); + } else group.removeControl('allocation_count'); + } + getcity(code) { + this.APIServ.Get('/City/GetCity/' + code).subscribe(data => { + if (data) { + this.allCityDetials = data; + } + }); + }; + + // select_nataionality_type(nationality_type) { + // (nationality_type == 'all_nationality') ? + // this.RateConfigForm.removeControl('incNationalityCodes') : + // this.RateConfigForm.addControl('incNationalityCodes', this.fb.control('')); + // } + + remove_nationality(type) { + let con = type == 'exclude' ? 'incNationalityCodes' : 'excNationalityCodes' + type == 'exclude' ? this.exclude_nationality_list = [...this.all_nationality_list] : this.include_nationality_list = [...this.all_nationality_list]; + let list = type == 'exclude' ? this.exclude_nationality_list : this.include_nationality_list; + let nationality_arr = this.RateConfigForm.get(con).value ? this.RateConfigForm.get(con).value : []; + nationality_arr.forEach(nationality_code => { + let ind = list.findIndex(nationality_obj => nationality_obj.alpha_2_code == nationality_code); + (ind != -1) ? list.splice(ind, 1) : ''; + type == 'exclude' ? this.exclude_nationality_list = [...list] : this.include_nationality_list = [...list]; + }); + } + + SaveRate() { + let value = this.RateConfigForm.getRawValue(); + console.log(this.RateConfigForm) + if (this.RateConfigForm.status == 'INVALID') { + this.validationService.showValidationsMsg(this.RateConfigForm); + return; + }; + + let RateConfigModel = new SaveActivityContractDetails(); + let RateContract = new ActivityContract(); + let ArrRateContractDetail = new Array(); + let ArrRateDateRange = new Array(); + + // RATE CONTRACT + RateContract.org_id = value.org_id; + RateContract.activity_id = CommonService.getSessionStoage('activity_id'); + RateContract.supplier_id = value.supplier_id; + RateContract.currency_code = value.currency_code; + RateContract._nationality_type = value._nationality_type; + RateContract.is_exclude_nationality = value.is_exclude_nationality; + RateContract._period_type = value._period_type.toString(); + RateContract.season_id = value.seasonIdsForRateDates ? value.seasonIdsForRateDates.join(',') : ''; + RateContract._rate_type = value.slots[0]._rate_type.toString(); + RateContract._pricing_type = value.slots[0]._pricing_type.toString(); + RateContract.is_pickup_included = value.is_pickup_included; + RateContract.is_drop_off_included = value.is_drop_off_included; + RateContract.is_guide_included = value.is_guide_included; + RateContract.is_slot_wise_cancellation_policy = value.is_slot_wise_cancellation_policy; + RateContract._no_show_policy_type = value._no_show_policy_type.toString(); + RateContract.no_show_charge_value = value._no_show_policy_type != 1 ? value.no_show_charge_value : 0; + RateContract.guide_languages = value.guide_languages ? value.guide_languages.join(',') : ''; + RateContract.is_private_transfer_price_included = value.is_private_transfer_price_included; + RateContract.reviewed_by = 'Razzak' + RateContract.reviewer_comments = 'Razzak' + RateContract.reviewer_user_type = 'Razzak' + + // Private Tranfer Price Included + RateConfigModel.privateTransfer = []; + if (value.is_private_transfer_price_included) { + let val = this.privateTransferDataList.getRawValue() + let postarr = [] + val.forEach(e => { + let privateArr = new ActivityPrivateTransfer(); + privateArr.rate = e.rate; + privateArr.vehicle_id = e.vehicle_id; + privateArr.vehicle_occupancy = e.vehicle_occupancy; + privateArr.vehicle_supplier_id = e.vehicle_supplier_id; + postarr.push(privateArr); + }); + RateConfigModel.privateTransfer = postarr; + } + + // Shared Transfer Price Included + RateContract.is_shared_transfer_price_included = value.is_shared_transfer_price_included; + RateConfigModel.sharedTransfer = null; + if (value.is_shared_transfer_price_included) { + let SharetransferArr = new ActivitySharedTransfer(); + SharetransferArr.vehicle_supplier_id = value.vehicle_supplier_id + SharetransferArr.adult_rate = value.adult_rate ? value.adult_rate : 0; + SharetransferArr.senior_rate = value.senior_rate ? value.senior_rate : 0; + SharetransferArr.youth_rate = value.youth_rate ? value.youth_rate : 0; + SharetransferArr.child_rate = value.child_rate ? value.child_rate : 0; + RateConfigModel.sharedTransfer = SharetransferArr; + } + + + // Rate Period Type + RateConfigModel.datesForRates = []; + if (value._period_type == 1) { + value.datesForRates.map(li => { + let RateDateRange = new DateRange(); + RateDateRange.Start = moment(li.start, "HH:mm:ss").utc().format(''); + RateDateRange.End = moment(li.end, "HH:mm:ss").utc().format(''); + ArrRateDateRange.push(RateDateRange) + }) + RateConfigModel.datesForRates = ArrRateDateRange; + } + + RateConfigModel.seasonIdsForRateDates = []; + if (value._period_type == 2) { + RateConfigModel.seasonIdsForRateDates = value.seasonIdsForRateDates; + } + + + // ACTIVITY DETAILS + let RateContractDetail = new ActivityDetails(); + RateContractDetail.contract_remark = value.contract_remark; + RateContractDetail.language_code = CommonService.getSessionStoage('Def_Lang_code'); + RateContractDetail.option_name = value.option_name; + RateContractDetail.rate_inclusion = value.rate_inclusion; + ArrRateContractDetail.push(RateContractDetail); + + // Solts Details + let slotsDetaisl = [] + RateConfigModel.slotDetails = []; + value.slots.forEach(e => { + + let postDataArr = new SlotDetails(); + postDataArr.applicableDays = e.applicableDays.join(','); + if (value.slots[0]._rate_type == '1') { + + let slotDetail = e.allSlotRateRange[0]; + let RateTieredPricing = new RateRange(); + let ArrAdultAgeRange = new Array(); + let ArrYouthAgeRange = new Array(); + let ArrSeniorAgeRange = new Array(); + let ArrChildAgeRange = new Array(); + + // Adult + slotDetail.adultAgeRange ? slotDetail.adultAgeRange.map((li, i) => { + let AdultAgeRange = new AgeRange(); + AdultAgeRange.from_count = li.from_count; + AdultAgeRange.to_count = li.to_count; + AdultAgeRange.rate = li.rate; + AdultAgeRange.sequence = i + 1; + ArrAdultAgeRange.push(AdultAgeRange) + }) : ''; + // Youth + slotDetail.youthAgeRange ? slotDetail.youthAgeRange.map((li, i) => { + let YouthAgeRange = new AgeRange(); + YouthAgeRange.from_count = li.from_count; + YouthAgeRange.to_count = li.to_count; + YouthAgeRange.rate = li.rate; + YouthAgeRange.sequence = i + 1; + + ArrYouthAgeRange.push(YouthAgeRange) + }) : ''; + // Senior + slotDetail.seniorAgeRange ? slotDetail.seniorAgeRange.map((li, i) => { + let SeniorAgeRange = new AgeRange(); + SeniorAgeRange.from_count = li.from_count; + SeniorAgeRange.to_count = li.to_count; + SeniorAgeRange.rate = li.rate; + SeniorAgeRange.sequence = i + 1; + + ArrSeniorAgeRange.push(SeniorAgeRange) + }) : ''; + // Child + slotDetail.childAgeRange ? slotDetail.childAgeRange.map((li, i) => { + let ChildAgeRange = new AgeRange(); + ChildAgeRange.from_count = li.from_count; + ChildAgeRange.to_count = li.to_count; + ChildAgeRange.rate = li.rate; + ChildAgeRange.sequence = i + 1; + + ArrChildAgeRange.push(ChildAgeRange) + }) : ''; + + RateTieredPricing.adultAgeRange = ArrAdultAgeRange; + RateTieredPricing.childAgeRange = ArrChildAgeRange; + RateTieredPricing.seniorAgeRange = ArrSeniorAgeRange; + RateTieredPricing.youthAgeRange = ArrYouthAgeRange; + let post = new AllocationDetails(); + post._allocation_type = slotDetail.is_free_sales ? '1' : '3'; + post.allocation_count = slotDetail.is_free_sales ? 0 : slotDetail.allocation_count; + post.release_days = slotDetail.release_days; + post._release_type = '1'; + post.vehicle_id = 'er'; + RateTieredPricing.allocationDetails = post; + postDataArr.rateRange = RateTieredPricing; + } + if (value.slots[0]._rate_type == '2') { + let slotDetail = value.slots[0].activityPaxRate; + let RatePerPerson = new ActivityPaxRate(); + RatePerPerson.adult_rate = slotDetail.adult_rate; + RatePerPerson.child_rate = slotDetail.child_rate; + RatePerPerson.senior_rate = slotDetail.senior_rate; + RatePerPerson.youth_rate = slotDetail.youth_rate; + + let post = new AllocationDetails(); + post._allocation_type = slotDetail.is_free_sales ? '1' : '3'; + post.allocation_count = slotDetail.is_free_sales ? 0 : slotDetail.allocation_count; + post.release_days = slotDetail.release_days; + post._release_type = '1'; + post.vehicle_id = 'er'; + RatePerPerson.allocationDetails = post; + postDataArr.activityPaxRate = RatePerPerson; + } + if (value.slots[0]._rate_type == '3') { + let slotDetail = e.activityVehicleRate; + let postdata = []; + slotDetail.forEach(li => { + let RateVehicle = new ActivityVehicleRate(); + RateVehicle.rate = slotDetail[0].rate ? li.rate : 0; + // RateVehicle.vehicle_max_occupancy = li.vehicle_max_occupancy ? parseInt(li.vehicle_max_occupancy) : 0; + RateVehicle.vehicle_max_occupancy = li.vehicle_max_occupancy; + RateVehicle.vehicle_id = li.vehicle; + RateVehicle.vehicle_supplier_id = li.vehicleSupplier; + let post = new AllocationDetails(); + post._allocation_type = slotDetail.is_free_sales ? '1' : '3'; + post.allocation_count = slotDetail.is_free_sales ? 0 : slotDetail.allocation_count; + post.release_days = slotDetail.release_days; + post._release_type = '1'; + post.vehicle_id = 'er'; + RateVehicle.allocationDetails = post; + postdata.push(RateVehicle); + }) + postDataArr.activityVehicleRate = postdata; + } + if (value.is_slot_wise_cancellation_policy) { + let slotspolicy = e.activityCancellationDetails; + let postdata = []; + slotspolicy.forEach(li => { + let arr = new ActivityCancellationDetails(); + arr.CP_Type = li.CP_Type.toString(); + arr.CP_Value = li.CP_Type != 1 ? li.CP_Value : 0; + arr.cancellation_Type = slotspolicy[0].cancellation_Type.toString(); + arr.from = li.from; + arr.to = li.to; + postdata.push(arr); + }) + postDataArr.activityCancellationDetails = postdata; + } + if (value.slots[0]._pricing_type == 1) { + let allslots = []; + value.slotDetails.forEach(li => { + let post = new Slots(); + post.slotId = li.slots + post.is_private_transfer = false; + post.is_without_transfer = false; + post.is_shared_transfer = false; + li.transfer_type.forEach(q => { + if (q == 1) post.is_private_transfer = true; + if (q == 2) post.is_without_transfer = true; + if (q == 3) post.is_shared_transfer = true; + }) + allslots.push(post); + }) + postDataArr.slot = allslots; + } + else if (value.slots[0]._pricing_type == 2) { + let allslots = []; + e.SlotId.forEach(q => { + let arr = value.slotDetails.filter(li => li.slots == q); + let post = new Slots(); + post.slotId = arr[0].slots; + post.is_private_transfer = false; + post.is_without_transfer = false; + post.is_shared_transfer = false; + arr[0].transfer_type.forEach(z => { + if (z == 1) post.is_private_transfer = true; + if (z == 2) post.is_without_transfer = true; + if (z == 3) post.is_shared_transfer = true; + }) + allslots.push(post); + postDataArr.slot = allslots; + }); + } + slotsDetaisl.push(postDataArr); + }) + RateConfigModel.slotDetails = slotsDetaisl; + + // Activity Cancellation Details + RateConfigModel.activityCancellationDetails = []; + if (!value.is_slot_wise_cancellation_policy) { + let policyDetails = value.activityCancellationDetails; + let postdata = []; + policyDetails.forEach(li => { + let arr = new ActivityCancellationDetails(); + arr.cancellation_Type = policyDetails[0].cancellation_Type.toString(); + arr.CP_Type = li.CP_Type.toString(); + arr.CP_Value = li.CP_Type != 1 ? li.CP_Value : 0; + arr.from = li.from; + arr.to = li.to; + postdata.push(arr); + }) + RateConfigModel.activityCancellationDetails = postdata; + }; + + RateConfigModel.activityContract = RateContract; + RateConfigModel.incNationalityCodes = value.incNationalityCodes ? value.incNationalityCodes : []; + RateConfigModel.excNationalityCodes = value.excNationalityCodes ? value.excNationalityCodes : []; + RateConfigModel.activityContractDetails = ArrRateContractDetail; + console.log(RateConfigModel); + this.APIServ.Post('/ActivityContract/SaveActivityContract', RateConfigModel).subscribe(res => { + if (res) { + this.showToastrMsg(res) + } + }) + } + + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']) + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.html new file mode 100644 index 0000000..21f26cf --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.html @@ -0,0 +1,137 @@ +
    + + Back +
    +
    Modify Allocation
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + + + {{ item.start_time | date : 'HH:mm'}} to {{item.end_time| date : 'HH:mm'}} + + + Please select Slot +
    +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + + {{ activity_obj.activitySeason.season_name}} + +
    +
    + + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    +
    Date
    +
    +
    + Allocation + +
    +
    +
    + Release Days + +
    +
    +
    Free Sale
    +
    +
    Stop Sale
    +
    {{data._date | date : "dd MMM YYYY"}} + + + + + + + + + +
    +
    + +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.ts new file mode 100644 index 0000000..4c0bed9 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-allocation/edit-allocation.component.ts @@ -0,0 +1,410 @@ +import { Component, OnInit, ElementRef, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AllocationItems, UpdateAllocation } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model'; +import { GetCancellationPolicy } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model'; +import { GetRateDetails } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model'; +// import { AllocationItems, UpdateAllocation } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-allocation/edit-allocation.model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; +interface grp { + name: string; + code: string; +} +@Component({ + selector: 'app-edit-allocation', + templateUrl: './edit-allocation.component.html', +}) +export class EditAllocationComponent implements OnInit { + + FormData: FormGroup + activityContractId; + activityContract; + DaySelect; + NoShowPolicyType; + AllSlotData; + AllocationDetails; + SoltDate; + slot_wise_cancellation_policy; + RateConfigdata + AllSlots; + lovKeyDataObj = { + RatePeriodType: [], + DaySelect: [], + ActivityNoShowPolicyType: [], + ActivityCancellationPolicyType: [], + ActivityCancellationChargeType: [], + }; + season_list; + constructor(private router: Router, private route: ActivatedRoute, public ApiServ: API, public Fb: FormBuilder, public MsgService: MessageService, public validationService: ValidationService) { } + ngOnInit(): void { + this.NgOinitFrom(); + this.GetSlotData(); + this.GetRateConfig(); + this.GetAllActivitySeason(); + this.GetLOVKeys('RatePeriodType,DaySelect,ActivityNoShowPolicyType,ActivityCancellationPolicyType,ActivityCancellationChargeType'); + }; + + + /** + * @author Abdul Razzak + * To create form group + */ + NgOinitFrom() { + this.FormData = this.Fb.group({ + option_name: [''], + activity_name: [''], + period_type: [''], + seasonId: [''], + dates: [''], + days: [''], + Allocation_list: this.Fb.array([ + this.Fb.group({ + allocation_count: [''], + release_days: [''], + FreeSale: [false], + StopSale: [false], + }) + ]) + }); + } + + /** + * @author Abdul Razzak + * to get activity contract data by contract id and set value + */ + GetRateConfig() { + this.route.queryParams.subscribe(obj => { + if (obj['id']) { + this.GetActivityById(); + this.activityContractId = obj['id']; + this.GetSlotsById(obj['id']); + this.ApiServ.Get('/ActivityContract/GetRateConfig/' + obj['id']).subscribe(d => { + if (d && d.status) { + this.RateConfigdata = d.responseObject; + d.responseObject.is_slot_wise_cancellation_policy; + if (d.responseObject.is_slot_wise_cancellation_policy) { + this.FormData.addControl('slot_id', this.Fb.control('',[Validators.required])); + } + this.FormData.get('option_name').setValue(d.responseObject.option_name); + + } + }) + } + }); + } + + /** + * @author Abdul Razzak + * to get slot data by contract id + * @param Id + */ + GetSlotsById(Id) { + this.ApiServ.Get('/ActivityContract/GetSlotsById/' + Id).subscribe(res => { + if (res) { + this.AllSlots = res.responseObject; + } + }) + } + + + /** + * @author Abdul Razzak + * to get activity details + */ + GetActivityById() { + let activity_id = CommonService.getSessionStoage('activity_id'); + this.ApiServ.Get('/Activity/GetActivity/' + activity_id).subscribe(res => { + if (res) { + this.FormData.get('activity_name').setValue(res.responseObject.activityContents[0].activity_name); + } + }) + } + + /** + * @author Abdul razzak + * to set value + */ + CopyOnUi() { + console.log('this.allocationValue.nativeElement.value') + let Group = this.Allocation_list.getRawValue(); + let newgroup = Group.splice(0, 1) + + Group.map((e, i) => { + !newgroup[0].FreeSale ? this.Allocation_list.controls[i + 1].get('allocation_count').setValue(newgroup[0].allocation_count) : ''; + this.StopSalecheck(newgroup[0].StopSale, i + 1); + this.freesalecheck(newgroup[0].FreeSale, i + 1); + this.Allocation_list.controls[i + 1].get('StopSale').setValue(newgroup[0].StopSale); + this.Allocation_list.controls[i + 1].get('FreeSale').setValue(newgroup[0].FreeSale); + this.Allocation_list.controls[i + 1].get('release_days').setValue(newgroup[0].release_days); + }); + + } + + + /** + * @author Abdul Razzak + * to get data from LOV + * @param lov_key_names + */ + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + } + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + this.GetActivityById(); + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + } + + + /** + * @author Abdul Razzak + * to get all activity season data + */ + GetAllActivitySeason() { + this.ApiServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + CommonService.getSessionStoage('activity_id')).subscribe(d => { + if (d && d.status) { + this.season_list = d.responseObject; + } + }); + } + + /** + * @author Abdul Razzak + * to get form group controls + */ + get Allocation_list() { + return this.FormData.get('Allocation_list') as FormArray + }; + + /** + * @author Abdul Razzak + * to set value for each form list + * @param data + */ + setValue(data) { + this.Allocation_list.clear(); + this.addForm(); + for (let i = 0; i < data.length; i++) { + this.addForm(); + let formval = this.Allocation_list.controls[i + 1].value; + Object.keys(formval).forEach(a => { + if (a == 'StopSale' || a == 'FreeSale') { + if (data[i]['_allocation_type'] == '1') { + this.Allocation_list.controls[i + 1].get('FreeSale').setValue(true); + this.freesalecheck(true, i + 1); + } + if (data[i]['_allocation_type'] == '2') { + this.Allocation_list.controls[i + 1].get('StopSale').setValue(true); + this.StopSalecheck(true, i + 1); + } + } + else { + this.Allocation_list.controls[i + 1].get(a).setValue(data[i][a]); + } + }); + } + }; + + /** + * @author Abdul Razzak + * to create allocation form group + * + */ + addForm() { + this.Allocation_list.push(this.Fb.group({ + allocation_count: [''], + release_days: [''], + FreeSale: [false], + StopSale: [false], + _date: [''], + activity_allocation_id: [''], + })); + }; + + /** + * @author Abdul Razzak + * to get slots list by contract id + */ + GetSlotData() { + this.ApiServ.Get('/ActivityContract/GetSlotsById/' + this.activityContractId).subscribe(data => { + if (data) { + this.AllSlotData = data.responseObject; + } + }); + }; + + /** + * @author Abdul Razzak + * to clear input field + */ + ClearSearchField() { + let val = this.FormData.getRawValue() + if (val.period_type == 2) this.FormData.get('dates').setValue(''); + else if (val.period_type == 1) this.FormData.get('seasonId').setValue([]); + } + + Months = [ + { id: 1, name: 'Jan' }, + { id: 2, name: 'Feb' }, + { id: 3, name: 'Mar' }, + { id: 4, name: 'Apr' }, + { id: 5, name: 'Jun' }, + { id: 6, name: 'Jun' }, + { id: 7, name: 'Jul' }, + { id: 8, name: 'Aug' }, + { id: 9, name: 'Sep' }, + { id: 10, name: 'Oct' }, + { id: 11, name: 'Nov' }, + { id: 12, name: 'Dec' }, + ]; + MonthsList = this.Months[0].name; + + /** + * @author Abdul razzak + * to get all allocation details + */ + getAllocationDetails() { + let val = this.FormData.getRawValue(); + let postdata = new GetRateDetails(); + postdata.from_date = val.dates[0] ? moment(val.dates[0]).format('YYYY-MM-DD') : ''; + postdata.to_date = val.dates[1] ? moment(val.dates[1]).format('YYYY-MM-DD') : ''; + postdata.dates = ''; + postdata.slot_id = val.slot_id ? val.slot_id : ''; + postdata.seasonId = val.seasonId ? val.seasonId : []; + postdata.days = val.days ? val.days.join(',') : ''; + postdata.contract_id = this.activityContractId; + + this.ApiServ.Post('/ActivityContract/GetAllocationDetails', postdata).subscribe(data => { + if (data) { + this.AllocationDetails = data.responseObject; + data.responseObject ? this.setValue(data.responseObject) : ''; + } + }); + }; + + + + /** + * @author Abdul Razzak + * to update allocation value + * @returns + */ + updateAllocation() { + if (this.FormData.status == "INVALID") { + this.validationService.showValidationsMsg(this.FormData); + const firstElementWithError = document.querySelector('.ng-invalid'); + if (firstElementWithError) { + firstElementWithError.scrollIntoView({ behavior: 'smooth' }); + } + return; + } + let value = this.FormData.getRawValue(); + let postArr = []; + value.Allocation_list.splice(0, 1) + value.Allocation_list.map((e, i) => { + let items = new AllocationItems(); + if (value.Allocation_list[i].FreeSale) { + items._allocation_type = '1'; + } else if (value.Allocation_list[i].StopSale) { + items._allocation_type = '2'; + } else items._allocation_type = '3'; + items.allocation_count = value.Allocation_list[i].allocation_count ? value.Allocation_list[i].allocation_count : 0; + items.release_days = value.Allocation_list[i].release_days ? value.Allocation_list[i].release_days : 0; + items.activity_allocation_id = value.Allocation_list[i].activity_allocation_id; + postArr.push(items) + }) + + let PostData = new UpdateAllocation(); + PostData.activity_contract_id = this.activityContractId; + PostData.activity_slot_id = value.slot_id ? value.slot_id : ''; + PostData.allocationItems = postArr; + this.ApiServ.Post('/ActivityContract/UpdateActivityAllocation', PostData).subscribe((res) => { + if (res) { + this.showToastrMsg(res) + } + }); + }; + + /** + * @author Abdul Razzak + * to show toaster + * @param respData + */ + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + /** + * @author Abdul Razzak + * to navigate overview + */ + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']) + } + + /** + * @author Abdul Razzak + * to disable checkbox + * @param Check + * @param Ind + */ + freesalecheck(Check, Ind) { + if (Check) { + this.Allocation_list.controls[Ind].get('StopSale').disable(); + this.Allocation_list.controls[Ind].get('allocation_count').disable(); + this.Allocation_list.controls[Ind].get('allocation_count').setValue(''); + } else { + this.Allocation_list.controls[Ind].get('allocation_count').enable(); + this.Allocation_list.controls[Ind].get('StopSale').enable(); + } + }; + + /** + * @author Abdul Razzak + * to disable checkbox + * @param Check + * @param Ind + */ + StopSalecheck(Check, Ind) { + if (Check) { + this.Allocation_list.controls[Ind].get('FreeSale').disable(); + } else { + this.Allocation_list.controls[Ind].get('FreeSale').enable(); + } + }; + + /** + * @author Abdul Razzak + * to reset search value + */ + reset() { + this.FormData.get('seasonId').setValue([]); + this.FormData.get('dates').setValue(''); + this.FormData.get('period_type').setValue(''); + this.FormData.get('slot_id').setValue(''); + this.FormData.get('slot_id').markAsUntouched(); + this.FormData.get('days').setValue(''); + } + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.html new file mode 100644 index 0000000..e93531c --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.html @@ -0,0 +1,161 @@ +
    + + Back +
    +
    Modify Cancellation
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + + + Please select No Show Type +
    +
    + + + Please enter value + accept number only +
    +
    +
    +
    +
    +
    + + + + {{ item.start_time | date : 'HH:mm'}} to {{item.end_time| date : 'HH:mm'}} + + +
    +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + + {{ activity_obj.activitySeason.season_name}} + +
    +
    + + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + +
    +
    Date
    +
    +
    Days
    +
    +
    Policy Type
    +
    +
    Cancellation Type
    +
    +
    Range
    +
    +
    + Value + +
    +
    {{data.get('_date').value| date: 'dd MMM YYYY'}}{{data.get('_date').value| date : 'EEEE'}} +
    + + +
    +
    +
    + + +
    +
    {{data.get('_from').value}} to {{data.get('_to').value}} + + + +
    +
    +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.ts new file mode 100644 index 0000000..b2e41b3 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-cancelletion-policy/edit-cancelletion-policy.component.ts @@ -0,0 +1,472 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import * as moment from 'moment'; +import { ValidationService } from 'src/app/core/common/validation.service'; +// import { CancellationDisplay, GetCancellationPolicy, UpdateCancellationPolicy } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model'; +import { MessageService } from 'primeng/api'; +import { CommonService } from 'src/app/core/services/common.service'; +import { CancellationDisplay, GetCancellationPolicy, UpdateCancellationPolicy } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-cancellation-policy/edit-cancellation-policy.model'; +interface grp { + name: string, + code: string +} +@Component({ + selector: 'app-edit-cancelletion-policy', + templateUrl: './edit-cancelletion-policy.component.html', +}) +export class EditCancelletionPolicyComponent implements OnInit { + Pickup: string[] = []; + date1!: Date; + date2!: Date; + CommonCalender!: string; + FromData: FormGroup + Data; + AllSlots; + activityContractId; + RateConfigdata; + season_list; + slot_wise_cancellation_policy; + lovKeyDataObj = { + RatePeriodType: [], + DaySelect: [], + ActivityNoShowPolicyType: [], + ActivityCancellationPolicyType: [], + ActivityCancellationChargeType: [], + }; + + constructor(private route: ActivatedRoute, + public ApiServ: API, public Fb: FormBuilder, + public validationService: ValidationService, + private MsgService: MessageService, + private router: Router,) { } + + ngOnInit(): void { + this.GetLOVKeys('RatePeriodType,DaySelect,ActivityNoShowPolicyType,ActivityCancellationPolicyType,ActivityCancellationChargeType'); + this.GetRateConfig(); + this.ngOninForm(); + this.GetAllActivitySeason(); + } + + + /** + * @author Abdul Razzak + * to create form group + */ + ngOninForm() { + this.FromData = this.Fb.group({ + activity_name: [''], + option_name: [''], + period_type: [''], + slot_id: [''], + dates: [''], + days: [''], + seasonId: [''], + _no_show_policy_type: this.validationService.required, + cancellationDisplays: this.Fb.array([ + ]) + }); + } + + /** + * @author Abdul Razzak + * to get activity contract data by contract id and set value + */ + GetRateConfig() { + this.route.queryParams.subscribe(obj => { + if (obj['id']) { + this.GetActivityById(); + this.activityContractId = obj['id']; + this.GetSlotsById(obj['id']); + this.ApiServ.Get('/ActivityContract/GetRateConfig/' + obj['id']).subscribe(d => { + if (d && d.status) { + this.RateConfigdata = d.responseObject; + this.slot_wise_cancellation_policy = d.responseObject.is_slot_wise_cancellation_policy; + this.FromData.get('option_name').setValue(d.responseObject.option_name); + this.FromData.get('_no_show_policy_type').setValue(parseInt(d.responseObject._no_show_policy_type)); + if (d.responseObject._no_show_policy_type != 1) { + this.No_Show_Type(d.responseObject._no_show_policy_type); + this.FromData.get('no_show_charge_value').setValue(d.responseObject.no_show_charge_value); + } + } + }) + } + }); + } + + /** + * @author Abdul Razzak + * to get slot data by contract id + * @param Id + */ + GetSlotsById(Id) { + this.ApiServ.Get('/ActivityContract/GetSlotsById/' + Id).subscribe(res => { + if (res) { + this.AllSlots = res.responseObject; + } + }) + } + /** + * @author Abdul Razzak + * to get form controls + */ + get cancelDisplay() { + return this.FromData.get('cancellationDisplays') as FormArray; + }; + + // AddFormDate() { + // this.cancelDisplay.push(this.Fb.group({ + // _charge_type: this.validationService.required, + // charge_value: [''], + // _from: [''], + // _to: [''], + // _date: [''], + // activity_cancellation_policy_id: [''], + // // _cancellation_policy_type: this.validationService.required, + // })) + // } + + // cancellationDisplays; + // SetValue(d) { + // let value = this.FromData.getRawValue(); + // this.cancellationDisplays = d.cancellationDisplays; + // this.setinputVal(d.cancellationDisplays); + // // Object.keys(value).forEach(e => { + // // if (e != 'cancellationDisplays') { + // // this.FromData.get(e).setValue(d[e]); + // // } + // // }); + + + // } + + + + // setinputVal(data) { + // for (let i = 0; i < data.length; i++) { + // console.log(i); + // this.AddFormDate() + // let formval = this.cancelDisplay.controls[i].value + // Object.keys(formval).forEach(a => { + // console.log(a) + // if (a == "_charge_type") { + // this.cancelDisplay.controls[i].get('_charge_type').setValue(parseInt(data[i][a])); + // } + // // else if (a == '_cancellation_policy_type') { + // // this.cancelDisplay.controls[i].get(a).setValue(parseInt(data[i][a])); + // // } + // else if (a == 'charge_value') { + // this.cancelDisplay.controls[i].get('charge_value').setValue(this.cancelDisplay.controls[i].get('_charge_type').value == '1' ? '' : data[i][a]); + // } + // else { + // this.cancelDisplay.controls[i].get(a).setValue(data[i][a]); + // } + // }); + // }; + // }; + + // LOVCancallationData; + // LOVCancallationPolicy; + // GetLOVMater() { + // let formdata = { + // "lov_types": [ + // { "lov_type": "NoShowType" }, + // { "lov_type": "CancellationPolicyType" } + // ], + // "lov_lang": "EN" + // } + + // this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + // if (data) { + // this.LOVCancallationData = data.responseObject[0].keys; + // this.LOVCancallationPolicy = data.responseObject[1].keys; + // } + + + + /** + * @author Abdul Razzak + * to check cancellation type if full amount is selected then + * @param val + * @param ind + */ + InputClear(val, ind, group) { + if (val == '1') { + this.cancelDisplay.controls[ind].get('charge_value').setValue(''); + this.addvalidNum('charge_value', val, group); + } else this.addvalidNum('charge_value', val, group); + }; + + + addvalidNum(name, val, group) { + if (val == '1') { + group.controls[name].clearValidators(); + group.controls[name].updateValueAndValidity(); + group.controls[name].markAsUntouched(); + } else { + group.controls[name].addValidators([Validators.required, Validators.pattern(/^[0-9.]*$/)]); + group.controls[name].updateValueAndValidity(); + } + }; + + /** + * @author Abdul Razzak + * to empty value + * @param ind + */ + No_Show_Type(ind) { + if (ind != 1) { + this.FromData.addControl('no_show_charge_value', this.Fb.control('', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } else { + this.FromData.removeControl('no_show_charge_value'); + } + } + + /** + * @author Abdul Razzak + * to get data from LOV + * @param lov_key_names + */ + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + } + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + this.GetActivityById(); + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + } + + /** + * @author Abdul Razzak + * to get activity details + */ + GetActivityById() { + let activity_id = CommonService.getSessionStoage('activity_id'); + this.ApiServ.Get('/Activity/GetActivity/' + activity_id).subscribe(res => { + if (res) { + this.FromData.get('activity_name').setValue(res.responseObject.activityContents[0].activity_name); + } + }) + } + + /** + * @author Abdul Razzak + * to remove specific row of cancellation policy list + * @param ind + */ + remove(ind) { + this.cancelDisplay.removeAt(ind); + } + + CopyValue() { + let val = this.cancelDisplay.getRawValue(); + for (let i = 1; i < val.length; i++) { + this.cancelDisplay.controls[i].get('charge_value').setValue(this.cancelDisplay.controls[i].get('_charge_type').value != '1' ? val[0].charge_value : ''); + } + } + + CopyBlocksValue() { + let val = this.cancelDisplay.getRawValue(); + for (let i = 1; i < val.length; i++) { + this.cancelDisplay.controls[i].get('_cancellation_policy_type').setValue(val[0]._cancellation_policy_type); + this.cancelDisplay.controls[i].get('_charge_type').setValue(val[0]._charge_type); + this.cancelDisplay.controls[i].get('charge_value').setValue(this.cancelDisplay.controls[i].get('_charge_type').value != '1' ? val[0].charge_value : ''); + + } + } + + /** + * @author Abdul Razzak + * to get all activity season data + */ + GetAllActivitySeason() { + this.ApiServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + CommonService.getSessionStoage('activity_id')).subscribe(d => { + if (d && d.status) { + this.season_list = d.responseObject; + } + }); + } + + /** + * @author Abdul Razzak + * to get all cancellation details + */ + SearchCancellationPolicy() { + let val = this.FromData.getRawValue(); + let postdata = new GetCancellationPolicy(); + postdata.from_date = val.dates[0] ? moment(val.dates[0]).format('YYYY-MM-DD') : ''; + postdata.to_date = val.dates[1] ? moment(val.dates[1]).format('YYYY-MM-DD') : ''; + postdata.slot_id = val.slot_id ? val.slot_id : ''; + postdata.seasonId = val.seasonId ? val.seasonId : []; + postdata.days = val.days ? val.days.join(',') : ''; + postdata.contract_id = this.activityContractId; + this.ApiServ.Post('/ActivityContract/GetCancellationPolicy', postdata).subscribe(res => { + if (res) { + this.SetPolicyValue(res.responseObject) + } + }) + } + /** + * @author Abdul Razzak + * method to create form group controler and set value + * @param data + */ + SetPolicyValue(data) { + this.cancelDisplay.clear() + data.forEach(d => { + this.cancelDisplay.push(this.Fb.group({ + _charge_type: [parseInt(d._charge_type), [Validators.required]], + charge_value: parseInt(d._charge_type) == 1 ? [''] : [d.charge_value, [Validators.required, Validators.pattern(/^[0-9.]*$/)]], + _from: [d._from], + _to: [d._to], + _date: [d._date], + activity_cancellation_policy_id: [d.activity_cancellation_policy_id], + _cancellation_policy_type: [parseInt(d._cancellation_policy_type), [Validators.required]] + })) + }) + } + + /** + * @author Abdul Razzak + * method to update cancellation details + */ + UpdateCancellationDetails() { + let postArrayData = []; + if (this.FromData.status == 'INVALID') { + this.validationService.showValidationsMsg(this.FromData); + const firstElementWithError = document.querySelector('.ng-invalid'); + if (firstElementWithError) { + firstElementWithError.scrollIntoView({ behavior: 'auto' }); + } + return; + }; + let val = this.FromData.getRawValue() + let ValArr = this.cancelDisplay.getRawValue(); + ValArr.map(e => { + let PostArray = new CancellationDisplay(); + PostArray._cancellation_policy_type = e._cancellation_policy_type.toString(); + PostArray._charge_type = JSON.stringify(e._charge_type); + PostArray.charge_value = e.charge_value ? e.charge_value : 0; + PostArray.activity_cancellation_policy_id = e.activity_cancellation_policy_id; + PostArray.date = e.date; + PostArray.from = e.from; + PostArray.to = e.to; + postArrayData.push(PostArray); + }) + let PostData = new UpdateCancellationPolicy(); + PostData.activity_contract_id = this.activityContractId; + PostData._no_show_policy_type = val._no_show_policy_type.toString(); + PostData.no_show_value = val.no_show_charge_value ? val.no_show_charge_value : 0; + PostData.cancellation_policy = postArrayData; + this.ApiServ.Post('/ActivityContract/UpdateActivityCancellation', PostData).subscribe(data => { + if (data) { + this.showToastrMsg(data) + } + }); + }; + /** + * @author Abdul Razzak + * to show toastr + * @param respData + */ + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + + /** + * @author Abdul razzak + * to navigate overview tab + */ + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']) + } + + + + /** + * @author Abdul Razzak + * to clear hide field value + */ + ClearSearchField() { + let val = this.FromData.getRawValue() + if (val.period_type == 2) this.FromData.get('dates').setValue(''); + else if (val.period_type == 1) this.FromData.get('seasonId').setValue([]); + } + + + + AllMonths = [] + Checkdate() { + let date = this.FromData.get('dates').value + console.log(date) + if (date.length > 1) { + // var result = eachMonthOfInterval({ + // start: new Date(date[0]), + // end: new Date(date[1]) + // }); + // console.log(result); + let allname = [] + // this.AllMonths = result.map(e => allname.push(moment(e).format("MMM"))) + this.AllMonths = [...new Set(allname)]; + } + } + + checkMonthOfSeason() { + this.season_list + console.log(this.season_list) + let alldate = []; + let val = this.FromData.get('seasonId').value; + val.forEach(ID => { + this.season_list.forEach(q => { + if (q.activitySeason.activity_season_id == ID) { + q.seasondateRange.forEach(t => { + // var result = eachMonthOfInterval({ + // start: new Date(t.fromDate), + // end: new Date(t.toDate) + // }); + // let list = result.map(r => moment(r).format("MMM")); + // alldate.push(...list); + }); + }; + }); + }); + let AllDateName = [...new Set(alldate)]; + this.AllMonths = AllDateName; + } + + MonthCheck(data) { + console.log(data) + } + + /** + * @author Abdul Razzak + * to reset search value + */ + reset() { + this.FromData.get('seasonId').setValue([]); + this.FromData.get('dates').setValue(''); + this.FromData.get('period_type').setValue(''); + this.FromData.get('slot_id').setValue(''); + this.FromData.get('days').setValue(''); + } + + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.html new file mode 100644 index 0000000..a1b6c6c --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.html @@ -0,0 +1,183 @@ +
    + + Back +
    +
    Edit Details
    +
    +
    +
    + + + Please enter option name +
    +
    + + +
    +
    + + + +
    + +
    Currency
    +
    + +
    +
    + Please select currency +
    +
    +
    Applicable Nationality
    +
    + +
    +
    + All Nationality +
    +
    + Specify Nationality +
    +
    +
    + + + +
    + +
    Nationality
    +
    + +
    +
    + Please select Nationality + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Is Exclude Nationality + +
    +
    +
    + + + +
    + +
    Nationality
    +
    + +
    +
    + Please select currency +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + Tourist Guide Included +
    +
    + + + + Please select tourist guide languages +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.ts new file mode 100644 index 0000000..28f0df7 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-details/edit-details.component.ts @@ -0,0 +1,479 @@ +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { ActivatedRoute } from '@angular/router'; +import * as moment from 'moment'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { EditActivityContractDetail } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; + +@Component({ + selector: 'app-edit-details', + templateUrl: './edit-details.component.html', +}) +export class EditDetailsComponent implements OnInit { + constructor( + private route: ActivatedRoute, + public Fb: FormBuilder, + public APIServ: API, + public validationService: ValidationService + ) {} + Pickup: string[] = []; + CommonCalender: string[] = []; + // + FormData: FormGroup; + currencyList; + activityContractId; + PhoneCode; + include_nationality_list; + exclude_nationality_list; + fil_exclude_nationality_list; + PaxDetails; + vahicleDetails; + LangList = []; + DaySelect = []; + AllSlotData; + SoltDate; + @ViewChild('Vehicle_Rate_copy') Vehicle_Rate_copy: ElementRef; + @ViewChild('myCalendar') datePicker; + ngOnInit(): void { + this.FormData = this.Fb.group({ + option_name: this.validationService.required, + emergency_phone_code: this.validationService.required, + emergency_phone: this.validationService.mobNo, + currency_code: this.validationService.required, + is_exclude_nationality: [false], + include_nationality_code: [''], + exclude_nationality_code: [''], + contract_remark: [''], + rate_inclusion: [''], + _nationality_type: [''], + Solt_data: [''], + Search_date: [''], + Days: [''], + is_pickup_included: [false], + is_drop_off_included: [false], + is_guide_included: [false], + guide_languages: [''], + + PaxDetails: this.Fb.array([ + this.Fb.group({ + adult_rate: [''], + child_rate: [''], + infant_rate: [''], + senior_rate: [''], + youth_rate: [''], + }), + ]), + vahicle_list: this.Fb.array([]), + }); + this.GetLOVMater(); + this.GetAllCurrency(); + this.GetAllNationality(); + this.getRateConfig(); + this.GetPhoneCode(); + // hard code + // this.getVehicleRateDetails() + // this.getPerPaxDetails() + this.getPaxType(); + } + + // form get + get paxform() { + return this.FormData.get('PaxDetails') as FormArray; + } + get Vahicleform() { + return this.FormData.get('vahicle_list') as FormArray; + } + Months = [ + { id: 1, name: 'Jan' }, + { id: 2, name: 'Feb' }, + { id: 3, name: 'Mar' }, + { id: 4, name: 'Apr' }, + { id: 5, name: 'Jun' }, + { id: 6, name: 'Jun' }, + { id: 7, name: 'Jul' }, + { id: 8, name: 'Aug' }, + { id: 9, name: 'Sep' }, + { id: 10, name: 'Oct' }, + { id: 11, name: 'Nov' }, + { id: 12, name: 'Dec' }, + ]; + MonthsList = this.Months[0].name; + + getRateConfig() { + this.route.queryParams.subscribe((obj) => { + if (obj['id']) { + this.activityContractId = obj['id']; + this.GetSlotData(); + this.APIServ.Get( + '/ActivityContract/GetRateConfig/' + obj['id'] + ).subscribe((data) => { + if (data) { + // this.activityContract = data.responseObject; + console.log(data); + console.log(data.result.responseObject); + this.SetValueConfi(data.result.responseObject); + } + }); + } + }); + } + + SetValueConfi(d) { + let value = this.FormData.getRawValue(); + Object.keys(value).map((e) => { + if (e == 'guide_languages') { + let value = d[e] ? d[e].split(',') : null; + let Arr = []; + value.map((e) => Arr.push(parseInt(e))); + setTimeout(() => { + this.FormData.get(e).setValue(Arr); + }, 100); + } else if (e == 'is_guide_included') { + this.FormData.get(e).setValue(d[e]); + d[e] ? this.is_guideLang('guide_languages') : ''; + } else if ( + e == 'include_nationality_code' || + e == 'exclude_nationality_code' + ) { + let value = d[e] ? d[e].split(',') : null; + this.FormData.get(e).setValue(value); + } else if (e == '_nationality_type') { + this.FormData.get(e).setValue(d[e]); + d[e] == 'specific_nationality' + ? this.is_Nationality('specific_nationality') + : ''; + } else if (e == 'is_exclude_nationality') { + this.FormData.get(e).setValue(d[e]); + d[e] ? this.is_exclude(true) : ''; + } else if ( + e == 'PaxDetails' || + e == 'vahicle_list' || + e == 'Solt_data' || + e == 'Search_date' || + e == 'Days' + ) { + console.log('nice razzak '); + } else this.FormData.get(e).setValue(d[e]); + }); + } + + GetAllCurrency() { + this.APIServ.Get('/Currency/GetCurrency').subscribe((d) => { + if (d) this.currencyList = d; + }); + } + + GetAllNationality() { + this.APIServ.Get('/Country/GetCountry').subscribe((d) => { + this.include_nationality_list = d; + this.exclude_nationality_list = d; + this.fil_exclude_nationality_list = d; + }); + } + + GetLOVMater() { + let formdata = { + lov_types: [{ lov_type: 'Language' }, { lov_type: 'DaySelect' }], + lov_lang: 'EN', + }; + + this.APIServ.Post('/LovMaster/GetLov', formdata).subscribe((data) => { + if (data) { + this.LangList = data.responseObject[0].keys; + this.DaySelect = data.responseObject[1].keys; + } + }); + } + + GetSlotData() { + // this.APIServ.Get('/ActivityContract/GetSlotsById/' + this.activityContractId).subscribe(data => { + // if (data) { + // this.AllSlotData = data.responseObject; + // console.log(data) + // } + // }); + + this.APIServ.Get( + '/ActivityContract/GetSlotsById/' + '2207140719598616047' + ).subscribe((data) => { + if (data) { + this.AllSlotData = data.responseObject; + } + }); + } + + GetSoltDetails(val) { + // this.SoltDate = val.date.split(",") + this.getPerPaxDetails(); + } + + getPerPaxDetails() { + let val = this.FormData.getRawValue(); + let obj = { + contract_id: this.activityContractId, + slot_id: val.Solt_data.activity_slot_id, + dates: val.Search_date + ? moment(val.Search_date[0]).format('dd MMM YYYY') + + 'to' + + moment(val.Search_date[1]).format('dd MMM YYYY ') + : val.Solt_data.date, + days: val.Days ? val.Days.join(',') : '7', + }; + + // hard code + let new_obj = { + contract_id: '2206290724107915812', + slot_id: '2206290724110863052', + dates: '2022-05-30,2022-05-31', + days: '1,2', + }; + + this.APIServ.Post('/ActivityContract/GetRatePerPax', new_obj).subscribe( + (data) => { + if (data) { + console.log(data); + if (data.result.responseObject) { + this.PaxDetails = data.result.responseObject; + this.setpaxValue(data.result.responseObject); + } + } + } + ); + + /// GetVehicleRate + + // hard code + + // let vahicle_obj = { + // "contract_id": "2206290730562842277", + // "slot_id": "2206290730584999007", + // "dates": "2022-06-01,2022-06-02", + // "days": "0,1,2,3,4,5" + // } + + this.APIServ.Post('/ActivityContract/GetVehicleRate', obj).subscribe( + (data) => { + if (data) { + console.log(data); + if (data.result.responseObject) { + this.vahicleDetails = data.result.responseObject; + this.setvahicleValue(data.result.responseObject); + } + } + } + ); + } + + // getVehicleRateDetails() { + // let new_obj = { + // "contract_id": "2206290730562842277", + // "slot_id": "2206290730584999007", + // "dates": "2022-06-01,2022-06-02", + // "days": "0,1,2,3,4,5" + // } + // let val = this.FormData.getRawValue(); + // let obj = { + // "contract_id": this.activityContractId, + // "slot_id": val.Solt_data.activity_slot_id, + // "dates": val.Search_date ? val.Search_date.join(',') : val.Solt_data.date, + // "days": val.Days ? val.Days.join(',') : '7' + // } + // console.log(obj) + // // this.APIServ.Post('/ActivityContract/GetVehicleRate', new_obj).subscribe(data => { + // // if (data) { + // // console.log(data) + // // this.vahicleDetails = data.result.responseObject; + // // this.setvahicleValue(data.result.responseObject); + // // } + // // }); + // }; + + setpaxValue(data) { + for (let i = 0; i < data.length; i++) { + this.AddPaxGroup(); + Object.keys(data[i]).map((e) => { + this.paxform.controls[i + 1].get(e).setValue(data[i][e]); + }); + } + } + + setvahicleValue(data) { + for (let i = 0; i < data.length; i++) { + this.addvahicleGroup(); + Object.keys(data[i]).map((e) => { + this.Vahicleform.controls[i].get(e).setValue(data[i][e]); + }); + } + } + + AddPaxGroup() { + this.paxform.push( + this.Fb.group({ + date: [''], + adult_rate: [''], + child_rate: [''], + infant_rate: [''], + senior_rate: [''], + youth_rate: [''], + }) + ); + } + + addvahicleGroup() { + this.Vahicleform.push( + this.Fb.group({ + date: [''], + rate: [''], + }) + ); + } + + getPaxType() { + this.APIServ.Get( + '/Activity/GetActivity/' + CommonService.getSessionStoage('activity_id') + ).subscribe((data) => { + if (data) { + // this.AllSetvalue(data['responseObject']); + console.log(data); + } + }); + } + + // vehicle selection + + Vehicle_Selection = [ + { id: 1, name: 'Mercedes S Class' }, + { id: 2, name: 'Coach 20 Seater' }, + { id: 3, name: 'Helicopter' }, + ]; + + GetPhoneCode() { + this.APIServ.Get('/CountryPhone/GetCountryPhone').subscribe((data) => { + if (data) { + this.PhoneCode = data; + } + }); + } + + UpdateRateConfi() { + let value = this.FormData.getRawValue(); + console.log(this.FormData); + console.log(value); + let PostData = new EditActivityContractDetail(); + PostData.contract_id = this.activityContractId; + PostData.option_name = value.option_name; + PostData.currency_code = value.currency_code; + PostData.include_nationality_code = value.include_nationality_code + ? value.include_nationality_code.join(',') + : ''; + PostData.exclude_nationality_code = value.exclude_nationality_code + ? value.exclude_nationality_code.join(',') + : ''; + PostData._nationality_type = value._nationality_type; + PostData.is_exclude_nationality = value.is_exclude_nationality; + PostData.rate_inclusion = value.rate_inclusion; + PostData.contract_remark = value.contract_remark; + PostData.is_pickup_included = value.is_pickup_included; + PostData.is_drop_off_included = value.is_drop_off_included; + PostData.is_guide_included = value.is_guide_included; + PostData.guide_languages = value.guide_languages + ? value.guide_languages.join(',') + : ''; + } + + addvalid(name, type, num) { + if (type == 'add') { + if (num == 'number') { + this.FormData.controls[name].addValidators([ + Validators.pattern(/^[0-9]*$/), + ]); + this.FormData.controls[name].updateValueAndValidity(); + } else { + this.FormData.controls[name].addValidators([Validators.required]); + this.FormData.controls[name].updateValueAndValidity(); + } + } else { + this.FormData.controls[name].clearValidators(); + this.FormData.controls[name].updateValueAndValidity(); + this.FormData.controls[name].markAsUntouched(); + } + } + is_exclude(check) { + check + ? this.addvalid('exclude_nationality_code', 'add', 'required') + : this.addvalid('exclude_nationality_code', 'remove', ''); + } + + is_Nationality(val) { + val == 'specific_nationality' + ? this.addvalid('include_nationality_code', 'add', 'required') + : this.addvalid('include_nationality_code', 'remove', 'required'); + } + + is_guideLang(check) { + check + ? this.addvalid('guide_languages', 'add', 'required') + : this.addvalid('guide_languages', 'remove', ''); + } + + SetVahicleValCopyUi() { + let value = this.Vehicle_Rate_copy.nativeElement.value; + if (value != '') { + let obj = this.Vahicleform.getRawValue(); + obj.map((e) => { + Object.keys(e).forEach((ol, i) => { + this.Vahicleform.controls[i].get('rate').setValue(value); + }); + }); + } + } + + checkcleander() { + let value = this.FormData.getRawValue(); + if (value.Search_date[0] && value.Search_date[1]) { + this.datePicker.overlayVisible = false; + this.getPerPaxDetails(); + } + } + + setpaxValueFromUi() { + let val = this.paxform.getRawValue(); + if (val[0].adult_rate != '') { + this.setValueFormUi('adult_rate'); + } + if (val[0].senior_rate != '') { + this.setValueFormUi('senior_rate'); + } + if (val[0].youth_rate != '') { + this.setValueFormUi('youth_rate'); + } + if (val[0].child_rate != '') { + this.setValueFormUi('child_rate'); + } + if (val[0].infant_rate != '') { + this.setValueFormUi('infant_rate'); + } + } + + setValueFormUi(name) { + let obj = this.paxform.getRawValue(); + for (let i = 1; i < obj.length; i++) { + Object.keys(obj[i]).map((e) => { + if (e == name) { + this.paxform.controls[i].get(e).setValue(obj[0][name]); + } + }); + } + } + + Pax_Type = [ + { id: 0, name: 'Adult' }, + { id: 1, name: 'Senior' }, + { id: 2, name: 'Youth' }, + { id: 3, name: 'Child' }, + { id: 4, name: 'Infant' }, + ]; +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.html new file mode 100644 index 0000000..2a17dd7 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.html @@ -0,0 +1,398 @@ +
    + + Back +
    +
    +
    Edit Rate Config
    +
    +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + + + Please select + supplier + +
    +
    + + + + + Please select + vehicle selection +
    +
    + + + Please select + private transfer occupancy +
    +
    + + + Please select + supplier + Accept number only +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + + Please select + supplier +
    +
    +
    + + +
    +
    + + + Please enter + adult + accept number only + +
    +
    + + + Please enter + senior + accept number only + +
    +
    + + + Please enter + youth + accept number only + +
    +
    + + + Please enter + child + accept number only + +
    +
    +
    +
    +
    +
    +
    + + + {{ item.start_time | date: "h:mm" }} to {{ item.end_time | date: "h:mm" }} + +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + + {{ activity_obj.activitySeason.season_name}} + +
    +
    + + + +
    +
    + + +
    +
    +
    + +
    + + +
    +
    Per Person Pricing
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    +
    Date
    +
    +
    Days
    +
    +
    + Adult Rate + +
    +
    +
    + Senior Rate + +
    +
    +
    + Youth Rate + +
    +
    +
    + Child Rate + +
    +
    {{ item.date | date: "dd MMM YYYY" }}{{ item.date | date: "EEEE" }} + + + + + + + +
    +
    + +
    +
    +
    + + +
    +
    Per Vehicle Pricing
    +
    + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    Date
    +
    +
    Days
    +
    +
    + +
    +
    {{ item.date | date: "dd MMM YYYY" }}{{ item.date | date: "EEEE" }} +
    + +
    +
    +
    + +
    +
    +
    + + + +
    Tiered Pricing
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    +
    Date
    +
    +
    Days
    +
    +
    + Adult + ({{controls.from_adult_count}} to + {{controls.to_adult_count}}) + + +
    +
    +
    + Senior + ({{controls.from_senior_count}} to + {{controls.to_senior_count}}) + + +
    +
    +
    + Youth + ({{controls.from_youth_count}} to + {{controls.to_youth_count}}) + + +
    +
    +
    + Child + ({{controls.from_child_count}} to + {{controls.to_child_count}}) + + +
    +
    {{ group.date | date: "dd MMM YYYY" }}{{ group.date | date: "EEEE" }} + + + + + + + +
    +
    + +
    +
    +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.ts new file mode 100644 index 0000000..5531f27 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/edit-modify-rate/edit-modify-rate.component.ts @@ -0,0 +1,861 @@ +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { EditActivityContractRate, GetRateDetails, PaxPricing, PaxRates, TieredPricingList, VehicleRates } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model'; +import { ActivityPrivateTransfer, ActivitySharedTransfer } from 'src/app/core/models/Experience-Service/experience-rate-config/experience-rate-config.model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; + +@Component({ + selector: 'app-edit-modify-rate', + templateUrl: './edit-modify-rate.component.html', +}) +export class EditModifyRateComponent implements OnInit { + constructor( + private route: ActivatedRoute, + public Fb: FormBuilder, + public ApiServ: API, + public validationService: ValidationService, + public MsgService: MessageService, + private router: Router, + ) { } + Pickup: string[] = []; + CommonCalender: string[] = []; + // + FormData: FormGroup; + currencyList; + activityContractId; + PaxDetails; + vahicleDetails; + activityData; + AllSlots; + AllVehicleBySupplierId = { + Shared: [], + Slots: [] + };; + lovKeyDataObj = { + RatePeriodType: [], + DaySelect: [], + RateConfigType: [], + ActivityNoShowPolicyType: [], + ActivityCancellationPolicyType: [], + ActivityCancellationChargeType: [], + }; + season_list; + AllVehicleSupplier; + AllContractTieredRate; + HeaderTieredRateGroup = { + adult_range: [], + youth_range: [], + senior_range: [], + child_range: [], + } + TieredRatedynamicgroup: FormGroup; + + + ngOnInit(): void { + this.ngOninitform(); + this.GetAllCurrency(); + this.GetAllVehicleSupplier(); + this.GetLOVKeys('RatePeriodType,DaySelect,ActivityNoShowPolicyType,RateConfigType,ActivityCancellationPolicyType,ActivityCancellationChargeType'); + this.GetAllActivitySeason(); + } + + /** + * @author Abdul Razzak + * to create a form group + */ + ngOninitform() { + this.FormData = this.Fb.group({ + activity_name: [''], + option_name: [''], + currency_code: [''], + searchgroup: this.Fb.group({ + slot_id: [''], + _rate_type: [''], + period_type: [''], + dates: [''], + seasonId: [[]], + days: [''], + }) + }); + } + + /** + * @author Abdul Razzak + * to get form controller + */ + + get privateTransfer() { + return this.FormData.get('privateTransfer') as FormArray; + } + + get sharedTransfer() { + return this.FormData.get('sharedTransfer') as FormGroup; + } + + get paxformGroup() { + return this.FormData.get('PaxDetails') as FormArray; + } + get tieredPricingsGroup() { + return this.FormData.get('tieredPricings') as FormArray; + } + + get VahicleformGroup() { + return this.FormData.get('vahicle_list') as FormArray; + } + + + /** + * @author Abdul Razzak + * to get activity details + */ + GetActivityById() { + let activity_id = CommonService.getSessionStoage('activity_id'); + this.ApiServ.Get('/Activity/GetActivity/' + activity_id).subscribe(res => { + if (res) { + this.activityData = res.responseObject; + this.FormData.get('activity_name').setValue(res.responseObject.activityContents[0].activity_name); + this.getRateConfig(); + } + }) + } + + /** + * @author Abdul razzak + * to get contract details + */ + getRateConfig() { + this.route.queryParams.subscribe((obj) => { + if (obj['id']) { + this.activityContractId = obj['id']; + this.GetSlotsById(obj['id']) + this.ApiServ.Get('/ActivityContract/GetRateConfig/' + obj['id']).subscribe((res) => { + if (res) { + this.FormData.get('option_name').setValue(res.responseObject.option_name); + this.FormData.get('currency_code').setValue(res.responseObject.currency_code); + let val = parseInt(res.responseObject._rate_type) + this.FormData.get('searchgroup').get('_rate_type').setValue(val); + if (val == 2) { + this.FormData.addControl('PaxDetails', this.Fb.array([ + this.Fb.group({ + activity_rate_per_pax_id: [''], + date: [''], + }) + ])) + this.AddPaxController(this.paxformGroup.controls[0], false); + } else if (val == 3) { + this.FormData.addControl('vahicle_list', this.Fb.array([ + this.Fb.group({ + date: [''], + vehicle_rates: this.Fb.array([ + this.Fb.group({ + activity_rate_per_vehicle_id: [''], + rate: [''], + vehicle_id: [''], + vehicle_name: [''], + }) + ]) + }) + ])) + } else if (val == 1) { + this.ApiServ.Get('/ActivityContract/GetTieredRateTableView/' + this.activityContractId).subscribe(res => { + if (res) { + this.FormData.addControl('tieredPricings', this.Fb.array([ + ])) + res.responseObject.forEach((e, i) => { + this.tieredPricingsGroup.push(this.Fb.group({ + date: [''], + activity_rate_tiered_id: [''], + })) + let controls = this.tieredPricingsGroup.controls[0] as FormGroup + if (e.adult_range) { + let adult_range = JSON.parse(e.adult_range); + this.HeaderTieredRateGroup.adult_range = adult_range; + adult_range.forEach((r, i) => { + controls.addControl('adult_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (e.youth_range) { + let youth_range = JSON.parse(e.youth_range); + this.HeaderTieredRateGroup.youth_range = youth_range; + youth_range.forEach((r, i) => { + controls.addControl('youth_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (e.senior_range) { + let senior_range = JSON.parse(e.senior_range); + this.HeaderTieredRateGroup.senior_range = senior_range; + senior_range.forEach((r, i) => { + controls.addControl('senior_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (e.child_range) { + let child_range = JSON.parse(e.child_range); + this.HeaderTieredRateGroup.child_range = child_range; + child_range.forEach((r, i) => { + controls.addControl('child_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + }) + } + }); + } + if (res.responseObject.is_shared_transfer) this.AddSharedTransferControls(true, res.responseObject.shared_transfer); + if (res.responseObject.is_private_transfer) this.AddPrivateTransferControls(true, res.responseObject.private_transfer); + } + }); + } + }); + } + + + /** + * @author Abdul Razzak + * to get slot data by contract id + * @param Id + */ + GetSlotsById(Id) { + this.ApiServ.Get('/ActivityContract/GetSlotsById/' + Id).subscribe(res => { + if (res) { + this.AllSlots = res.responseObject; + } + }) + } + + /** + * @author Abdul Razzak + * to create Tiered Pricings FormGroup + * @param ind + */ + createTieredGroup(ind) { + this.tieredPricingsGroup.push(this.Fb.group({ + date: [''], + activity_rate_tiered_id: [''], + })) + let controls = this.tieredPricingsGroup.controls[ind] as FormGroup + if (this.HeaderTieredRateGroup.adult_range) { + this.HeaderTieredRateGroup.adult_range.forEach((r, i) => { + controls.addControl('adult_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (this.HeaderTieredRateGroup.youth_range) { + this.HeaderTieredRateGroup.youth_range.forEach((r, i) => { + controls.addControl('youth_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (this.HeaderTieredRateGroup.senior_range) { + this.HeaderTieredRateGroup.senior_range.forEach((r, i) => { + controls.addControl('senior_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + if (this.HeaderTieredRateGroup.child_range) { + this.HeaderTieredRateGroup.child_range.forEach((r, i) => { + controls.addControl('child_rate_range_' + (i + 1), this.Fb.control('')); + }) + } + } + + + + /** + * @author Abdul Razzak + * To Get All Activity Season + */ + GetAllActivitySeason() { + this.ApiServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + CommonService.getSessionStoage('activity_id')).subscribe(d => { + if (d && d.status) { + this.season_list = d.responseObject; + } + }); + } + + + /** + * @author Abdul Razzak + * To Get All Vehicle Supplier + */ + GetAllVehicleSupplier() { + this.ApiServ.Get('/Vehicle/GetAllVehicleSupplier').subscribe((res) => { + if (res) { + this.AllVehicleSupplier = res.responseObject; + } + }); + } + + /** + * @author Abdul Razzak + * To get all curency + */ + GetAllCurrency() { + this.ApiServ.Get('/Currency/GetCurrency').subscribe((d) => { + if (d) this.currencyList = d; + }); + } + + + /** + * @author Abdul Razzak + * TO get Get All Vehicle details by supplier Id + * @param Id + * @param name + * @param i + */ + GetAllVehicleBySupplierId(Id, name, i) { + this.ApiServ.Get('/Vehicle/GetAllVehicleBySupplier/' + Id).subscribe((res) => { + if (res) { + this.AllVehicleBySupplierId[name][i] = [] + this.AllVehicleBySupplierId[name][i] = res.responseObject; + } + }); + } + + + /** + * @author Abdul Razzak + * to get data from LOV + * @param lov_key_names + */ + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + } + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + this.GetActivityById(); + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + } + + + /** + * @author Abdul Razzak + * to get Per Pax Details , Vehicle Rate and Tiered Rate + */ + Search() { + let val = this.FormData.get('searchgroup').get('_rate_type').value; + let searchform = this.FormData.get('searchgroup').value; + let postdata = new GetRateDetails(); + postdata.contract_id = this.activityContractId; + postdata.slot_id = searchform.slot_id; + postdata.from_date = searchform.dates[0] ? moment(searchform.dates[0]).format('YYYY-MM-DD') : ''; + postdata.to_date = searchform.dates[1] ? moment(searchform.dates[1]).format('YYYY-MM-DD') : ''; + postdata.seasonId = searchform.seasonId; + postdata.days = searchform.days ? searchform.days.join(',') : ''; + if (val == 2) { + this.getPerPaxDetails(postdata); + } else if (val == 3) { + this.GetVehicleRate(postdata); + } else if (val == 1) { + this.GetActivityTieredRate(postdata); + } + } + + // private Transfer -------------------------------------------------------------------- + + /** + * @author Abdul Razzak + * to create private Transfer form array + * @param check + * @param Data + */ + AddPrivateTransferControls(check, Data) { + if (check) { + this.FormData.addControl('privateTransfer', this.Fb.array([ + ])) + let Obj = JSON.parse(Data) + Obj.forEach((e, i) => { + this.AddPrivateTransferGroup(e, i); + }); + } + } + + /** + * @author Abdul Razzak + * to create pax controls on form group + * @param Data + * @param ind + */ + AddPrivateTransferGroup(Data, ind) { + Data ? this.GetAllVehicleBySupplierId(Data.vehicle_supplier_id, 'Shared', ind) : '' + this.privateTransfer.push(this.Fb.group({ + // activity_pvt_transfer_add_on_id: [Data.activity_pvt_transfer_add_on_id], + vehicle_supplier_id: [Data ? Data.vehicle_supplier_id : '', Validators.required], + vehicle_id: [Data ? Data.vehicle_id : '', Validators.required], + vehicle_occupancy: [Data ? Data.vehicle_occupancy : '', Validators.required], + rate: [Data ? Data.rate : '', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)]], + })) + } + + /** + * @author Abdul Razzak + * to remove form group on privete transfer + * @param ind + */ + RemovePrivateformGroup(ind) { + this.privateTransfer.removeAt(ind); + } + + /** + * @author Abdul Razzak + * to clear formcontrols value when period type change + */ + ClearDateAndSeason() { + let val = this.FormData.get('searchgroup').get('period_type').value; + if (val == 2) this.FormData.get('searchgroup').get('dates').setValue(''); + else if (val == 1) this.FormData.get('searchgroup').get('seasonId').setValue([]); + } + + // shared transfer -------------------------------------------------------------------- + + /** + * @author Abdul Razzak + * to add contols on shared transfer + * @param check + */ + AddSharedTransferControls(check, data) { + if (check) { + this.FormData.addControl('sharedTransfer', this.Fb.group({})) + let obj = JSON.parse(data) + this.sharedTransfer.addControl('vehicle_supplier_id', this.Fb.control(obj[0].vehicle_supplier_id, [Validators.required])); + this.sharedTransfer.addControl('activity_shared_transfer_add_on_id', this.Fb.control(obj[0].activity_shared_transfer_add_on_id, [Validators.required])); + if (this.activityData.is_adult) this.sharedTransfer.addControl('adult_rate', this.Fb.control(obj[0].adult_rate, [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_senior) this.sharedTransfer.addControl('senior_rate', this.Fb.control(obj[0].senior_rate, [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_youth) this.sharedTransfer.addControl('youth_rate', this.Fb.control(obj[0].youth_rate, [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_child) this.sharedTransfer.addControl('child_rate', this.Fb.control(obj[0].child_rate, [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + // else { + // this.sharedTransfer.removeControl('vehicle_supplier_id'); + // this.sharedTransfer.removeControl('activity_shared_transfer_add_on_id'); + // if (this.activityData.is_adult) this.sharedTransfer.removeControl('adult_rate'); + // if (this.activityData.is_senior) this.sharedTransfer.removeControl('senior_rate'); + // if (this.activityData.is_youth) this.sharedTransfer.removeControl('youth_rate'); + // if (this.activityData.is_child) this.sharedTransfer.removeControl('child_rate'); + // } + } + + // per pax details -------------------------------------------------------------------- + + /** + * @author Abdul Razzak + * to get contract pax details + * @param postdata + */ + getPerPaxDetails(postdata) { + this.ApiServ.Post('/ActivityContract/GetRatePerPax', postdata).subscribe((data) => { + if (data) { + this.PaxDetails = data.responseObject; + data.responseObject ? this.setpaxValue(data.responseObject) : ''; + } + }); + } + + /** + * @author Abdul Razzak + * to create form group and set value + * @param data + */ + setpaxValue(data) { + this.paxformGroup.clear(); + this.paxformGroup.push(this.Fb.group({ + activity_rate_per_pax_id: [''], + date: [''], + })) + this.AddPaxController(this.paxformGroup.controls[0], false); + data.forEach((e, i) => { + this.paxformGroup.push( + this.Fb.group({ + activity_rate_per_pax_id: [e['activity_rate_per_pax_id']], + date: [e['date']], + }) + ); + this.AddPaxController(this.paxformGroup.controls[i + 1], data[i]); + }); + } + + /** + * @author Abdul Razzak + * to create pax control + * @param group + * @param value + */ + AddPaxController(group, value) { + if (this.activityData.is_adult) group.addControl('adult_rate', this.Fb.control(value ? value.adult_rate : '', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_senior) group.addControl('senior_rate', this.Fb.control(value ? value.senior_rate : '', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_youth) group.addControl('youth_rate', this.Fb.control(value ? value.youth_rate : '', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + if (this.activityData.is_child) group.addControl('child_rate', this.Fb.control(value ? value.child_rate : '', [Validators.required, Validators.pattern(/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/)])); + } + + /** + * @author Abdul Razzak + * to set all pax rate value form copy on UI button + */ + setallpaxdetails() { + let val = this.paxformGroup.getRawValue(); + if (val[0].adult_rate != '') { + this.setValueFormUi('adult_rate'); + } + if (val[0].senior_rate != '') { + this.setValueFormUi('senior_rate'); + } + if (val[0].youth_rate != '') { + this.setValueFormUi('youth_rate'); + } + if (val[0].child_rate != '') { + this.setValueFormUi('child_rate'); + } + } + + setValueFormUi(name) { + let obj = this.paxformGroup.getRawValue(); + for (let i = 1; i < obj.length; i++) { + Object.keys(obj[i]).map((e) => { + if (e == name) { + this.paxformGroup.controls[i].get(e).setValue(obj[0][name]); + } + }); + } + } + + // Vehicle Rate -------------------------------------------------------------------- + + /** + * @author Abdul Razzak + * to get contract vehicle details + * @param postdata + */ + GetVehicleRate(postdata) { + this.ApiServ.Post('/ActivityContract/GetVehicleRate', postdata).subscribe( + (data) => { + if (data) { + console.log(data); + if (data.responseObject) { + this.vahicleDetails = data.responseObject; + data.responseObject ? this.setvahicleValue(data.responseObject) : ''; + } + } + } + ); + } + + /** + * @author Abdul Razzak + * to creta form group and set value on vehicle rate group + */ + setvahicleValue(data) { + this.VahicleformGroup.clear(); + this.VahicleformGroup.push( + this.Fb.group({ + date: [''], + vehicle_rates: this.Fb.array([]) + }) + ) + this.CreateFormGroup(data[0], this.VahicleformGroup.controls[0].get('vehicle_rates'), false); + data.forEach((value, i) => { + this.VahicleformGroup.push( + this.Fb.group({ + date: [value['date']], + vehicle_rates: this.Fb.array([]) + }) + ); + let VehicleRatesGroup = this.VahicleformGroup.controls[i + 1].get('vehicle_rates') as FormArray; + this.CreateFormGroup(value, VehicleRatesGroup, true); + }); + } + + CreateFormGroup(value, VehicleRatesGroup, check) { + value.vehicle_rates.forEach((e) => { + VehicleRatesGroup.push(this.Fb.group({ + activity_rate_per_vehicle_id: [check ? e.activity_rate_per_vehicle_id : ''], + rate: [check ? e.rate : ''], + vehicle_id: [check ? e.vehicle_id : ''], + vehicle_name: [check ? e.vehicle_name : ''], + })) + }) + } + + /** + * @author Abdul Razzak + * to set all vehicle rate price + */ + CopyOnUIvehicle() { + let val = this.VahicleformGroup.controls[0].get('vehicle_rates').value; + if (this.VahicleformGroup.controls.length > 1) { + let obj = this.VahicleformGroup.getRawValue(); + obj.forEach((e, i) => { + val.forEach((d, li) => { + this.VahicleformGroup.controls[i].get('vehicle_rates')['controls'][li].get('rate').setValue(d.rate) + }); + }); + }; + }; + + + // Tiered Rate -------------------------------------------------------------------- + + /** + * @author Abdul Razzak + * to get all Tiered Rate details + * @param PostData + */ + GetActivityTieredRate(PostData) { + this.ApiServ.Post('/ActivityContract/GetActivityTieredRate', PostData).subscribe((res) => { + if (res) { + this.AllContractTieredRate = res.responseObject; + this.tieredPricingsGroup.clear(); + this.createTieredGroup(0) + this.AllContractTieredRate.forEach((e, i) => { + let ind = i + 1; + this.createTieredGroup(ind) + let val = this.tieredPricingsGroup.controls[ind].value; + Object.keys(val).forEach((l) => { + this.tieredPricingsGroup.controls[ind].get(l).setValue(e[l]); + }); + }) + } + }) + } + + + /** + * @author Abdul Razzak + * to set all Tiered Rate value + */ + SetTieredRateValCopyUi() { + let val = this.tieredPricingsGroup.controls[0].value; + if (this.tieredPricingsGroup.controls.length > 1) { + let obj = this.tieredPricingsGroup.getRawValue(); + obj.forEach((e, i) => { + if (this.HeaderTieredRateGroup.adult_range) { + this.HeaderTieredRateGroup.adult_range.forEach((d, li) => { + let name = 'adult_rate_range_' + (li + 1) + this.tieredPricingsGroup.controls[i].get(name).setValue(val[name]); + }) + } + if (this.HeaderTieredRateGroup.senior_range) { + this.HeaderTieredRateGroup.senior_range.forEach((d, li) => { + let name = 'senior_rate_range_' + (li + 1) + this.tieredPricingsGroup.controls[i].get(name).setValue(val[name]); + }) + } + if (this.HeaderTieredRateGroup.youth_range) { + this.HeaderTieredRateGroup.youth_range.forEach((d, li) => { + let name = 'youth_rate_range_' + (li + 1) + this.tieredPricingsGroup.controls[i].get(name).setValue(val[name]); + }) + } + if (this.HeaderTieredRateGroup.child_range) { + this.HeaderTieredRateGroup.child_range.forEach((d, li) => { + let name = 'child_rate_range_' + (li + 1) + this.tieredPricingsGroup.controls[i].get(name).setValue(val[name]); + }) + } + }); + }; + } + + + + + UpdateRate() { + let val = this.FormData.getRawValue() + let postdata = new EditActivityContractRate(); + postdata.activity_contract_id = this.activityContractId; + postdata.activity_slot_id = ''; + + // private Transfer + let privateTransferArr = [] + if (val.privateTransfer) { + val.privateTransfer.forEach((e) => { + let PostPrivateTransfer = new ActivityPrivateTransfer(); + PostPrivateTransfer.rate = e.rate; + PostPrivateTransfer.vehicle_id = e.vehicle_id; + PostPrivateTransfer.vehicle_occupancy = e.vehicle_occupancy; + PostPrivateTransfer.vehicle_supplier_id = e.vehicle_supplier_id; + privateTransferArr.push(PostPrivateTransfer) + }) + } + postdata.privateTransfer = val.privateTransfer ? privateTransferArr : []; + + // shared Transfer + let PostSharedTransfer = new ActivitySharedTransfer(); + if (val.sharedTransfer) { + let value = val.sharedTransfer + PostSharedTransfer.vehicle_supplier_id = value.vehicle_supplier_id; + PostSharedTransfer.adult_rate = value.adult_rate; + PostSharedTransfer.child_rate = value.child_rate; + PostSharedTransfer.senior_rate = value.senior_rate; + PostSharedTransfer.youth_rate = value.youth_rate; + } + postdata.sharedTransfer = val.sharedTransfer ? PostSharedTransfer : null; + + // per pax prices + let PaxDetailsArr = [] + if (val.PaxDetails) { + val.PaxDetails.splice(0, 1); + val.PaxDetails.forEach((e) => { + let postpaxrate = new PaxRates(); + postpaxrate.activity_rate_per_pax_id = e.activity_rate_per_pax_id; + postpaxrate.adult_rate = e.adult_rate ? e.adult_rate : 0; + postpaxrate.child_rate = e.child_rate ? e.child_rate : 0; + postpaxrate.senior_rate = e.senior_rate ? e.senior_rate : 0; + postpaxrate.youth_rate = e.youth_rate ? e.youth_rate : 0; + PaxDetailsArr.push(postpaxrate) + }); + } + postdata.perPaxPrices = val.PaxDetails ? PaxDetailsArr : []; + + // per Vehicle Rates + let VahiclelistArr = [] + if (val.vahicle_list) { + val.vahicle_list.splice(0, 1); + val.vahicle_list.forEach((q) => { + q.vehicle_rates.forEach((e) => { + let PostVahiclelist = new VehicleRates(); + PostVahiclelist.activity_rate_per_vehicle_id = e.activity_rate_per_vehicle_id; + PostVahiclelist.rate = e.rate; + PostVahiclelist.vehicle_id = e.vehicle_id; + PostVahiclelist.vehicle_max_occupancy = e.vehicle_max_occupancy; + PostVahiclelist.vehicle_supplier_id = e.vehicle_supplier_id; + VahiclelistArr.push(PostVahiclelist) + }) + }) + } + postdata.perVehicleRates = val.vahicle_list ? VahiclelistArr : []; + + // tiered Pricings + let PostTieredPricings = []; + if (val.tieredPricings) { + if (val.tieredPricings.length > 1) { + val.tieredPricings.splice(0, 1); + val.tieredPricings.forEach(e => { + let postList = new TieredPricingList(); + postList.id = e.activity_rate_tiered_id; + let pricingArr = [] + if (this.HeaderTieredRateGroup.adult_range) { + this.HeaderTieredRateGroup.adult_range.forEach((r, i) => { + let post = new PaxPricing(); + post.rate = e['adult_rate_range_' + (i + 1)]; + post.sequence = (i + 1); + post.pax_type = 'adult'; + pricingArr.push(post); + }) + } + if (this.HeaderTieredRateGroup.youth_range) { + this.HeaderTieredRateGroup.youth_range.forEach((r, i) => { + let post = new PaxPricing(); + post.rate = e['youth_rate_range_' + (i + 1)]; + post.sequence = (i + 1); + post.pax_type = 'youth'; + pricingArr.push(post); + }) + } + if (this.HeaderTieredRateGroup.senior_range) { + this.HeaderTieredRateGroup.senior_range.forEach((r, i) => { + let post = new PaxPricing(); + post.rate = e['senior_rate_range_' + (i + 1)]; + post.sequence = (i + 1); + post.pax_type = 'senior'; + pricingArr.push(post); + }) + } + if (this.HeaderTieredRateGroup.child_range) { + this.HeaderTieredRateGroup.child_range.forEach((r, i) => { + let post = new PaxPricing(); + post.rate = e['child_rate_range_' + (i + 1)]; + post.sequence = (i + 1); + post.pax_type = 'child'; + pricingArr.push(post); + }) + } + postList.pricing = pricingArr; + PostTieredPricings.push(postList) + }) + } + postdata.tieredPricings = val.tieredPricings.length > 1 ? PostTieredPricings : []; + } + this.ApiServ.Post('/ActivityContract/UpdateRateConfig', postdata).subscribe((res) => { + if (res) { + this.showToastrMsg(res) + } + }) + } + + /** + * @author Abdul Razzak + * to show toaster + * @param respData + */ + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + + /** + * @author Abdul razzak + * to navigate overview tab + */ + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']) + } + + /** + * @author Abdul Razzak + * to reset search value + */ + reset() { + this.FormData.get('searchgroup').get('slot_id').setValue(''); + this.FormData.get('searchgroup').get('period_type').setValue(''); + this.FormData.get('searchgroup').get('dates').setValue(''); + this.FormData.get('searchgroup').get('seasonId').setValue([]); + this.FormData.get('searchgroup').get('days').setValue(''); + } + + + // ---------------------------------------------------------------------------------------- + + // addvalid(name, type, num) { + // if (type == 'add') { + // if (num == 'number') { + // this.FormData.controls[name].addValidators([ + // Validators.pattern(/^[0-9]*$/), + // ]); + // this.FormData.controls[name].updateValueAndValidity(); + // } else { + // this.FormData.controls[name].addValidators([Validators.required]); + // this.FormData.controls[name].updateValueAndValidity(); + // } + // } else { + // this.FormData.controls[name].clearValidators(); + // this.FormData.controls[name].updateValueAndValidity(); + // this.FormData.controls[name].markAsUntouched(); + // } + // } + // ---------------------------------------------------------------------------------------------- + // for calender + + // checkcleander() { + // let value = this.FormData.getRawValue(); + // if (value.Search_date[0] && value.Search_date[1]) { + // this.datePicker.overlayVisible = false; + // } + // } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.html new file mode 100644 index 0000000..c289aa6 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.html @@ -0,0 +1,139 @@ +
    + + Back +
    +
    Edit Modify Details
    +
    +
    +
    + + +
    +
    + + +
    +
    + + + Please enter option name +
    +
    +
    +

    Applicable Nationality

    +
    + +
    +
    + All Nationality +
    +
    + Specific Nationality +
    +
    +
    + + + + Please select nationality +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Exclude + Nationality +
    +
    +
    +
    + + + + Please select nationality +
    +
    +
    +
    +
    +
    +
    + Pickup Included + +
    +
    + Drop Off Included + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + Tourist Guide + Included +
    + + + + Please enter + tourist guide language +
    +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.ts new file mode 100644 index 0000000..bffd669 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/modify-details/modify-details.component.ts @@ -0,0 +1,228 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { EditActivityContractDetail } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-details/edit-deatils.model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; + +@Component({ + selector: 'app-modify-details', + templateUrl: './modify-details.component.html', +}) +export class ModifyDetailsComponent implements OnInit { + + FormData: FormGroup + activityData; + currencyList; + activityContractId; + include_nationality_list; + exclude_nationality_list; + all_nationality_list; + constructor( + private route: ActivatedRoute, + public fb: FormBuilder, + public APIServ: API, + public validationService: ValidationService, + public MsgService: MessageService, + private router: Router + ) { } + + + ngOnInit(): void { + this.OnintGroup() + this.GetActivityById(); + this.GetAllCurrency(); + this.GetAllNationality(); + this.GetLOVKeys('Language') + this.getRateConfig(); + } + lovKeyDataObj = { + Language: [] + } + + OnintGroup() { + this.FormData = this.fb.group({ + experience_name: [''], + option_name: this.validationService.required, + currency_code: [''], + _nationality_type: ['1'], + is_exclude_nationality: [false], + rate_inclusion: [''], + contract_remark: [''], + is_pickup_included: [false], + is_drop_off_included: [false], + is_guide_included: [false], + }); + } + + GetActivityById() { + let activity_id = CommonService.getSessionStoage('activity_id'); + this.APIServ.Get('/Activity/GetActivity/' + activity_id).subscribe(d => { + if (d && d.status) { + if (d.responseObject.activityContents && d.responseObject.activityContents.length > 0) { + this.activityData = d.responseObject; + this.FormData.get('experience_name').setValue(d.responseObject.activityContents[0].activity_name); + + } + } + }); + } + + getRateConfig() { + this.route.queryParams.subscribe((obj) => { + if (obj['id']) { + this.activityContractId = obj['id']; + this.APIServ.Get( + '/ActivityContract/GetRateConfig/' + obj['id'] + ).subscribe((data) => { + if (data) { + this.SetValue(data.responseObject); + } + }); + } + }); + } + + SetValue(data) { + let value = this.FormData.getRawValue(); + Object.keys(value).forEach(e => { + if (e == 'option_name' || e == 'currency_code' || e == 'rate_inclusion' || e == 'contract_remark' || + e == 'is_drop_off_included' || e == 'is_pickup_included') { + this.FormData.get(e).setValue(data[e]); + } else if (e == '_nationality_type') { + this.FormData.get(e).setValue(data[e]); + if (data[e] == '2') { + this.isIncludeNationality(data[e]); + let code = data['include_nationality_code'] ? data['include_nationality_code'].split(',') : []; + this.FormData.get('include_nationality_code').setValue(code); + this.remove_nationality('exclude'); + } + } else if (e == 'is_exclude_nationality') { + this.FormData.get(e).setValue(data[e]); + if (data[e]) { + this.isExcludeNationality(data[e]); + let code = data['exclude_nationality_code'] ? data['exclude_nationality_code'].split(',') : []; + this.FormData.get('exclude_nationality_code').setValue(code); + this.remove_nationality('include'); + } + } else if (e == 'is_guide_included') { + this.FormData.get(e).setValue(data[e]); + if (data[e]) { + this.AddLangContorls(data[e]) + let Lngcode = data['guide_languages'] ? data['guide_languages'].split(',') : ''; + this.FormData.get('guide_languages').setValue(Lngcode); + } + } + }); + } + AddLangContorls(check) { + if (check) { + this.FormData.addControl('guide_languages', this.fb.control([], Validators.required)); + } else { + this.FormData.removeControl('guide_languages'); + } + } + GetAllCurrency() { + this.APIServ.Get('/Currency/GetCurrency').subscribe(d => { + if (d) this.currencyList = d; + }); + } + + + isExcludeNationality(check) { + if (check) { + this.FormData.addControl('exclude_nationality_code', this.fb.control([[]], Validators.required)); + this.remove_nationality('include'); + } else this.FormData.removeControl('exclude_nationality_code'); + } + + isIncludeNationality(val) { + if (val == '2') { + this.FormData.addControl('include_nationality_code', this.fb.control([], Validators.required)); + this.FormData.get('include_nationality_code').setValue([]); + } else if (val == '1') { + this.FormData.removeControl('include_nationality_code'); + this.remove_nationality('exclude'); + } + } + + remove_nationality(type) { + let con = type == 'exclude' ? 'include_nationality_code' : 'exclude_nationality_code' + type == 'exclude' ? this.exclude_nationality_list = [...this.all_nationality_list] : this.include_nationality_list = [...this.all_nationality_list]; + let list = type == 'exclude' ? this.exclude_nationality_list : this.include_nationality_list; + let nationality_arr = this.FormData.get(con) ? this.FormData.get(con).value : []; + nationality_arr.forEach(nationality_code => { + let ind = list.findIndex(nationality_obj => nationality_obj.alpha_2_code == nationality_code); + (ind != -1) ? list.splice(ind, 1) : ''; + type == 'exclude' ? this.exclude_nationality_list = [...list] : this.include_nationality_list = [...list]; + }); + } + + GetAllNationality() { + this.APIServ.Get('/Country/GetCountry').subscribe(res => { + if (res) { + this.all_nationality_list = res; + this.include_nationality_list = res; + this.exclude_nationality_list = res; + } + }); + } + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + } + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.APIServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + this.GetActivityById(); + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + } + updateEditdetails() { + let postdata = new EditActivityContractDetail(); + let value = this.FormData.getRawValue(); + postdata.contract_id = this.activityContractId; + postdata.language_code = CommonService.getSessionStoage('Def_Lang_code'); + postdata.option_name = value.option_name; + postdata.currency_code = value.currency_code; + postdata._nationality_type = value._nationality_type; + postdata.is_exclude_nationality = value.is_exclude_nationality; + postdata.rate_inclusion = value.rate_inclusion; + postdata.contract_remark = value.contract_remark; + postdata.is_pickup_included = value.is_pickup_included; + postdata.is_drop_off_included = value.is_drop_off_included; + postdata.is_guide_included = value.is_guide_included; + postdata.exclude_nationality_code = value.exclude_nationality_code ? value.exclude_nationality_code.join(',') : ''; + postdata.include_nationality_code = value.include_nationality_code ? value.include_nationality_code.join(',') : ''; + postdata.guide_languages = value.guide_languages ? value.guide_languages.join(',') : ''; + this.APIServ.Post('/ActivityContract/UpdateContractDetails', postdata).subscribe(res => { + if (res) { + this.showToastrMsg(res) + } + }) + + + } + showToastrMsg(respData) { + this.MsgService.add({ + severity: respData['status'] ? 'success' : 'error', + detail: respData['message'], + }); + setTimeout(() => { + respData['status'] ? this.btnClick() : ''; + }, 500); + } + btnClick() { + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']) + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.html new file mode 100644 index 0000000..12b145f --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.html @@ -0,0 +1,178 @@ +
    +
    Rate Config
    + +
    +
    +
    +
    + + +
    +
    + +
    Pickup Included
    +
    +
    +
    + +
    Drop Off Included
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Option Name + + + + Nationality + + + + Date Range/Season + + + + Currency + + + + Slot + + + + Pickup Included + + + + Drop Off Included + + + + Status + + + + Action + + + + + + {{rateDetails.option_name}} + {{rateDetails.nationality}} + + + {{rateDetails.date + == null ? '' : + item | date: 'dd MMM YYYY' }} {{ + + + i == 0 && rateDetails.date.split(',').length > 1? '-' : ''}} + + + {{rateDetails.currency_code}} + + {{item.date}} + + {{rateDetails.is_pickup_included ? "Yes" : "No"}} + {{rateDetails.is_drop_off_included? "Yes" : "No"}} + + {{ + rateDetails.is_active ? + 'Active' : 'Deactive' }} + + + +
    + + + + + + + + + +
    + + +
    + + + + No data found + + + +
    +
    + +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.ts new file mode 100644 index 0000000..0035ef1 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/rate-config/rate-config.component.ts @@ -0,0 +1,122 @@ +import { Component, OnInit } from '@angular/core'; +import * as FileSaver from 'file-saver'; +import { + ConfirmationService, + MessageService, + PrimeNGConfig, +} from 'primeng/api'; +import { API } from 'src/app/core/services/api.service'; + +import { Product } from 'src/app/core/services/product'; +import { CommonService } from 'src/app/core/services/common.service'; +import { Router } from '@angular/router'; +import { ActivityAllContract } from 'src/app/core/models/Experience-Service/experience-rate-config-Edit/edit-rate-confi/edit-rate-confi.model'; +import * as moment from 'moment'; + +@Component({ + selector: 'rate-config', + templateUrl: './rate-config.component.html', +}) +export class RateConfigComponent implements OnInit { + products!: Product[]; + selectedProducts!: Product[]; + + product!: Product; + rateDetails; + OptionName = ''; + is_pickup_included = false; + is_drop_off_included = false; + constructor(public ApiServ: API, private MsgService: MessageService, private router: Router) { } + ngOnInit(): void { + // this.GetallrateDetails(); + } + + + GetallrateDetails() { + let activityid = CommonService.getSessionStoage('activity_id'); + let postdata = new ActivityAllContract(); + postdata.activity_id = activityid; + postdata.is_drop_off_included = this.is_drop_off_included; + postdata.is_pickup_included = this.is_pickup_included; + postdata.option_name = this.OptionName; + this.ApiServ.Post('/ActivityContract/GetAllActivityRates', postdata).subscribe(data => { + if (data) { + this.rateDetails = data.responseObject; + } + }) + } + + UpdateStatus(ID, Status) { + let Obj = { + id: ID, + updatedBy: "", + "status": Status ? false : true + } + this.ApiServ.Post('/ActivityContract/UpdateStatus', Obj).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + this.GetallrateDetails(); + } + }); + }; + + EditCancelPoli(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditCancelletionPolicy'], { queryParams: obj }) + } + EditAllocation(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditAllocation'], { queryParams: obj }) + } + EditRateConfig(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditModifyRate'], { queryParams: obj }) + } + + EditDetails(Id) { + let obj = { id: Id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/EditDetails'], { queryParams: obj }) + } + + exportExcel() { + import('xlsx').then((xlsx) => { + const worksheet = xlsx.utils.json_to_sheet(this.products); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'products'); + }); + } + reset(){ + this.is_drop_off_included = false; + this.is_pickup_included = false; + this.OptionName = ''; + } + + + SoltsDetailsConvParse(data) { + let obj = data ? JSON.parse(data) : ''; + let html = []; + obj ? obj.forEach(e => html.push({ 'date': moment(e.start_time).format('hh:mm') + '-' + moment(e.end_time).format('hh:mm') })) : '' + return html + } + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.html new file mode 100644 index 0000000..d366fce --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.html @@ -0,0 +1,43 @@ +
    + + Back +
    +
    Add New Season Setting
    +
    +
    +
    + + + + Please enter season name + +
    +
    +
    +
    +
    + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.ts new file mode 100644 index 0000000..76f03d3 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/add-new-season/add-new-season.component.ts @@ -0,0 +1,168 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ActivitySeason, ActivitySeasonDetails } from 'src/app/core/models/Experience-Service/season-setting/season-setting-add.model'; +@Component({ + selector: 'app-add-new-season', + templateUrl: './add-new-season.component.html', +}) +export class AddNewSeasonComponent implements OnInit { + CommonCalender!: string; + minDateLst = [] + AddSeasonForm; + season_id; + messageService: any; + constructor( + private router: Router, + private route: ActivatedRoute, + private ApiServ: API, + private MsgService: MessageService, + public validationService: ValidationService, + private fb: FormBuilder + ) { } + + ngOnInit(): void { + this.initForm(); + this.minDateLst.push(new Date()) + this.update() + } + update() { + this.route.queryParams.subscribe(obj => { + if (obj['id']) { + this.ApiServ.Get('/ActivitySeason/GetActivitySeason/' + obj['id']).subscribe(d => { + this.SetValue(d['responseObject']); + this.season_id = obj['id']; + }); + } + }); + } + + initForm() { + this.AddSeasonForm = this.fb.group({ + season_name: this.validationService.required, + // supplier_id: ['2205221841391724322'], + activity_id: CommonService.getSessionStoage('activity_id'), + org_id: ['2105311837100000021'], + Calender: this.fb.array([ + this.fb.group({ + CalenderDate: [[new Date(), new Date()]] + }) + ]) + }) + } + SetValue(value) { + this.AddSeasonForm.get("season_name").setValue(value[0].activitySeason.season_name) + this.Calenders.clear() + for (let i = 0; i < value[0].seasondateRange.length; i++) { + this.Calenders.push(this.fb.group({ + CalenderDate: [[,]] + })) + let first = new Date(value[0].seasondateRange[i].fromDate); + let last = new Date(value[0].seasondateRange[i].toDate); + + this.Calenders.controls[i].get('CalenderDate').setValue([first, last]); + this.minDateLst[i] = first + } + } + get Calenders() { + return this.AddSeasonForm.get('Calender') as FormArray; + } + + onSelect(elem, index) { + for (let i = index + 1; i < this.Calenders.controls.length; i++) { + let value = this.Calenders.controls[index].value + this.Calenders.controls[i].get('CalenderDate').setValue([ + new Date(moment(value.CalenderDate[1]).add(1, 'days').format()),//start date + new Date(moment(value.CalenderDate[1]).add(1, 'days').format()) //end date + ]); + this.minDateLst[i] = new Date(moment(value.CalenderDate[1]).add(1, 'days').format()) + } + + } + addSeasonSetting(checkDate) { + if (checkDate) { + let value = this.Calenders.controls[this.Calenders.controls.length - 1].value + this.Calenders.push(this.fb.group({ + CalenderDate: [[ + new Date(moment(value.CalenderDate[1]).add(1, 'days').format()),//start date + new Date(moment(value.CalenderDate[1]).add(1, 'days').format())//end date + ]] + })); + this.minDateLst.push(new Date(moment(value.CalenderDate[1]).add(1, 'days').format())) + }; + } + + SaveSeason() { + if (this.AddSeasonForm.status == "INVALID") { + this.validationService.showValidationsMsg(this.AddSeasonForm); + return; + } + let dateArray = [] + for (let i = 0; i < this.Calenders.controls.length; i++) { + + let value = this.Calenders.controls[i].value + let newdate = value.CalenderDate + dateArray.push({ + FromDate: moment(newdate[0]).format('YYYY-MM-DD'), + ToDate: moment(newdate[1]).format('YYYY-MM-DD') + }) + } + let value = this.AddSeasonForm.getRawValue() + let SeasonModel = new ActivitySeasonDetails() + let Season = new ActivitySeason() + Season.org_id = ''; + Season.season_name = value.season_name; + Season.activity_id = value.activity_id; + Season.supplier_id = '' + Season.activity_season_id = this.season_id ? this.season_id : ''; + + SeasonModel.activitySeason = Season; + Season.created_by = ''; + Season.updated_by = '' + SeasonModel.seasondateRange = dateArray; + + if (this.season_id) { + this.ApiServ.Post('/ActivitySeason/UpdateActivitySeason', SeasonModel).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data['status'] ? 'success' : 'error', + detail: data['message'], + }); + setTimeout(() => { + data['status'] ? this.btnClick() : '' + }, 500); + } + }); + } else { + this.ApiServ.Post('/ActivitySeason/SaveActivitySeason', SeasonModel).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data['status'] ? 'success' : 'error', + detail: data['message'], + }); + setTimeout(() => { + data['status'] ? this.btnClick() : '' + }, 500); + } + }); + } + }; + removeSeasonSetting(index: number) { + this.Calenders.removeAt(index) + this.minDateLst.splice(index, 1) + } + btnClick() { + this.router.navigateByUrl("/Services/ActivityServices/ExpServices/Manage"); + } + descreption: string = ''; + + showInfo(descreption) { + this.descreption = descreption; + this.messageService.add({ severity: 'info', summary: 'samary', detail: '' }); + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.html new file mode 100644 index 0000000..5b9a028 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.html @@ -0,0 +1,117 @@ +
    +
    Season Setting
    + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Season Name + + + + Season Date Range + + + + Status + + + + Action + + + + + + + {{SeasonData.activitySeason.season_name}} + + {{date.fromDate | date: + 'dd MMM yyyy'}} - {{date.toDate| date: 'dd MMM yyyy'}} + + + {{ + SeasonData.activitySeason.is_active ? 'Active' : 'Deactive'}} + + +
    + + + + + +
    + + +
    + + + + No data found + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.ts new file mode 100644 index 0000000..462f4af --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/season-creation/season-creation.component.ts @@ -0,0 +1,106 @@ +import { Component, OnInit } from '@angular/core'; +import * as FileSaver from 'file-saver'; +import { MessageService } from 'primeng/api'; +import { API } from 'src/app/core/services/api.service'; +import jsPDF from "jspdf"; +import "jspdf-autotable"; +import { Router } from '@angular/router'; +import { CommonService } from 'src/app/core/services/common.service'; +@Component({ + selector: 'season-creation', + templateUrl: './season-creation.component.html', +}) +export class SeasonCreationComponent implements OnInit { + constructor( + private router: Router, + private ApiServ: API, + private MsgService: MessageService, + // private primengConfig: PrimeNGConfig + ) { } + SeasonData; + cols!: any[]; + exportColumns!: any[]; + Season_name = ''; + ngOnInit(): void { + // this.primengConfig.ripple = true; + this.cols = [ + { field: 'activitySeason.season_name', header: 'Season Name', customExportHeader: 'Product Code' }, + { field: 'seasondateRange.fromDate', header: 'Season Date Range' }, + { field: 'activitySeason.is_active', header: 'Status' }, + ]; + + this.exportColumns = this.cols.map((col) => ({ + title: col.header, + dataKey: col.field, + })); + } + + exportPdf() { + // const doc = new jsPDF(); + const doc = new jsPDF('p', 'pt'); + doc['autoTable'](this.exportColumns, this.SeasonData); + doc.save("Season_Data_export_" + new Date().getTime() + ".pdf"); + } + + Edit(sea_id) { + let obj = { id: sea_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/AddNewSeason'], { queryParams: obj }) + } + + UpdateStatus(exp_id, status) { + let obj = { id: exp_id, status: status ? false : true, updatedBy: '' } + this.ApiServ.Post('/ActivitySeason/UpdateStatus', obj).subscribe((data) => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + this.SearchSeason(); + } + }); + } + + SearchSeason() { + let activityid = CommonService.getSessionStoage('activity_id') + this.ApiServ.Get('/ActivitySeason/GetAllActivitySeason?activityId=' + activityid + '&seasonName=' + this.Season_name).subscribe(e => { + if (e) { + this.SeasonData = e['responseObject']; + } + }) + } + + reset() { + this.Season_name = ''; + } + + exportExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.SeasonData); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'Season_Data_export_' + new Date().getTime()); + }); + } + + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } + + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.html new file mode 100644 index 0000000..1e67d3b --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.html @@ -0,0 +1,59 @@ +
    + + Back +
    +
    Add Slot
    +
    +
    +
    + + + + Please select Slot Start Time + + Please select different start time + +
    +
    + + + Please + select slot end time + + Please select different end time + +
    +
    + + + Please select cut-off time + +
    +
    + + + {{item.utc + ' ' + item.timezone }} + + + Please select time zone + +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.ts new file mode 100644 index 0000000..a0d88ec --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/add-slots/add-slots.component.ts @@ -0,0 +1,173 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ActivitySlot } from 'src/app/core/models/Experience-Service/slot/add-slots-model'; +// import { ActivitySlot } from 'src/app/core/models/Experience-Service/slot/add-slots.model'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; + +@Component({ + selector: 'app-add-slots', + templateUrl: './add-slots.component.html', +}) +export class AddSlotsComponent implements OnInit { + date8: Date; + timeZoneData: any; + slot_id: any; + constructor( + public fb: FormBuilder, + public ApiServ: API, + public router: Router, + public validationService: ValidationService, + public MsgService: MessageService, + public routes: ActivatedRoute + ) { } + SaveAddSlot: FormGroup; + date1 = new Date(); + date2 = new Date(); + ngOnInit(): void { + this.initform(); + this.GetData(); + this.GetSlotId(); + this.date1.setHours(0); + this.date1.setMinutes(0); + this.date1.setSeconds(0); + this.date2.setHours(0); + this.date2.setMinutes(0); + this.date2.setSeconds(0); + } + + initform() { + this.SaveAddSlot = this.fb.group({ + start_time: [this.date1, Validators.required], + start_time_Check: [false], + end_time_Check: [false], + end_time: [this.date2, Validators.required], + cut_off_time: [this.date2, Validators.required], + timezone: this.validationService.required, + }); + } + + GetData() { + this.ApiServ.Get('/TimezoneCity/GetAllTimezoneCity').subscribe((res) => { + if (res) { + this.timeZoneData = res; + } + }); + } + //this function is user for edit + GetSlotId() { + this.routes.queryParams.subscribe((d) => { + if (d['id']) { + this.slot_id = d['id']; + this.ApiServ.Get('/ActivitySlot/GetSlot/' + d['id']).subscribe( + (data) => { + if (data) { + this.AllSetvalue(data['responseObject']); + } + } + ); + } + }); + } + + AllSetvalue(val) { + Object.keys(val).forEach((li) => { + if (li == 'cut_off_time' || li == 'start_time' || li == 'end_time') { + let date = val[li].split('T'); + let st = moment().utc().format('MM-DD-YYYY ' + date[1]); + let date1 = new Date(st); + this.SaveAddSlot.get(li).setValue(date1); + } + if (li == 'timezone') { + this.SaveAddSlot.get(li).setValue(val[li]); + } + }); + } + + Save() { + + if (this.SaveAddSlot.status == 'INVALID') { + console.log(this.SaveAddSlot.get('start_time')); + this.validationService.showValidationsMsg(this.SaveAddSlot); + console.log(this.SaveAddSlot); + return; + } + let val = this.SaveAddSlot.getRawValue(); + var now = new Date(val.start_time); + var d = new Date(val.end_time); + if (now.getTime() == d.getTime() || now.getTime() >= d.getTime()) { + this.SaveAddSlot.get('start_time_Check').setValue(true); + this.SaveAddSlot.get('end_time_Check').setValue(true); + return + } + let postdata = new ActivitySlot(); + postdata.activity_id = CommonService.getSessionStoage('activity_id'); + postdata.start_time = + '0001-01-01' + 'T' + moment(val.start_time).format('HH:mm:01'); + postdata.end_time = + '0001-01-01' + 'T' + moment(val.end_time).format('HH:mm:01'); + postdata.cut_off_time = + '0001-01-01' + 'T' + moment(val.cut_off_time).format('HH:mm:01'); + postdata.timezone = val.timezone; + postdata.is_deleted = false; + postdata.activity_slot_id = this.slot_id ? this.slot_id : ''; + postdata.org_id = ''; + postdata.supplier_id = ''; + + if (this.slot_id) { + this.ApiServ.Post('/ActivitySlot/UpdateActivitySlot', postdata).subscribe( + (res) => { + if (res) { + console.log(res); + this.MsgService.add({ + severity: res['status'] ? 'success' : 'error', + detail: res['message'], + }); + setTimeout(() => { + this.router.navigate([ + '/Services/ActivityServices/ExpServices/Manage', + ]); + }, 500); + } + } + ); + } else { + this.ApiServ.Post('/ActivitySlot/SaveActivitySlot', postdata).subscribe( + (res) => { + if (res) { + console.log(res); + this.MsgService.add({ + severity: res['status'] ? 'success' : 'error', + detail: res['message'], + }); + setTimeout(() => { + this.router.navigate([ + '/Services/ActivityServices/ExpServices/Manage', + ]); + }, 500); + } + } + ); + } + } + + + + // + Check() { + let val = this.SaveAddSlot.getRawValue(); + var now = new Date(val.start_time); + var d = new Date(val.end_time); + if (now.getTime() == d.getTime() || now.getTime() >= d.getTime()) { + this.SaveAddSlot.get('start_time_Check').setValue(true); + this.SaveAddSlot.get('end_time_Check').setValue(true); + } else { + this.SaveAddSlot.get('start_time_Check').setValue(false); + this.SaveAddSlot.get('end_time_Check').setValue(false); + } + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.html new file mode 100644 index 0000000..cdc9fd2 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.html @@ -0,0 +1,163 @@ +
    + Search Slots + +
    +
    +
    +
    + +
    +
    + + + {{ item.hour }} : {{item.minute}} + +
    +
    +
    +
    + +
    +
    + + + {{item.hour}} : {{item.minute}} + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Id + + + + Slot Start Time + + + + Slot End Time + + + + Cut-Off Time (in Hrs) + + + + Status + + + + Action + + + + + + + {{ AllSlots.activity_slot_id }} + + {{ + AllSlots.start_time | date: "H:mm" + }} + + + {{ + AllSlots.end_time | date: "H:mm" + }} + + + {{ + AllSlots.cut_off_time | date: "H:mm" + }} + + + + {{ AllSlots.is_active ? "Active" : "Deactive" }} + + +
    + + + + + +
    + + +
    + + + + No data found + + + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.ts new file mode 100644 index 0000000..87b8413 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs-content/slots/slots.component.ts @@ -0,0 +1,69 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Product } from 'src/app/core/services/product'; +import * as FileSaver from 'file-saver'; +import { MatMenuTrigger } from '@angular/material/menu'; +import { API } from 'src/app/core/services/api.service'; +import { MessageService } from 'primeng/api'; +import { Router } from '@angular/router'; +import { CommonService } from 'src/app/core/services/common.service'; +import { GetActivitySlot } from 'src/app/core/models/Experience-Service/slot/add-slots-model'; +import * as moment from 'moment'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +@Component({ + selector: 'slots', + templateUrl: './slots.component.html', +}) +export class SlotsComponent implements OnInit { + @ViewChild('menuTrigger') menuTrigger: MatMenuTrigger; + + displayModal: boolean; + AllSlots: any; + + showModalDialog() { + this.displayModal = true; + } + constructor(public ApiServ: API, private MsgService: MessageService, public router: Router, public CommonVari: StaticDataService) { } + StartTime; + EndTime; + ngOnInit(): void { + } + + GetAllSlot() { + let post = new GetActivitySlot(); + let activity_id = CommonService.getSessionStoage('activity_id'); + post.activity_id = activity_id; + post.from_hour = this.StartTime ? this.StartTime.split(':')[0] : null; + post.from_minute = this.StartTime ? this.StartTime.split(':')[1] : null; + post.to_hour = this.EndTime ? this.EndTime.split(':')[0] : null; + post.to_minute = this.EndTime ? this.EndTime.split(':')[1] : null; + this.ApiServ.Post('/ActivitySlot/GetAllSlot', post).subscribe(res => { + if (res) { + this.AllSlots = res['responseObject']; + } + }); + } + reset() { + this.EndTime = null; + this.StartTime = null + } + UpdateStatus(slot_id, status) { + let obj = { Id: slot_id, Status: status ? false : true } + this.ApiServ.Post('/ActivitySlot/UpdateStatus', obj).subscribe(data => { + if (data) { + this.GetAllSlot(); + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + } + }) + } + + // table + cols!: any[]; + + Edit(pk_id) { + let obj = { id: pk_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage/AddSlots'], { queryParams: obj }); + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.html new file mode 100644 index 0000000..6f2b8c8 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.ts new file mode 100644 index 0000000..0464e6d --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-manage/tabs/tabs.component.ts @@ -0,0 +1,17 @@ +import { Component, OnInit } from '@angular/core'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; + +@Component({ + selector: 'app-tabs', + templateUrl: './tabs.component.html', +}) +export class TabsComponent implements OnInit { + + constructor(public CommonVariable: StaticDataService) { } + ngOnInit(): void { + } + TabviewSet(data) { + this.CommonVariable.ActivityOverViewtab = data.index; + console.log(this.CommonVariable.ActivityOverViewtab); + } +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.html b/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.html new file mode 100644 index 0000000..3e8d505 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.html @@ -0,0 +1,230 @@ +
    +
    Search Experience
    + +
    +
    +
    +
    + + +
    +
    + + ExpCity + +
    + +
    Supplier
    +
    + +
    +
    +
    +
    + + + + +
    +
    + + + +
    +
    + + + + +
    +
    + + + +
    + +
    City
    +
    + +
    +
    +
    +
    + Pickup Included +
    +
    + Drop Off Included +
    +
    +
    + + +
    +
    + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Experience Id + + + + Experience Name + + + + Supplier + + + + Country + + + + City + + + + Pickup Included + + + + Drop Off Included + + + + Status + + + + Action + + + + + + + + {{exp.activity_id}} + + + {{exp.activity_name}} + + + - + + + {{exp.country_name}} + + + {{exp.city_name}} + + + {{exp.is_pickup_included ? 'Yes' : 'No'}} + + + {{exp.is_drop_included ? 'Yes' : 'No'}} + + {{ + exp.is_active ? 'Active' : 'Deactive'}} + + +
    + + + + + + + + +
    + + +
    + + + + No data found + + + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.ts b/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.ts new file mode 100644 index 0000000..1054332 --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services-search/exp-services-search.component.ts @@ -0,0 +1,260 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as FileSaver from 'file-saver'; +import jsPDF from "jspdf"; +import "jspdf-autotable"; +import { MessageService } from 'primeng/api'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { API } from 'src/app/core/services/api.service'; +import { CommonService } from 'src/app/core/services/common.service'; + + +@Component({ + selector: 'app-exp-services-search', + templateUrl: './exp-services-search.component.html', +}) +export class ExpServicesSearchComponent implements OnInit { + ExpSearch: FormGroup; + ExpData; + SubCategory; + ExpCatData; + cols: any[]; + exportColumns; + CityData; + ExpSupData: any; + CountryData: any; + Experience_Type; + constructor( + private router: Router, + private fb: FormBuilder, + public ApiServ: API, + private MsgService: MessageService, + private commonVari: StaticDataService + + ) { } + + + + + /** + * @author Abdul Razzak + * to get supplier data + */ + ExpSupplier() { + this.ApiServ.Get('/HotelSupplierMapping/GetAllHotelSupplierMapping').subscribe(data => { + if (data) { + this.ExpSupData = data['responseObject']; + } + }); + }; + + + /** + * @author Abdul Razzak + * to get city based on country + */ + ExpCity() { + let val = this.ExpSearch.getRawValue(); + this.ApiServ.Get('/City/GetCity/' + val.country_code).subscribe((data) => { + if (data) { + this.CityData = data; + } + }); + }; + + /** + * @author Abdul Razzak + * to get all country + */ + ExpCounrty() { + this.ApiServ.Get('/Country/GetCountry').subscribe(data => { + if (data) { + this.CountryData = data; + console.log(this.CountryData) + } + }); + }; + + /** + * @author Abdul Razzak + * to get all category + */ + GetAllCategory() { + this.ApiServ.Get('/ActivityCategoryMaster/GetAllCategory').subscribe(data => { + if (data) { + this.Experience_Type = data['responseObject'] + } + }); + }; + + /** + * @author Abdul Razzak + * to get sub category based on category + */ + GetSubCategory(value) { + this.ExpSearch.get('sub_category_id').setValue('') + this.ApiServ.Get('/ActivityCategoryMaster/GetSubCategory?Id=' + value).subscribe(data => { + if (data) { + this.SubCategory = data['responseObject'] + } + }); + }; + + ngOnInit(): void { + this.ExpCounrty(); + this.GetAllCategory() + this.ExpSupplier(); + CommonService.resetLocalStoage('activity_id'); + this.initForm(); + this.cols = [ + { field: "activity_id", header: "Experience Id" }, + { field: "activity_name", header: "Experience Name" }, + { field: "category_name", header: "Experience Type" }, + { field: "country_name", header: "Country" }, + { field: "city_name", header: "City" }, + { field: "is_pickup_included", header: "Pickup Included" }, + { field: "is_drop_included", header: "Drop Off Included" }, + { field: "is_active", header: "Status" } + ]; + this.exportColumns = this.cols.map(col => ({ + title: col.header, + dataKey: col.field + })); + } + + /** + * @author Abdul Razzak + * to get supplier data + * @param Activity_id + */ + Edit(activity_id) { + let obj = { id: activity_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/Add'], { queryParams: obj }); + } + + /** + * @author Abdul Razzak + * method to store Activity id + */ + Manage(activity_id) { + CommonService.setSessionStorage('activity_id', activity_id); + this.router.navigate(['/Services/ActivityServices/ExpServices/Manage']); + this.commonVari.ActivityOverViewtab = 0; + } + + manageTrans(activity_id) { + let obj = { id: activity_id }; + this.router.navigate(['/Services/ActivityServices/ExpServices/ManageTranslation'], { queryParams: obj }); + }; + + /** + * @author Abdul Razzak + * to create form group + */ + initForm() { + this.ExpSearch = this.fb.group({ + activity_name: [''], + city_id: [''], + category_id: [''], + sub_category_id: [''], + country_code: [''], + is_pickup_included: [false], + is_drop_included: [false], + }); + } + + /** + * @author Abdul Razzak + * to get all activitys + */ + SearchExp() { + this.ApiServ.Post('/Activity/GetAllActivity', this.ExpSearch.getRawValue()).subscribe(e => { + if (e) { + this.ExpData = e['responseObject']; + } + }); + }; + + /** + * @author Abdul Razzak + * to active or deactive + * @param exp_id + * @param status + */ + UpdateStatus(exp_id, status) { + let obj = { id: exp_id, status: status ? false : true, updatedBy: '' } + this.ApiServ.Post('/Activity/UpdateStatus', obj).subscribe((data) => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + this.SearchExp(); + } + }); + }; + + /** + * @author Abdul Razzak + * to reset search form value + */ + ResetExp() { + this.ExpSearch.get('activity_name').setValue('') + this.ExpSearch.get('city_id').setValue('') + this.ExpSearch.get('country_code').setValue('') + this.ExpSearch.get('category_id').setValue('') + this.ExpSearch.get('sub_category_id').setValue('') + this.ExpSearch.get('is_pickup_included').setValue(false) + this.ExpSearch.get('is_drop_included').setValue(false) + this.SearchExp(); + }; + + /** + * @author Abdul Razzak + * to download excel sheet + */ + exportExcel() { + import('xlsx').then((xlsx) => { + const worksheet = xlsx.utils.json_to_sheet(this.ExpData); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'Experience_Service'); + }); + }; + /** + * @author Abdul Razzak + * to download Excel + */ + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + }; + /** + * @author Abdul Razzak + * to download PDF + */ + exportPdf() { + // const doc = new jsPDF(); + const doc = new jsPDF('p', 'pt'); + doc['autoTable'](this.exportColumns, this.ExpData); + // doc.autoTable(this.exportColumns, this.products); + doc.save("Experience_Service_export_" + new Date().getTime() + ".pdf"); + }; + + + +} diff --git a/src/app/modules/services/activity-services/exp-services/exp-services.module.ts b/src/app/modules/services/activity-services/exp-services/exp-services.module.ts new file mode 100644 index 0000000..6a90d7c --- /dev/null +++ b/src/app/modules/services/activity-services/exp-services/exp-services.module.ts @@ -0,0 +1,100 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// import { ExpServicesSearchComponent } from './experience-services-search/experience-services-search.component'; +import { RouterModule, Routes } from '@angular/router'; + + +// +import { ButtonModule } from 'primeng/button'; +import { CalendarModule } from 'primeng/calendar'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { RatingModule } from 'primeng/rating'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TreeModule } from 'primeng/tree'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MessageService, ConfirmationService } from 'primeng/api'; +import { ProductService } from 'src/app/core/services/product.service'; +import { CheckboxModule } from 'primeng/checkbox'; +import {EditorModule} from 'primeng/editor'; + +import {FileUploadModule} from 'primeng/fileupload'; +import {HttpClientModule} from '@angular/common/http'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { ToastModule } from 'primeng/toast'; +import { ExpServicesAddComponent } from './exp-services-add/exp-services-add.component'; +import { ExpServicesSearchComponent } from './exp-services-search/exp-services-search.component'; +import { ExpManageTranslationComponent } from './exp-manage-translation/exp-manage-translation.component'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; + +const routes: Routes = [ + { + path: 'Search', + component: ExpServicesSearchComponent, + }, + { + path: 'Manage', + loadChildren: () => + import('./exp-services-manage/exp-services-manage.module').then( + (m) => m.ExpServicesManageModule + ), + }, + { + path: 'ManageTranslation', + component: ExpManageTranslationComponent + }, + { + path: 'Add', + component: ExpServicesAddComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ + ExpServicesSearchComponent, + ExpServicesAddComponent, + ExpManageTranslationComponent, + // HotelServicesComponent, + // TabsComponent, + ], + imports: [ + CommonModule, + FormsModule, + CalendarModule, + TableModule, + InputTextModule, + NgSelectModule, + InputNumberModule, + TreeModule, + RatingModule, + ButtonModule, + ToolbarModule, + RouterModule.forChild(routes), + CheckboxModule, + EditorModule, + FileUploadModule, + HttpClientModule, + MatMenuModule, + MatButtonModule, + MatCheckboxModule, + ReactiveFormsModule, + FormsModule, + ToastModule + ], + providers:[ + MessageService, + ConfirmationService, + ProductService, + StaticDataService + ] +}) +export class ExpServicesModule {} diff --git a/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.html b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.html new file mode 100644 index 0000000..c495967 --- /dev/null +++ b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.html @@ -0,0 +1,235 @@ +
    + + Back +
    + +
    Add Hotel Zone
    +
    +
    +
    + + +
    + + +
    + + + + +
    + +
    Trip Type
    +
    + +
    +
    +
    +
    + + + +
    + +
    Airline
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + + +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + Hotel NameHotel Star CategoryAddressCity
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    + + Hotel 14Four square, DubaiDubai
    +
    +
    + +
    +
    diff --git a/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.ts b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.ts new file mode 100644 index 0000000..56c6f88 --- /dev/null +++ b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-add/hotel-zone-services-add.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-hotel-zone-services-add', + templateUrl: './hotel-zone-services-add.component.html', +}) +export class HotelZoneServicesAddComponent implements OnInit { + constructor() {} + + ngOnInit(): void {} + cities = [ + { id: 1, name: 'Select' }, + { id: 2, name: 'abc' }, + { id: 3, name: 'abc1' }, + { id: 4, name: 'abc2' }, + ]; + // selectedCity = this.cities[0].name; + labelFloat; + statusClass = 'not-active'; + + check = false; + fun1() { + this.statusClass = 'active'; + } + + fun2(val) { + if (val.target.value != '') { + this.statusClass = 'active'; + } + if (!this.check) { + this.statusClass = 'non-active'; + } + } + + fun3(val) { + console.log(val.target.value); + if (val.target.value == '') { + this.check = false; + this.statusClass = 'non-active'; + } else { + this.statusClass = 'active'; + } + } + + fun4(val) { + if (val != '') { + this.statusClass = 'active'; + this.check = true; + } + } + + setActiveClass() {} +} diff --git a/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.html b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.html new file mode 100644 index 0000000..d54f28f --- /dev/null +++ b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.html @@ -0,0 +1,215 @@ +
    + Hotel Zones + +
    +
    +
    +
    + + +
    + +
    + + + +
    + +
    Trip Type
    +
    + +
    +
    +
    +
    + + + +
    + +
    Airline
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Zone Id + + + + Zone Name + + + + Zone Code + + + + Country + + + + City + + + + Status + + + Action + + + + + 220220202020 + Mumbai City Zone + MUMZ01 + India + Mumbai + + {{ product.inventoryStatus }} + + +
    + + + + + +
    + + +
    +
    +
    diff --git a/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.ts b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.ts new file mode 100644 index 0000000..19f98e9 --- /dev/null +++ b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services-search/hotel-zone-services-search.component.ts @@ -0,0 +1,107 @@ +import { MatMenuTrigger } from '@angular/material/menu'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Product } from 'src/app/core/services/product'; +import { ProductService } from 'src/app/core/services/product.service'; +import * as FileSaver from 'file-saver'; +@Component({ + selector: 'app-hotel-services-search', + templateUrl: './hotel-zone-services-search.component.html', +}) +export class HotelZoneServicesSearchComponent implements OnInit { + @ViewChild('menuTrigger') menuTrigger: MatMenuTrigger; + + displayModal: boolean; + + constructor( + private productService: ProductService, + ) {} + + cities = [ + { id: 1, name: 'Vilnius' }, + { id: 2, name: 'Kaunas' }, + { id: 3, name: 'Pavilnys', disabled: true }, + { id: 4, name: 'Pabradė' }, + { id: 5, name: 'Klaipėda' }, + ]; + selectedCity = this.cities[0].name; + + ngOnInit(): void { + this.productService.getProducts().then((data) => (this.products = data)); + } + + rangeDates: Date[]; + + minDate: Date; + + maxDate: Date; + + es: any; + + invalidDates: Array; + // table + cols!: any[]; + + productDialog!: boolean; + + products!: Product[]; + + product!: Product; + + selectedProducts!: Product[]; + + submitted!: boolean; + + openNew() { + this.product = {}; + this.submitted = false; + this.productDialog = true; + } + + findIndexById(id: string): number { + let index = -1; + for (let i = 0; i < this.products.length; i++) { + if (this.products[i].id === id) { + index = i; + break; + } + } + return index; + } + createId(): string { + let id = ''; + var chars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (var i = 0; i < 5; i++) { + id += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return id; + } + exportExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.products); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'products'); + }); + } + + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } +} diff --git a/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services.module.ts b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services.module.ts new file mode 100644 index 0000000..83290c0 --- /dev/null +++ b/src/app/modules/services/activity-services/hotel-zone-services/hotel-zone-services.module.ts @@ -0,0 +1,63 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +// import { HotelZoneServicesAddComponent } from './hotel-services-add/hotel-services-add.component'; +// import { HotelZoneServicesSearchComponent } from './hotel-services-search/hotel-services-search.component'; +import { RouterModule, Routes } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { CheckboxModule } from 'primeng/checkbox'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TreeModule } from 'primeng/tree'; +import { ProductService } from 'src/app/core/services/product.service'; +import { HotelZoneServicesAddComponent } from './hotel-zone-services-add/hotel-zone-services-add.component'; +import { HotelZoneServicesSearchComponent } from './hotel-zone-services-search/hotel-zone-services-search.component'; +const routes: Routes = [ + { + path: 'Search', + component: HotelZoneServicesSearchComponent, + }, + + { + path: 'Add', + component: HotelZoneServicesAddComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [HotelZoneServicesAddComponent, HotelZoneServicesSearchComponent], + imports: [ + CommonModule, + ButtonModule, + NgSelectModule, + TreeModule, + ToolbarModule, + TableModule, + MatMenuModule, + MatButtonModule, + CheckboxModule, + InputTextModule, + InputNumberModule, + CalendarModule, + FormsModule, + MatDialogModule, + MatButtonModule, + MatCheckboxModule, + RouterModule.forChild(routes), + ], + providers: [ProductService], +}) +export class HotelZoneServicesModule {} diff --git a/src/app/modules/services/activity/activity-add/activity-add.component.html b/src/app/modules/services/activity/activity-add/activity-add.component.html new file mode 100644 index 0000000..2666304 --- /dev/null +++ b/src/app/modules/services/activity/activity-add/activity-add.component.html @@ -0,0 +1 @@ +

    activity-add works!

    diff --git a/src/app/modules/services/activity/activity-add/activity-add.component.ts b/src/app/modules/services/activity/activity-add/activity-add.component.ts new file mode 100644 index 0000000..b11b845 --- /dev/null +++ b/src/app/modules/services/activity/activity-add/activity-add.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-add', + templateUrl: './activity-add.component.html', +}) +export class ActivityAddComponent { + +} diff --git a/src/app/modules/services/activity/activity-language/activity-language.component.html b/src/app/modules/services/activity/activity-language/activity-language.component.html new file mode 100644 index 0000000..31d6833 --- /dev/null +++ b/src/app/modules/services/activity/activity-language/activity-language.component.html @@ -0,0 +1,125 @@ + +
    +
    +
    +

    Manage Translation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Translate To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Default Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Selected Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-language/activity-language.component.ts b/src/app/modules/services/activity/activity-language/activity-language.component.ts new file mode 100644 index 0000000..501cbdd --- /dev/null +++ b/src/app/modules/services/activity/activity-language/activity-language.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-language', + templateUrl: './activity-language.component.html', +}) +export class ActivityLanguageComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.html b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.html new file mode 100644 index 0000000..b3769e0 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.html @@ -0,0 +1,546 @@ +
    +
    +
    +

    Add Activity Details

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Activity Highlights

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Activity Category

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Emergency Contact Number

    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Service Language

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Service Duration (Days)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Service Duration (Hours)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Service Duration (Minutes)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Starting City

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Pickup Included

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Pickup Point

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Hotel Pickup

    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    +
    +

    Hotels

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Hotel Zones

    +
    + +
    +
    +
    + + + +
    +
    +
    + +
    +
    + + + +
    +
    +
    +

    Departure Point

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Pickup Before Time (Hours)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Pickup Before Time (Minutes)

    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Meeting Before Time (Hours)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meeting Before Time (Minutes)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Drop Off Included

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.ts b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.ts new file mode 100644 index 0000000..8441809 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-details', + templateUrl: './activity-details.component.html', +}) +export class ActivityDetailsComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-details/activity-details.module.ts b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.module.ts new file mode 100644 index 0000000..3f398a7 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-details/activity-details.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ActivityDetailsComponent } from './activity-details.component'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: '', + component:ActivityDetailsComponent, + }, +] +@NgModule({ + declarations: [ActivityDetailsComponent], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + ActivityDetailsComponent + ] +}) +export class ActivityDetailsModule { } diff --git a/src/app/modules/services/activity/activity-manage/activity-manage.component.html b/src/app/modules/services/activity/activity-manage/activity-manage.component.html new file mode 100644 index 0000000..325f728 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-manage.component.html @@ -0,0 +1,62 @@ +
    + + Back +
    +
    +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-manage.component.ts b/src/app/modules/services/activity/activity-manage/activity-manage.component.ts new file mode 100644 index 0000000..2083934 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-manage.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-manage', + templateUrl: './activity-manage.component.html', +}) +export class ActivityManageComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-manage.module.ts b/src/app/modules/services/activity/activity-manage/activity-manage.module.ts new file mode 100644 index 0000000..ca56b53 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-manage.module.ts @@ -0,0 +1,106 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { TabViewModule } from 'primeng/tabview'; +import { HotelRoomModule } from '../../hotel/hotel-manage/hotel-room/hotel-room.module'; +import { ActivityManageComponent } from './activity-manage.component'; +import { ActivityOverviewComponent } from './activity-overview/activity-overview.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ActivityOverviewModule } from './activity-overview/activity-overview.module'; + +const routes: Routes = [ + + { + path: '', + component: ActivityManageComponent, + }, + { + path: 'ActivityDetails', + loadChildren: () => + import('./activity-details/activity-details.module').then( + (m) => m.ActivityDetailsModule + ), + }, + { + path: 'TravelDetails', + loadChildren: () => + import('./travel-details/travel-details.module').then( + (m) => m.TravelDetailsModule + ), + }, + { + path: 'Itinerary', + loadChildren: () => + import('./itinerary/itinerary.module').then( + (m) => m.ItineraryModule + ), + }, + { + path: 'Media', + loadChildren: () => + import('./media/media.module').then( + (m) => m.MediaModule + ), + }, + { + path: 'RequiredInfo', + loadChildren: () => + import('./required-info/required-info.module').then( + (m) => m.RequiredInfoModule + ), + }, + { + path: 'Season', + loadChildren: () => + import('./season/season.module').then( + (m) => m.SeasonModule + ), + }, + { + path: 'Slots', + loadChildren: () => import('./slots/slots.module').then( + (m) => m.SlotsModule + ) + }, + { + path: 'Allocation', + loadChildren: () => import('./allocation/allocation.module').then( + (m) => m.AllocationModule + ) + }, + + { + path: 'ActivityOption', + loadChildren: () => import('./activity-option/activity-option.module').then( + (m) => m.ActivityOptionModule + ) + }, + { + path: 'Overview', + loadChildren: () => import('./activity-overview/activity-overview.module').then( + (m) => m.ActivityOverviewModule + ) + }, + +] + + +@NgModule({ + declarations: [ + ActivityManageComponent, + + ], + imports: [ + CalendarModule, + CommonModule, + FormsModule, + MatMenuModule, + HotelRoomModule, + TabViewModule, + RouterModule.forChild(routes), + + ] +}) +export class ActivityManageModule { } diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.html new file mode 100644 index 0000000..f2e3e84 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.html @@ -0,0 +1,309 @@ +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Days

    +
    + +
    +
    +
    + Monday + Tuesday + Wednesday +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    Per Person Pricing

    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    Date
    +
    +
    Day
    +
    +
    + Policy Type +
    +
    +
    + Cancellation Type +
    +
    +
    + From +
    +
    +
    + To +
    +
    +
    + Value + +
    +
    +
    +
    +
    + 12 Mar 2021 + + Mon + + Dropdown values: + Day + +
    + + + +
    +
    +
    +

    +
    + +
    +
    +
    + Non-refundable +
    +
    +
    + 0 + + 365 + +
    + + +
    +
    13 Mar 2021 Tue Dropdown values: Day +
    + + + +
    +
    +
    +

    +
    + +
    +
    +
    + Full Charges + Percentage + Amount + Non-refundable +
    +
    +
    61020 +
    + +
    +
    13 Mar 2021 Tue Dropdown values: + Day +
    + + + +
    +
    +
    +

    +
    + +
    +
    +
    + Amount +
    +
    +
    112020 +
    + +
    +
    + 14 Mar 2021 + Wed Dropdown values: + Day +
    + + + +
    +
    +
    +

    +
    + +
    +
    +
    + Percentage +
    +
    +
    61020 +
    + +
    +
    15 Mar 2021 Thus Dropdown values: + Day +
    + + + +
    +
    +
    +

    +
    + +
    +
    +
    + Amount +
    +
    +
    61020 +
    + +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.ts new file mode 100644 index 0000000..b27ed60 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-cancellation-policy/activity-edit-cancellation-policy.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-edit-cancellation-policy', + templateUrl: './activity-edit-cancellation-policy.component.html', + +}) +export class ActivityEditCancellationPolicyComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.html new file mode 100644 index 0000000..3d1dd06 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.html @@ -0,0 +1,350 @@ + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Supported Transfer Type

    +
    + +
    +
    +
    + Private + Shared + Without Transfer +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Transfer Included in Price

    +
    + +
    +
    +
    + Private Transfer + Shared Transfer + Without Transfer +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Selection +

    +
    + +
    +
    +
    + Private Transfer + Shared Transfer + Without Transfer +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Selection +

    +
    + +
    +
    +
    + Private Transfer + Shared Transfer + Without Transfer +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +

    Other Details

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Contract Remark

    +
    + +
    +
    +
    + Private + Shared + Without Transfer +
    +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Tourist Guide Type

    +
    + +
    +
    +
    + 1. Physical Guide + 2. Reading Material + 3. Audio Guide +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Tourist Guide Languages

    +
    + +
    +
    +
    + 1. + 2. + 3. +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Applicable Add-On

    +
    + +
    +
    +
    + 1. + 2. + 3. +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.ts new file mode 100644 index 0000000..80d438d --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-option/activity-edit-option.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-edit-option', + templateUrl: './activity-edit-option.component.html', + +}) +export class ActivityEditOptionComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.html new file mode 100644 index 0000000..ab19ac0 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.html @@ -0,0 +1,569 @@ +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +

    Price Config

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Days

    +
    + +
    +
    +
    + Monday + Tuesday + Wednesday +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    Per Person Pricing

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    Date
    +
    +
    Day
    +
    +
    + Adult Price (age range) + +
    +
    +
    + Senior Price (age range) + +
    +
    +
    + Youth Price (age range) + +
    +
    +
    + Child Price (age range) + +
    +
    +
    + Child Price (age range) + +
    +
    + 12 Mar 2021 + + Mon + + 150 + + 120 + + 120 + + 120 + + 120 +
    13 Mar 2021 Tue 150 120 120 120 120
    + 14 Mar 2021 + Wed 135 105 105 105 105
    15 Mar 2021 Thus 150 120 120 120 120
    16 Mar 2021 Fri 150 120 120 120 120
    17 Mar 2021 Sat 150 120 120 120 120
    18 Sun 2021 Tue 150 120 120 120 120
    19 Mar 2021 Mon 150 120 120 120 120
    20 Mar 2021 Tue 150 120 120 120 120
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Activity Pricing

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + Max Occupancy + +
    +
    +
    + Activity Price + +
    +
    + 12 Mar 2021 + + Mon + + 150 + + 120 +
    13 Mar 2021 Tue 150 120
    + 14 Mar 2021 + Wed 135 105
    15 Mar 2021 Thus 150 120
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Tiered Pricing

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + Adult (age 12 to 55) + +
    +
    +
    + Adult (age 12 to 55) + +
    +
    +
    + Adult (age 12 to 55) + +
    +
    +
    + Child Range 1 (Age 0 to 5) + +
    +
    +
    + Child Range 1 (Age 0 to 5) + +
    +
    +
    + Child Range 1 (Age 0 to 5) + +
    +
    +
    + Child Range 2 (Age 6 to 10) + +
    +
    +
    + Child Range 2 (Age 6 to 10) + +
    +
    +
    + Child Range 2 (Age 6 to 10) + +
    +
    + 12 Mar 2021 + + Mon +
    13 Mar 2021 Tue
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.ts new file mode 100644 index 0000000..ce30970 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-edit-price/activity-edit-price.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-edit-price', + templateUrl: './activity-edit-price.component.html', + +}) +export class ActivityEditPriceComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.html new file mode 100644 index 0000000..ebbd273 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.html @@ -0,0 +1,1226 @@ + +
    +
    +
    +

    Add Activity Option

    +
    +
    +
    +
    +
    +
    +
    Activity Name
    + +
    +
    +
    +
    +
    Country
    + +
    +
    +
    +
    +
    City
    + +
    +
    + +
    +
    + + +
    +
    + +
    +
    + + + +
    +
    +
    +

    Transfer Included in Price

    +
    + +
    +
    +
    + type 1 + type 2 + type 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Transfer Included in Price

    +
    + +
    +
    +
    + type 1 + type 2 + type 3 +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Departure Days

    +
    + +
    +
    + +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Supported Transfer Type

    +
    + +
    +
    + +
    + Private + Shared + Without Transfer +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Transfer Included in Price

    +
    + +
    +
    +
    + Private Transfer + Shared Transfer + Without Transfer +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Vehicle Selection

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    +

    Price Config

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Apply Price On

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Select Slots

    +
    + +
    +
    + +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Applicable days

    +
    + +
    +
    + +
    + Monday + Thuesday + Wednesday +
    +
    +
    +
    +
    +
    +
    +

    Adult (30 to 45)

    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Senior (46 to 70)

    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Youth (18 to 30)

    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Child (3 to 5)

    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Child (6 to 12)

    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    From

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    To

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    Pricing Per Pax
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +

    Other Details

    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Departure Days

    +
    + +
    +
    + +
    + Private + Shared + Without Transfer +
    +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Tourist Guide Type

    +
    + +
    +
    + +
    + 1. Physical Guide + 2. Reading Material + 3. Audio Guide +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Tourist Guide Languages

    +
    + +
    +
    + +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Applicable Add-On

    +
    + +
    +
    + +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.ts new file mode 100644 index 0000000..91e2c08 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-add/activity-option-add.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-option-add', + templateUrl: './activity-option-add.component.html', + +}) +export class ActivityOptionAddComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.html new file mode 100644 index 0000000..1053fe0 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.html @@ -0,0 +1,321 @@ + +
    +
    +
    +

    Cancellation Policy

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + Flexible + Non-refundable +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + Full Charges + Amount + Percentage +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + Full Charges + Amount + Percentage +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + 1 + 2 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + Full Charges + Amount + Percentage +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.ts new file mode 100644 index 0000000..568b9cd --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-policy/activity-option-policy.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-option-policy', + templateUrl: './activity-option-policy.component.html', + +}) +export class ActivityOptionPolicyComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.html new file mode 100644 index 0000000..41ecc62 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.html @@ -0,0 +1,231 @@ +
    +
    +
    +

    Activity Option Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Supported Transfer Type

    +
    + +
    +
    +
    + type 1 + type 2 + type 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Transfer Included in Price

    +
    + +
    +
    +
    + type 1 + type 2 + type 3 +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + type 1 +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Name + + + + Option Name + + + + Date Renge + + + + Currency + + + + Slot Id + + + + Tourist Guide Included + + + + Supported Transfer Type + + + + Transfer Included in Price + + + + Pickup Included + + + + Drop Off Included + + + + Option Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.ts new file mode 100644 index 0000000..fac49f2 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option-search/activity-option-search.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-option-search', + templateUrl: './activity-option-search.component.html', + +}) +export class ActivityOptionSearchComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.html new file mode 100644 index 0000000..b71b1a7 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.html @@ -0,0 +1 @@ +

    activity-option works!

    diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.ts new file mode 100644 index 0000000..c4a66a0 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-option', + templateUrl: './activity-option.component.html', + +}) +export class ActivityOptionComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-option.module.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.module.ts new file mode 100644 index 0000000..f556d86 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-option.module.ts @@ -0,0 +1,78 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { ActivityOptionAddComponent } from './activity-option-add/activity-option-add.component'; +import { ActivityOptionSearchComponent } from './activity-option-search/activity-option-search.component'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { MatMenuModule } from '@angular/material/menu'; + +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { PaginatorModule } from 'primeng/paginator'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; +import { ActivityOptionPolicyComponent } from './activity-option-policy/activity-option-policy.component'; +import { ActivityViewOptionComponent } from './activity-view-option/activity-view-option.component'; +import { ActivityEditOptionComponent } from './activity-edit-option/activity-edit-option.component'; +import { ActivityEditPriceComponent } from './activity-edit-price/activity-edit-price.component'; +import { ActivityEditCancellationPolicyComponent } from './activity-edit-cancellation-policy/activity-edit-cancellation-policy.component'; + +const routes: Routes = [ + { + path: 'Add', + component: ActivityOptionAddComponent, + }, + { + path: 'Search', + component: ActivityOptionSearchComponent, + }, + { + path: 'Policy', + component: ActivityOptionPolicyComponent, + }, + { + path: 'View', + loadChildren: () => import("./activity-view-option/activity-view.module").then((m) => m.ActivityViewModule) + }, + { + path: 'Edit', + component: ActivityEditOptionComponent, + }, + { + path: 'EditPrice', + component: ActivityEditPriceComponent, + }, + { + path: 'EditCancellationPolicy', + component: ActivityEditCancellationPolicyComponent, + }, +] + +@NgModule({ + declarations: [ + ActivityOptionAddComponent, + ActivityOptionSearchComponent, + ActivityOptionPolicyComponent, + ActivityEditOptionComponent, + ActivityViewOptionComponent, + ActivityEditCancellationPolicyComponent, + ActivityEditPriceComponent + + ], + imports: [ + CommonModule, + RouterModule.forChild(routes), + MatCheckboxModule, + NgSelectModule, + TableModule, + ToolbarModule, + MatMenuModule, + PaginatorModule, + CalendarModule, + InputTextModule, + ButtonModule, + ] +}) +export class ActivityOptionModule { } diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.html new file mode 100644 index 0000000..f735706 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.html @@ -0,0 +1,464 @@ + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +

    Rate Config

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Adult (30 to 45)

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Senior (46 to 70)

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Youth (18 to 30)

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Child (3 to 12)

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +

    Transfer Pickup Notes

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.ts new file mode 100644 index 0000000..da59270 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view-option.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-view-option', + templateUrl: './activity-view-option.component.html', + +}) +export class ActivityViewOptionComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view.module.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view.module.ts new file mode 100644 index 0000000..69a19d9 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/activity-view.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { ActivityViewOptionComponent } from './activity-view-option.component'; +import { ViewOptionPolicyComponent } from './view-option-policy/view-option-policy.component'; +import { NgSelectModule } from '@ng-select/ng-select'; + +const routes: Routes = [ + { + path: "", + component: ActivityViewOptionComponent, + }, + { + path: "Policy", + component: ViewOptionPolicyComponent, + }, +] + +@NgModule({ + declarations: [ + ViewOptionPolicyComponent + ], + imports: [ + CommonModule, + RouterModule.forChild(routes), + NgSelectModule, + ] +}) +export class ActivityViewModule { } diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.html b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.html new file mode 100644 index 0000000..4fc4168 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.html @@ -0,0 +1,63 @@ +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Type

    +
    + +
    +
    +
    + type 1 + type 2 +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.ts b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.ts new file mode 100644 index 0000000..4188e1c --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-option/activity-view-option/view-option-policy/view-option-policy.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-view-option-policy', + templateUrl: './view-option-policy.component.html', + +}) +export class ViewOptionPolicyComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.html b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.html new file mode 100644 index 0000000..7386568 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.html @@ -0,0 +1,2424 @@ +
    +
    +
    +

    Overview

    +
    +
    +
    +
    + Hotel-Image +
    +

    Activity name

    + +
    +
    +
    +
    +
    Inventory and Pricing Calendar
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Option Name

    +
    + +
    +
    +
    + Select + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    + + + + + + + + + + + + + + +
    +
    Options
    +
    +
    + Mon + 1 + jul +
    +
    +
    + Tue + 2 + jul +
    +
    +
    + Wed + 3 + jul +
    +
    +
    + Thus + 4 + jul +
    +
    +
    + Fri + 5 + jul +
    +
    +
    + Sat + 6 + jul +
    +
    +
    + sun + 7 + jul +
    +
    +
    + mon + 8 + jul +
    +
    +
    + Tue + 9 + jul +
    +
    +
    + Wed + 10 + jul +
    +
    +
    + Thus + 11 + jul +
    +
    + + + + +
    + Option Name 1 +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    + Allocation +
    +
    +
    + 5 +
    +
    +
    + 20 +
    +
    +
    + Sold Out +
    +
    +
    + 10 +
    +
    +
    + 0 +
    +
    +
    + 50 +
    +
    +
    + 50 +
    +
    +
    + open +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    +
    + Net Sold +
    +
    +
    + 2 +
    +
    +
    + 5 +
    +
    +
    + 3 +
    +
    +
    + 8 +
    +
    +
    + 2 +
    +
    +
    + 23 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 3 +
    +
    +
    + Available +
    +
    +
    + 3 +
    +
    +
    + 15 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 0 +
    +
    +
    + 27 +
    +
    +
    + 48 +
    +
    +
    + 3 +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    + Allocation +
    +
    +
    + 5 +
    +
    +
    + 20 +
    +
    +
    + Sold Out +
    +
    +
    + 10 +
    +
    +
    + 0 +
    +
    +
    + 50 +
    +
    +
    + 50 +
    +
    +
    + open +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    +
    + Net Sold +
    +
    +
    + 2 +
    +
    +
    + 5 +
    +
    +
    + 3 +
    +
    +
    + 8 +
    +
    +
    + 2 +
    +
    +
    + 23 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 3 +
    +
    +
    + Available +
    +
    +
    + 3 +
    +
    +
    + 15 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 0 +
    +
    +
    + 27 +
    +
    +
    + 48 +
    +
    +
    + 3 +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    + Allocation +
    +
    +
    + 5 +
    +
    +
    + 20 +
    +
    +
    + Sold Out +
    +
    +
    + 10 +
    +
    +
    + 0 +
    +
    +
    + 50 +
    +
    +
    + 50 +
    +
    +
    + open +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    +
    + Net Sold +
    +
    +
    + 2 +
    +
    +
    + 5 +
    +
    +
    + 3 +
    +
    +
    + 8 +
    +
    +
    + 2 +
    +
    +
    + 23 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 3 +
    +
    +
    + Available +
    +
    +
    + 3 +
    +
    +
    + 15 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 0 +
    +
    +
    + 27 +
    +
    +
    + 48 +
    +
    +
    + 3 +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    + + + +
    + Option Name 2 +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    + Allocation +
    +
    +
    + 5 +
    +
    +
    + 20 +
    +
    +
    + Sold Out +
    +
    +
    + 10 +
    +
    +
    + 0 +
    +
    +
    + 50 +
    +
    +
    + 50 +
    +
    +
    + open +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    +
    + Net Sold +
    +
    +
    + 2 +
    +
    +
    + 5 +
    +
    +
    + 3 +
    +
    +
    + 8 +
    +
    +
    + 2 +
    +
    +
    + 23 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 3 +
    +
    +
    + Available +
    +
    +
    + 3 +
    +
    +
    + 15 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 0 +
    +
    +
    + 27 +
    +
    +
    + 48 +
    +
    +
    + 3 +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + Sold Out +
    +
    +
    +
    +
    +
    + Allocation +
    +
    +
    + 5 +
    +
    +
    + 20 +
    +
    +
    + Sold Out +
    +
    +
    + 10 +
    +
    +
    + 0 +
    +
    +
    + 50 +
    +
    +
    + 50 +
    +
    +
    + open +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    +
    + Net Sold +
    +
    +
    + 2 +
    +
    +
    + 5 +
    +
    +
    + 3 +
    +
    +
    + 8 +
    +
    +
    + 2 +
    +
    +
    + 23 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 3 +
    +
    +
    + Available +
    +
    +
    + 3 +
    +
    +
    + 15 +
    +
    +
    + 2 +
    +
    +
    + 2 +
    +
    +
    + 0 +
    +
    +
    + 27 +
    +
    +
    + 48 +
    +
    +
    + 3 +
    +
    +
    + 0 +
    +
    +
    + 0 +
    +
    + + +
    +
    +
    +
    +
    Activity Details
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Name + + + + Activity Category + + + + Service Duration + + + + Country + + + + City + + + + Activity Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    Traveler Details
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Min Traveler + + + + Max_Traveler + + + + + + Supported Pax Types + + + + Max Child Allowed + + + + Free Child Allowed + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    Itinerary details
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Default Language + + + + Day Wise Itinerary + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    + +
    +
    Season
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Season Name + + + + Date Renge + + + + Season Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + + Status + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    Slots
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Name + + + + Slot Start Time + + + + Slot End Time + + + + Cut Off Time + + + + Slot Id + + + + Status + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    Activity Option
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Name + + + + Option Name + + + + Date Renge + + + + Currency + + + + Slot Id + + + + Tourist Guide Included + + + + Supported Transfer Type + + + + Transfer Included in Price + + + + Pickup Included + + + + Drop Off Included + + + + Option Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    Allocation
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Name + + + + Slot Time + + + + Allocation Date Range + + + + Slot Name + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + data.status + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.ts b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.ts new file mode 100644 index 0000000..7b65dde --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'activity-overview', + templateUrl: './activity-overview.component.html', + +}) +export class ActivityOverviewComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.module.ts b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.module.ts new file mode 100644 index 0000000..559af4d --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/activity-overview/activity-overview.module.ts @@ -0,0 +1,57 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; + +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { SlotsAddComponent } from '../slots/slots-add/slots-add.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { ToastModule } from 'primeng/toast'; +import { ActivityOverviewComponent } from './activity-overview.component'; + + + +const routes: Routes = [ + { + path:'', + component:ActivityOverviewComponent, + }, + +] + + +@NgModule({ + declarations: [ + ActivityOverviewComponent + ], + imports: [ + CommonModule, + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ] +}) +export class ActivityOverviewModule { } diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.html b/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.html new file mode 100644 index 0000000..28e191f --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.html @@ -0,0 +1,190 @@ + +
    +
    +
    +

    Add Allocation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    Select
    + +
    + + +
    + One + Two +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Specific Dates + Season +
    +
    +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Select
    + +
    + + +
    + One + Two +
    +
    +
    +
    +
    + +
    +
    +
    Select
    + +
    + + +
    + Monday + Tuesday + Wednesday + Thursday +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Allocation Type

    +
    + +
    +
    +
    + Free Sale + + + Count Sale +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.ts b/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.ts new file mode 100644 index 0000000..b7cf485 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-add/allocation-add.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-allocation-add', + templateUrl: './allocation-add.component.html', + +}) +export class AllocationAddComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.html b/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.html new file mode 100644 index 0000000..75f8389 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.html @@ -0,0 +1,412 @@ +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + +
    + +
    +
    + +
    +
    + + + +
    +
    +
    +

    Days

    +
    + +
    +
    + +
    + Monday + Thuesday + Wednesday +
    +
    +
    +
    + +
    + + +
    +
    + + + +
    +
    +

    Allocation

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + 1. Count Sale + 2. Free Sale + 3. Stop Sale +
    +
    +
    +
    + +
    +
    + + + + +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + Allocation Type + +
    +
    +
    + Allocation + +
    +
    +
    + Booked Count +
    +
    +
    + Remaining Count +
    +
    +
    + Release Days + + +
    +
    + 12 Mar 2021 + + Mon + +
    + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + Select + Count Sale + Free Sale + Stop Sale +
    +
    +
    + 10 + + 10 + + 10 + + 10 +
    + 13 Mar 2021 + + Tue + + Count Sale + + 2 + + 2 + + 2 + + 2 +
    + 14 Mar 2021 + + Wed + + Count Sale + + 2 + + 2 + + 2 + + 3 +
    + 15 Mar 2021 + + Thus + + Free Sale + + Free Sale + + 2 + + Free Sale + + Free Sale +
    + 19 Mar 2021 + + Tue + + Count Sale + + 4 + + 2 + + 2 + + 2 +
    + 20 Mar 2021 + + Wed + + Stop Sale + + 5 + + 2 + + 2 + + 2 +
    + 21 Mar 2021 + + Thus + + Count Sale + + 7 + + 10 + + 10 + + 10 +
    + 22 Mar 2021 + + Tue + + Free Sale + + Free Sale + + 2 + + Free Sale + + Free Sale +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.ts b/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.ts new file mode 100644 index 0000000..94db557 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-edit/allocation-edit.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-allocation-edit', + templateUrl: './allocation-edit.component.html', + +}) +export class AllocationEditComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.html b/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.html new file mode 100644 index 0000000..a0cb5c2 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.html @@ -0,0 +1,134 @@ +
    +
    +
    +

    Allocation Search

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Slot Name +

    +
    + +
    +
    +
    + 1 + 2 + 3 +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Name + + + + Slot Time + + + + Allocation Date Range + + + + Slot Name + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.ts b/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.ts new file mode 100644 index 0000000..ece66df --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation-search/allocation-search.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-allocation-search', + templateUrl: './allocation-search.component.html', + +}) +export class AllocationSearchComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation.component.html b/src/app/modules/services/activity/activity-manage/allocation/allocation.component.html new file mode 100644 index 0000000..58cd0b6 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation.component.html @@ -0,0 +1 @@ +

    allocation works!

    diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation.component.ts b/src/app/modules/services/activity/activity-manage/allocation/allocation.component.ts new file mode 100644 index 0000000..7c8053b --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-allocation', + templateUrl: './allocation.component.html', + +}) +export class AllocationComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/allocation/allocation.module.ts b/src/app/modules/services/activity/activity-manage/allocation/allocation.module.ts new file mode 100644 index 0000000..9adadff --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/allocation/allocation.module.ts @@ -0,0 +1,51 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { AllocationAddComponent } from './allocation-add/allocation-add.component'; +import { RouterModule, Routes } from '@angular/router'; +import { AllocationSearchComponent } from './allocation-search/allocation-search.component'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; + +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { PaginatorModule } from 'primeng/paginator'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; +import { AllocationEditComponent } from './allocation-edit/allocation-edit.component'; + +const routes: Routes = [ + { + path: 'Add', + component: AllocationAddComponent, + }, + { + path: 'Search', + component: AllocationSearchComponent, + }, + { + path: 'Edit', + component: AllocationEditComponent, + }, +] + +@NgModule({ + declarations: [ + AllocationAddComponent, + AllocationSearchComponent, + AllocationEditComponent + ], + imports: [ + CommonModule, + RouterModule.forChild(routes), + TableModule, + ToolbarModule, + MatMenuModule, + PaginatorModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ButtonModule, + ] +}) +export class AllocationModule { } diff --git a/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.html b/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.html new file mode 100644 index 0000000..13eae59 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.html @@ -0,0 +1,189 @@ + +
    +
    +
    +

    Manage Translation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Translate To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Default Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Selected Language Content

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Day Wise Itinerary

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Day Wise Itinerary

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.ts b/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.ts new file mode 100644 index 0000000..071b875 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/itinerary/itinerary-language/itinerary-language.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-itinerary-language', + templateUrl: './itinerary-language.component.html', +}) +export class ItineraryLanguageComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.html b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.html new file mode 100644 index 0000000..be20bca --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.html @@ -0,0 +1,522 @@ +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Day Wise Itinerary

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Starting City

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Admission included in price

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Starting City

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Admission included in price

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Inclusions

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Inclusions

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Exclusions

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Id + + + + Default Language + + + + Day Wise Itinerary + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.ts b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.ts new file mode 100644 index 0000000..0f5c3d7 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-itinerary', + templateUrl: './itinerary.component.html', +}) +export class ItineraryComponent { + time: Date[] | undefined; +} diff --git a/src/app/modules/services/activity/activity-manage/itinerary/itinerary.module.ts b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.module.ts new file mode 100644 index 0000000..13d8b61 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/itinerary/itinerary.module.ts @@ -0,0 +1,54 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ItineraryLanguageComponent } from './itinerary-language/itinerary-language.component'; +import { ItineraryComponent } from './itinerary.component'; +import { CalendarModule } from 'primeng/calendar'; + +const routes: Routes = [ + { + path: 'Language', + component:ItineraryLanguageComponent, + }, + { + path: '', + component:ItineraryComponent, + }, +] +@NgModule({ + declarations: [ + ItineraryComponent, + ItineraryLanguageComponent + ], + imports: [ + ToastModule, + TableModule, + DialogModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes), + ], +}) +export class ItineraryModule { } diff --git a/src/app/modules/services/activity/activity-manage/media/media.component.html b/src/app/modules/services/activity/activity-manage/media/media.component.html new file mode 100644 index 0000000..1308a2c --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/media/media.component.html @@ -0,0 +1,114 @@ +
    +
    +
    +

    Add Image

    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Image Category

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Image City

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + Add Images + + +
    + Note: Upload jpeg/png with max file size upto + 500kb. Height + 200px and Width 800px. +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Add Video

    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/media/media.component.ts b/src/app/modules/services/activity/activity-manage/media/media.component.ts new file mode 100644 index 0000000..ba4434c --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/media/media.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-media', + templateUrl: './media.component.html', +}) +export class MediaComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/media/media.module.ts b/src/app/modules/services/activity/activity-manage/media/media.module.ts new file mode 100644 index 0000000..6adc730 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/media/media.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MediaComponent } from './media.component'; + +const routes: Routes = [ + { + path: '', + component:MediaComponent, + }, +] +@NgModule({ + declarations: [MediaComponent], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + MediaComponent + ] +}) +export class MediaModule { } diff --git a/src/app/modules/services/activity/activity-manage/required-info/required-info.component.html b/src/app/modules/services/activity/activity-manage/required-info/required-info.component.html new file mode 100644 index 0000000..7164931 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/required-info/required-info.component.html @@ -0,0 +1,285 @@ +
    +
    +
    +

    Here's what we'll collect automatically:

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    Required Information for All Travelers

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    Personal Details

    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Passport Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Departure Flight Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Arrival Flight Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Departure Ship Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Arrival Ship Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Shore Excursion Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Departure Train Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Arrival Train Details

    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/required-info/required-info.component.ts b/src/app/modules/services/activity/activity-manage/required-info/required-info.component.ts new file mode 100644 index 0000000..3f57101 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/required-info/required-info.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-required-info', + templateUrl: './required-info.component.html', +}) +export class RequiredInfoComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/required-info/required-info.module.ts b/src/app/modules/services/activity/activity-manage/required-info/required-info.module.ts new file mode 100644 index 0000000..b9d1e5f --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/required-info/required-info.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { RequiredInfoComponent } from './required-info.component'; + +const routes: Routes = [ + { + path: '', + component:RequiredInfoComponent, + }, +] +@NgModule({ + declarations: [RequiredInfoComponent], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + RequiredInfoComponent + ] +}) +export class RequiredInfoModule { } diff --git a/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.html b/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.html new file mode 100644 index 0000000..dd5ad35 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.html @@ -0,0 +1,123 @@ + +
    +
    +
    +

    Add Season

    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.ts b/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.ts new file mode 100644 index 0000000..1f8cf41 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season-add/season-add.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-season-add', + templateUrl: './season-add.component.html', +}) +export class SeasonAddComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.html b/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.html new file mode 100644 index 0000000..dd2b8fa --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.html @@ -0,0 +1,116 @@ +
    +
    +
    +

    Season Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Season Name + + + + Date Renge + + + + Season Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + + Status + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.ts b/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.ts new file mode 100644 index 0000000..ccb2f4c --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season-search/season-search.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-season-search', + templateUrl: './season-search.component.html', +}) +export class SeasonSearchComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/season/season.component.ts b/src/app/modules/services/activity/activity-manage/season/season.component.ts new file mode 100644 index 0000000..27405b1 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-season', + templateUrl: './season.component.html', +}) +export class SeasonComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/season/season.module.ts b/src/app/modules/services/activity/activity-manage/season/season.module.ts new file mode 100644 index 0000000..cf26e5f --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/season/season.module.ts @@ -0,0 +1,44 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { PaginatorModule } from 'primeng/paginator'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { SeasonAddComponent } from './season-add/season-add.component'; +import { SeasonSearchComponent } from './season-search/season-search.component'; +import { CalendarModule } from 'primeng/calendar'; + + +const routes: Routes = [ + { + path: 'Search', + component: SeasonSearchComponent, + }, + { + path: 'Add', + component: SeasonAddComponent, + }, +] +@NgModule({ + declarations: [ + SeasonSearchComponent, + SeasonAddComponent, + ], + imports: [ + CommonModule, + TableModule, + ToolbarModule, + MatMenuModule, + PaginatorModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ButtonModule, + RouterModule.forChild(routes) + ] +}) +export class SeasonModule { } diff --git a/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.html b/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.html new file mode 100644 index 0000000..87c2017 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.html @@ -0,0 +1,105 @@ + +
    +
    +
    +

    Add slots

    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    + + + +
    + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.ts b/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.ts new file mode 100644 index 0000000..1fb8bc0 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots-add/slots-add.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-slots-add', + templateUrl: './slots-add.component.html', + +}) +export class SlotsAddComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.html b/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.html new file mode 100644 index 0000000..80f79e5 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.html @@ -0,0 +1,124 @@ +
    +
    +
    +

    Slots Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Slot Name + + + + Slot Start Time + + + + Slot End Time + + + + Cut Off Time + + + + Slot Id + + + + Status + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.ts b/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.ts new file mode 100644 index 0000000..f98a162 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots-search/slots-search.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-slots-search', + templateUrl: './slots-search.component.html', + +}) +export class SlotsSearchComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/slots/slots.component.html b/src/app/modules/services/activity/activity-manage/slots/slots.component.html new file mode 100644 index 0000000..b6b39f4 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots.component.html @@ -0,0 +1 @@ +

    slots works!

    diff --git a/src/app/modules/services/activity/activity-manage/slots/slots.component.ts b/src/app/modules/services/activity/activity-manage/slots/slots.component.ts new file mode 100644 index 0000000..d4646d2 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-slots', + standalone: true, + imports: [], + templateUrl: './slots.component.html', + styleUrl: './slots.component.css' +}) +export class SlotsComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/slots/slots.module.ts b/src/app/modules/services/activity/activity-manage/slots/slots.module.ts new file mode 100644 index 0000000..b29b07e --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/slots/slots.module.ts @@ -0,0 +1,46 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { SlotsAddComponent } from './slots-add/slots-add.component'; +import { SlotsSearchComponent } from './slots-search/slots-search.component'; +import { TableModule } from 'primeng/table'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; + +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { PaginatorModule } from 'primeng/paginator'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; + + +const routes: Routes = [ + { + path:'Add', + component:SlotsAddComponent, + }, + { + path:'Search', + component:SlotsSearchComponent, + }, +] + +@NgModule({ + declarations: [ + SlotsAddComponent, + SlotsSearchComponent + ], + imports: [ + CommonModule, + TableModule, + ToolbarModule, + MatMenuModule, + PaginatorModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ButtonModule, + RouterModule.forChild(routes), + ] +}) +export class SlotsModule { } diff --git a/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.html b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.html new file mode 100644 index 0000000..bbf421b --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.html @@ -0,0 +1,565 @@ +
    +
    +
    +

    Add Traveler Details

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Min Travelers (Per Booking)

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Travelers (Per Booking)

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Age From

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Age To

    +
    + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Age From

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Age To

    +
    + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Age From

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Age To

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Age From

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Age To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Allowed

    +
    + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Max Free Child

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Free Child Age From

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Free Child Age To

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +

    Paid Child (pricing range count)

    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age From

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age From

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age To

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Id + + + + Min Traveler + + + + Max Traveler + + + + Supported Pax Types + + + + Max Child Allowed + + + + Free Child Allowed + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.ts b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.ts new file mode 100644 index 0000000..768fd09 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-travel-details', + templateUrl: './travel-details.component.html', +}) +export class TravelDetailsComponent { + +} diff --git a/src/app/modules/services/activity/activity-manage/travel-details/travel-details.module.ts b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.module.ts new file mode 100644 index 0000000..3d532b4 --- /dev/null +++ b/src/app/modules/services/activity/activity-manage/travel-details/travel-details.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TravelDetailsComponent } from './travel-details.component'; + +const routes: Routes = [ + { + path: '', + component:TravelDetailsComponent, + }, +] +@NgModule({ + declarations: [TravelDetailsComponent], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + TravelDetailsComponent + ] +}) +export class TravelDetailsModule { } diff --git a/src/app/modules/services/activity/activity-search/activity-search.component.html b/src/app/modules/services/activity/activity-search/activity-search.component.html new file mode 100644 index 0000000..33196c3 --- /dev/null +++ b/src/app/modules/services/activity/activity-search/activity-search.component.html @@ -0,0 +1,244 @@ +
    +
    +
    +

    Activity Master Search

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Activity Category

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Pax Type

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Service Duration

    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Activity Name + + + + Activity Category + + + + Country + + + + City + + + + Pax Type + + + + Service Duration + + + + Free Child Allowed + + + + Pickup Included + + + + Drop Off Included + + + + Service Langauge + + + + Status + + + + Activity Id + + + + Activity Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/activity/activity-search/activity-search.component.ts b/src/app/modules/services/activity/activity-search/activity-search.component.ts new file mode 100644 index 0000000..93fbe13 --- /dev/null +++ b/src/app/modules/services/activity/activity-search/activity-search.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity-search', + templateUrl: './activity-search.component.html', +}) +export class ActivitySearchComponent { + +} diff --git a/src/app/modules/services/activity/activity.component.html b/src/app/modules/services/activity/activity.component.html new file mode 100644 index 0000000..781e721 --- /dev/null +++ b/src/app/modules/services/activity/activity.component.html @@ -0,0 +1 @@ +

    activity works!

    diff --git a/src/app/modules/services/activity/activity.component.ts b/src/app/modules/services/activity/activity.component.ts new file mode 100644 index 0000000..dab638b --- /dev/null +++ b/src/app/modules/services/activity/activity.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-activity', + templateUrl: './activity.component.html', +}) +export class ActivityComponent { + +} diff --git a/src/app/modules/services/activity/activity.module.ts b/src/app/modules/services/activity/activity.module.ts new file mode 100644 index 0000000..4eefef2 --- /dev/null +++ b/src/app/modules/services/activity/activity.module.ts @@ -0,0 +1,73 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ActivityAddComponent } from './activity-add/activity-add.component'; +import { ActivitySearchComponent } from './activity-search/activity-search.component'; +import { ActivityComponent } from './activity.component'; +import { ActivityLanguageComponent } from './activity-language/activity-language.component'; + +const routes: Routes = [ + { + path: 'Search', + component:ActivitySearchComponent, + }, + { + path: 'Add', + component:ActivityAddComponent, + }, + { + path: 'Language', + component:ActivityLanguageComponent, + }, + { + path: '', + component:ActivityComponent, + }, + { + path: 'Manage', + loadChildren: () => + import('./activity-manage/activity-manage.module').then( + (m) => m.ActivityManageModule + ), + }, +] +@NgModule({ + declarations: [ + ActivityComponent, + ActivitySearchComponent, + ActivityAddComponent, + ActivityLanguageComponent + ], + imports: [ + ToastModule, + TableModule, + DialogModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes), + ], +}) +export class ActivityModule { } diff --git a/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.html b/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.html new file mode 100644 index 0000000..ec6c239 --- /dev/null +++ b/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.html @@ -0,0 +1,330 @@ + + +
    +
    +
    +

    Flight Inventory Report

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Airline

    +
    + +
    +
    +
    + {{item.airline_name}} + ({{item.airline_code}}) + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Trip Type

    +
    + +
    +
    +
    + Select + One Way + Round Trip +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Origin

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Destination

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    + + + + Please + select from date +
    +
    +
    +
    + + + Please + select to date +
    +
    +
    +
    + + + +
    +
    +
    +

    Cabin Class

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    RBD

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Airline + + + + Flight No. + + + + Trip Type + + + + Origin + + + + Destination + + + + Day + + + + Departure Date + + + + Return Date + + + + RBD + + + + Fare Family Name + + + + Cabin Class + + + + Seats Allocation + + + + Booked Seats + + + + Remaining Seats + + + + Cancelled Seats + + + + PNR + + + + Stop Sale + + + + + + + {{data.validating_airline}} + {{data.flight_no}} + {{data.trip_type}} + {{data.origin}} + {{data.destination}} + {{data.day}} + {{data.departure_date}} + {{data.return_date}} + {{data.rbd}} + {{data.fare_family_name}} + {{data.cabin_class}} + {{data.seat_allocation}} + {{data.seat_booked}} + {{data.seat_remains}} + {{data.seat_cancelled}} + {{data.pnr}} + {{data.is_stop_sale}} + + + + + No data found + + +
    +
    + diff --git a/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.ts b/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.ts new file mode 100644 index 0000000..0d6af27 --- /dev/null +++ b/src/app/modules/services/flight-inventory-report/flight-inventory-report-search/flight-inventory-report-search.component.ts @@ -0,0 +1,132 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; + +@Component({ + selector: 'app-flight-inventory-report-search', + templateUrl: './flight-inventory-report-search.component.html', +}) +export class FlightInventoryReportSearchComponent implements OnInit { + + Formdata: FormGroup; + AirlineList; + FlightAllReport; + constructor( + public ApiServ: API, + public fb: FormBuilder, + public router: Router, + public _commonService: CommonFunctionService, + public _staticService: StaticDataService, + public _flightContractService: FlightContractService, + public validationService: ValidationService + ) { } + + trip_type_list = [ + {key: '', display_name:'Select'}, + {key: 'ONEWAY', display_name:'One way'}, + {key: 'ROUNDTRIP', display_name:'Round Trip'}, + ] + cols: any[]; + ngOnInit(): void { + this.pageSetUp() + } + pageSetUp() { + this.OnInitForm(); + this.cols = [ + { field: 'validating_airline', header: 'Airline' }, + { field: 'flight_no', header: ' Flight No.' }, + { field: 'trip_type', header: ' Trip Type.' }, + { field: "origin", header: 'Origin' }, + { field: 'destination', header: 'Destination' }, + { field: 'departure_date', header: 'Date' }, + { field: 'return_date', header: 'Return Date' }, + { field: 'day', header: 'Day' }, + { field: 'rbd', header: 'RBD' }, + { field: 'fare_family_name', header: 'Fare Family Name' }, + { field: 'cabin_class', header: 'Cabin Class' }, + { field: 'seat_allocation', header: ' Seats Allocation' }, + { field: 'seat_booked', header: 'Booked Seats' }, + { field: 'seat_remains', header: 'Remaining Seats' }, + { field: 'seat_cancelled', header: 'cancelled Seats' }, + { field: 'pnr', header: 'PNR' }, + { field: 'is_stop_sale', header: 'Stop Sale' }, + ]; + }; + plusDate = new Date(new Date().setMonth(new Date().getMonth() + 1)) + OnInitForm() { + this.Formdata = this.fb.group({ + vendor_id: [], + validating_airline: [], + flight_no: [], + trip_type: [], + origin: [], + destination: [], + return_date: [], + from_date: [new Date(), Validators.required], + to_date: [this.plusDate, Validators.required], + rbd: [], + cabin_class: [], + }); + if (this._commonService.clientId == '2109111018200000021') { + this.Formdata.get('trip_type').setValue('ONEWAY'); + } + }; + changeFormDate() { + let max = new Date(this.Formdata.get('to_date').value); + this.plusDate = new Date(this.Formdata.get('from_date').value); + if (this.plusDate > max) { + this.Formdata.get('to_date').setValue(null) + } + }; + ResetForm() { + this.Formdata.reset(); + // remove this when User want + if (this._commonService.clientId == '2109111018200000021') { + this.Formdata.get('trip_type').setValue('ONEWAY'); + } + this.plusDate = new Date(); + }; + GetAllFlightInventory() { + let value = this.Formdata.getRawValue(); + if (this.Formdata.valid) { + let searchobject = { + vendor_id: value.vendor_id ? value.vendor_id : '', + validating_airline: value.validating_airline ? value.validating_airline : '', + flight_no: value.flight_no ? value.flight_no : '', + trip_type: value.trip_type ? value.trip_type : '', + origin: value.origin ? value.origin : '', + destination: value.destination ? value.destination : '', + rbd: value.rbd ? value.rbd : '', + cabin_class: value.cabin_class ? value.cabin_class : '', + return_date: value.return_date ? value.return_date : '', + }; + searchobject['from_date'] = this._commonService.convertDateToSave(value.from_date); + searchobject['to_date'] = this._commonService.convertDateToSave(value.to_date); + this.ApiServ.Post('/FlightContract/GetFlightInventoryReport', searchobject).subscribe(res => { + if (res && res['data']) { + this.FlightAllReport = res['data']; + if (this.FlightAllReport && this.FlightAllReport.length > 0) { + this.FlightAllReport.forEach(e => { + e['is_stop_sale'] = e.is_stop_sale ? 'Yes' : 'No'; + e['departure_date'] = e.departure_date ? this._commonService.convertDateToShow(e.departure_date) : ''; + e['return_date'] = (e.return_date === '0001-01-01T00:00:00Z' || !e.return_date) + ? 'NA' + : this._commonService.UtcToLocaleTime(e.return_date, 'DD MMM YYYY, HH:mm:ss'); + }); + } + } else { + this._commonService.showMessage(res['status'], res['message']); + this.FlightAllReport = []; + } + }); + } else { + this.validationService.showValidationsMsg(this.Formdata); + } + }; + +} diff --git a/src/app/modules/services/flight-inventory-report/flight-inventory-report.module.ts b/src/app/modules/services/flight-inventory-report/flight-inventory-report.module.ts new file mode 100644 index 0000000..fa5d4da --- /dev/null +++ b/src/app/modules/services/flight-inventory-report/flight-inventory-report.module.ts @@ -0,0 +1,57 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Routes, RouterModule } from '@angular/router'; +import { FlightInventoryReportSearchComponent } from './flight-inventory-report-search/flight-inventory-report-search.component'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'primeng/calendar'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TableModule } from 'primeng/table'; +import { MatMenuModule } from '@angular/material/menu'; +import { InputTextModule } from 'primeng/inputtext'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MessageService } from 'primeng/api'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { ButtonModule } from 'primeng/button'; +import { CheckboxModule } from 'primeng/checkbox'; +import { ToastModule } from 'primeng/toast'; +import { TreeModule } from 'primeng/tree'; +import { TreeSelectModule } from 'primeng/treeselect'; +import { TreeTableModule } from 'primeng/treetable'; +import { TriStateCheckboxModule } from 'primeng/tristatecheckbox'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; + +const routes: Routes = [ + { + path: 'Search', + component: FlightInventoryReportSearchComponent, + }, +] + +@NgModule({ + declarations: [ + FlightInventoryReportSearchComponent + ], + imports: [ + TableModule, + CommonModule, + MatMenuModule, + ToolbarModule, + ToastModule, + InputTextModule, + MatCheckboxModule, + TreeModule, + TreeSelectModule, + TreeTableModule, + ButtonModule, + CheckboxModule, + TriStateCheckboxModule, + FormsModule, + NgSelectModule, + MatButtonModule, + ReactiveFormsModule, + CalendarModule, + RouterModule.forChild(routes), + ], providers: [MessageService,FlightContractService], +}) +export class FlightInventoryReportModule { } diff --git a/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.html b/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.html new file mode 100644 index 0000000..dc50de6 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.html @@ -0,0 +1,1589 @@ + + +
    +
    +
    +

    Add Flight Inventory

    +
    +
    +
    +
    +
    +
    + + + Please + enter contract name +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Trip Type

    +
    + +
    +
    +
    + One Way + Round + Trip +
    + Please + select trip type +
    +
    +
    + One-way sale allowed +
    +
    +
    + + + +
    +
    +
    +

    Origin

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    + Please + select origin +
    +
    +
    +
    + + + +
    +
    +
    +

    Destination

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    + Please + select destination +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Currency Code

    +
    + +
    +
    +
    + + + {{item.currency_code}} + +
    + Please + select currency code +
    +
    +
    +
    + + + +
    +
    +
    +

    Confirmation Type

    +
    + +
    +
    + +
    +
    + Please + select confirmation type +
    +
    +
    +
    + + + +
    +
    +
    +

    Contracted Cabins

    +
    + +
    +
    + +
    +
    + Please + select contracted cabins +
    +
    +
    +
    + + + +
    +
    +
    +

    Contracted Pax Types

    +
    + +
    +
    + +
    +
    + Please + select contracted pax types +
    +
    +
    +
    + + + +
    +
    +
    +

    Validating Airline

    +
    + +
    +
    +
    + {{item.airline_name}} + ({{item.airline_code}}) + +
    + Please + select validating airline +
    +
    +
    +
    +
    +
    + Multi Day + Operation + +
    +
    +
    +
    +
    +
    +
    + + + Please + select departure date +
    +
    + + + +
    +
    +
    +

    Multi Day Operation Type

    +
    + +
    +
    + +
    +
    + Please + select multi day operation type + +
    +
    +
    +
    +
    + + + Please + select return date +
    +
    +
    +
    + + + Please + select operation valid from +
    +
    +
    +
    + + + Please + select operation valid to +
    +
    +
    +
    + + + +
    + +
    Departure Days
    +
    + +
    +
    +
    +
    + Please + select departure + days +
    +
    + +
    +
    + + + Please + select departure dates +
    +
    +
    + +
    +
    +
    + Nearby + Airports +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Nearby From Airports

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Nearby To Airports

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Outbound Flight

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Airline Code

    +
    + +
    +
    +
    + {{item.airline_name}} + ({{item.airline_code}}) + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Aircraft Type

    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Origin

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Destination

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + + Next Day Arrival + +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + Departure Next + Day +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Inbound Flight

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Airline Code

    +
    + +
    +
    +
    + {{item.airline_code}} + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Aircraft Type

    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Origin

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Destination

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + + Next Day Arrival + +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + + +
    +
    +
    +

    Hours

    +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +

    Minutes

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + Departure Next Day +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Fare Details

    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Outbound Days

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Fare Family Group

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Cabin Class

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + + +
    +
    +
    +

    Outbound Days

    +
    + +
    +
    + +
    +
    +
    +
    +
    + Apply discount with same VC Only +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + Checked Bag Included +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    check bag unit

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    +

    Cabin Bag Unit

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Refund Type

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +

    Meal Included

    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + Active +
    +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.ts b/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.ts new file mode 100644 index 0000000..cec03da --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-add/flight-inventory-add.component.ts @@ -0,0 +1,1017 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightContractReq, FlightContracts, FlightRateArray } from 'src/app/core/models/flight-service/flight-contracts.model'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; + +@Component({ + selector: 'app-flight-inventory-add', + templateUrl: './flight-inventory-add.component.html', +}) +export class FlightInventoryAddComponent implements OnInit { + allAirpotList = { + fromAirList: [], + toAirList: [], + origin1AirList: [], + origin2AirList: [], + destination1AirList: [], + destination2AirList: [], + }; + allAirCraftList: any; + allAirLineList: any; + IsMobile; + ReturnDateMinDate = new Date(); + allDaysSelected: boolean; + + constructor( + public ApiServ: API, + public Fb: FormBuilder, + private activateRoute: ActivatedRoute, + public validationService: ValidationService, + public _staticService: StaticDataService, + public MsgService: MessageService, + public router: Router, + public _flightContractService: FlightContractService, + public _commonService: CommonFunctionService, + public brkpointsrv: BreakpointsService + ) { + // console.log(brkpointsrv.IsMobile.getValue()) + } + Formdata: FormGroup; + CurrencyList; + AirCabinClassList; + AirPaxTypeList; + lovKeyDataObj = { + AirCabinClass: [], + AirPaxType: [], + AirTripType: [], + DaySelect: [], + AirBaggageUnit: [], + AirFareType: [], + }; + AirportListFrom; + AirportListTO; + AirlineList; + AllAircraftTypeList; + minDate; + // static dropdown value + + MultiDayType = [ + { value: 'RANGE', displayName: 'Range' }, + { value: 'SPECIFICDATES', displayName: 'Specific Dates' }, + ]; + + RefundType = [ + { value: 'Refundale', displayName: 'Refundale' }, + { value: 'Non-Refundale', displayName: 'Non-Refundale' }, + ]; + + staticCurrency = [ + { value: 'INR', displayName: 'Indian Rupees' }, + { value: 'USD', displayName: 'US Dollar' }, + ]; + tripType = [ + { value: 'ONEWAY', displayName: 'One Way' }, + { value: 'ROUNDTRIP', displayName: 'Round Trip' }, + ]; + + FareFamilyList = []; + ngOnInit(): void { + this.OnInitForm(); + this._commonService.GetCurrencyList('ALL'); + this.GetFlightContract() + for (let index = 1; index <= 3; index++) { + this.FareFamilyList.push(index) + }; + const date = new Date(); + const year = date.getFullYear(); + const month = date.getMonth(); + const day = date.getDate(); + this.minDate = new Date(year, month, day); + this.IsMobile = this.brkpointsrv.IsMobile.getValue(); + } + + ToasterMsg(msg) { + this.MsgService.add({ + severity: "error", + detail: msg, + }); + } + + OnInitForm() { + this.Formdata = this.Fb.group({ + contract_name: this.validationService.required, + contract_description: [''], + trip_type: this.validationService.required, + origin: this.validationService.required, + destination: this.validationService.required, + pnr: [''],// pass value on flight rate + currency_code: this.validationService.required, + is_instant_confirmation: ['INSTANT', Validators.required],// pass value on flight rate + contracted_cabin_class: this.validationService.required, + contracted_pax_type: this.validationService.required, + validating_airline: this.validationService.required, + // is_multi_day: [false], + is_nearby_airports: [false], + outbound: this.Fb.array([ + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: this.validationService.required, + to_airport: this.validationService.required, + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: [''], + is_next_day_arrival: [false], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: [''], + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [false], + }) + ]), + inbound: this.Fb.array([]), + FlightsRate: this.Fb.array([ + this.Fb.group({ + rbd: this.validationService.required, + fare_family_group_id: this.validationService.required, + fare_family_name: this.validationService.required, + cabin_class: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + // chd_base_fare: [], + // chd_tax: [], + // inf_base_fare: [], + // inf_tax: [], + + // fare_type_applicability: ['BOTH', Validators.required], + // round_trip_discount_type: [''], + // adult_round_trip_discount: [null], + + seat_allocation: this.validationService.number, + // is_allocation_update_due_cancel: this.validationService.required, + // seat_booked: [], + // seat_remaining: [], + is_checked_bag_included: [false], + is_apply_discount_with_same_vc_only: [false], + adt_check_bag: [{ value: '', disabled: true }], + // chd_check_bag: [], + // inf_check_bag: [], + _check_bag_unit: [{ value: '', disabled: true }], + adt_cabin_bag: this.validationService.required, + _cabin_bag_unit: this.validationService.required, + refund_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + // chd_fare_rule: [], + // inf_fare_rule: [], + is_meal_included: this.validationService.required, + meal_details: [{ value: '', disabled: true }], + inclusions: [], + }) + ]), + is_active: [false] + }); + if(this._commonService.clientId == '2109111018200000021') { + this.Formdata.get('trip_type').setValue('ONEWAY'); + this.UpdateTripType(); + } + this.Formdata.get('contracted_pax_type').setValue(['A']); + this.UpdateMultiDayOperation(); + }; + + get inbound() { + return this.Formdata.get('inbound') as FormArray; + } + get outbound() { + return this.Formdata.get('outbound') as FormArray; + } + get FlightsRate() { + return this.Formdata.get('FlightsRate') as FormArray; + } + get FlightRateDetail() { + return this.Formdata.get('FlightRateDetail') as FormArray; + } + + addFlightGroupBtn(check) { + let formgroup = check ? this.inbound : this.outbound + formgroup.push( + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: this.validationService.required, + to_airport: this.validationService.required, + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: [''], + is_next_day_arrival: [false], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: [''], + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [false], + }) + ); + }; + addFlightsRateGroupBtn() { + this.FlightsRate.push( + this.Fb.group({ + rbd: this.validationService.required, + fare_family_group_id: this.validationService.required, + fare_family_name: this.validationService.required, + cabin_class: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + seat_allocation: this.validationService.number, + is_checked_bag_included: [false], + is_apply_discount_with_same_vc_only: [false], + adt_check_bag: [{ value: '', disabled: true }], + _check_bag_unit: [{ value: '', disabled: true }], + adt_cabin_bag: this.validationService.required, + _cabin_bag_unit: this.validationService.required, + refund_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + is_meal_included: this.validationService.required, + meal_details: [], + inclusions: [], + }) + ); + this.AddUpdatePaxWiseControls(); + this.UpdateFlightsRateFormGroup(); + }; + AddUpdatePaxWiseControls() { + let val = this.Formdata.get('contracted_pax_type').value; + let grp = this.FlightsRate.controls[this.FlightsRate.controls.length - 1]; + if (val?.includes('C')) this.UpdatePaxWiseControls(grp, 'chd', true); + if (val?.includes('I')) this.UpdatePaxWiseControls(grp, 'inf', true); + }; + + UpdateAllPaxWiseControls() { + let val = this.Formdata.get('contracted_pax_type').value; + this.FlightsRate.controls.forEach(e => { + val.includes('C') ? this.UpdatePaxWiseControls(e, 'chd', true) : this.UpdatePaxWiseControls(e, 'chd', false); + val.includes('I') ? this.UpdatePaxWiseControls(e, 'inf', true) : this.UpdatePaxWiseControls(e, 'inf', false); + }); + }; + UpdatePaxWiseControls(group, name, check) { + let grp = group as FormGroup; + let discountName = name == 'chd' ? 'child' : 'infant'; + let trip_type = this.Formdata.controls['trip_type'].value; + if (check) { + grp.addControl(name + '_base_fare', this.validationService.decimal); + grp.addControl(name + '_tax', this.validationService.decimal); + grp.addControl(name + '_check_bag', this.Fb.control({ value: null, disabled: true })); + grp.addControl(name + '_cabin_bag', this.validationService.required); + grp.addControl(name + '_fare_rule', this.validationService.required); + trip_type == 'ONEWAY' ? grp.addControl(discountName + '_round_trip_discount', this.Fb.control(null)) : ''; + } else { + grp.removeControl(name + '_base_fare'); + grp.removeControl(name + '_tax'); + grp.removeControl(name + '_check_bag'); + grp.removeControl(name + '_cabin_bag'); + grp.removeControl(name + '_fare_rule'); + grp.removeControl(discountName + '_round_trip_discount'); + } + this.UpdateBag(grp) + }; + + removeFlightGroupBtn(ind, check) { + let formgroup = check ? this.inbound : this.outbound + formgroup.removeAt(ind); + }; + + removeFlightsRateGroupBtn(ind) { + this.FlightsRate.removeAt(ind); + }; + RemoveFlightrRoundArr() { + this.Formdata.removeControl('FlightRateDetail'); + }; + plusDate = new Date() + changeFormDate() { + let max = new Date(this.Formdata.get('operation_to').value); + this.plusDate = new Date(this.Formdata.get('operation_from').value); + if (this.plusDate > max) { + this.Formdata.get('operation_to').setValue(null); + } + }; + UpdateBag(grp) { + let group = grp as FormGroup; + let controls = [ + 'adt_check_bag', + 'chd_check_bag', + 'inf_check_bag', + '_check_bag_unit', + // 'adt_cabin_bag', + // 'chd_cabin_bag', + // 'inf_cabin_bag', + // '_cabin_bag_unit', + ]; + if (group.get('is_checked_bag_included').value) controls.forEach(e => this.UpdateControlsValidation(group, e, 'add')); + else controls.forEach(e => this.UpdateControlsValidation(group, e, 'remove')); + if (group.get('is_checked_bag_included').value) controls.forEach(e => group.get(e)?.enable()); + else { + controls.forEach(e => { + group.get(e)?.disable(); + group.get(e)?.setValue(''); + }); + } + }; + UpdateMealTypeIncluded(grp) { + let group = grp as FormGroup; + if (group.get('is_meal_included').value == 'Yes') { + this.UpdateControlsValidation(group, 'meal_details', 'add'); + group.get('meal_details').enable() + } + else { + group.get('meal_details').disable(); + group.get('meal_details').setValue(''); + this.UpdateControlsValidation(group, 'meal_details', 'remove'); + } + }; + + UpdateControlsValidation(group, name, type) { + if (type == 'add') { + group.get(name)?.addValidators([Validators.required]); + group.get(name)?.updateValueAndValidity(); + } else { + group.get(name)?.clearValidators(); + group.get(name)?.updateValueAndValidity(); + group.get(name)?.markAsUntouched(); + }; + }; + + UpdateNearByAirport() { + let val = this.Formdata.get('is_nearby_airports').value; + if (val) { + this.Formdata.addControl('nearby_from_airports', this.Fb.control([])); + this.Formdata.addControl('nearby_to_airports', this.Fb.control([])); + } else { + this.Formdata.removeControl('nearby_from_airports'); + this.Formdata.removeControl('nearby_to_airports'); + } + }; + // UpdateNextDayArrivelcheck(grp) { + // let group = grp as FormGroup; + // let controls = [ + // 'arrival_hour', + // 'arrival_minutes', + // 'arrival_terminal', + // 'flying_duration_hour', + // 'flying_duration_minutes', + // ]; + // if (group.get('is_next_day_arrival').value) controls.forEach(e => this.UpdateControlsValidation(group, e, 'add')); + // else controls.forEach(e => this.UpdateControlsValidation(group, e, 'remove')); + // }; + + // Save + saveData() { + let value = this.Formdata.getRawValue(); + if (this.Formdata.status == "INVALID") { + this.validationService.showValidationsMsg(this.Formdata); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + if (value?.trip_type == 'ONEWAY' && value?.origin == value?.destination) { + this.ToasterMsg('origin airports and destination airports cannot be same in one way'); + return + } + // Out Bond + let FlightoutboundList = this.outbound.getRawValue(); + let outboundlastNumber = FlightoutboundList.length - 1; + if (!FlightoutboundList[outboundlastNumber].to_airport && !value.origin && !value.destination && !FlightoutboundList[0].from_airport) { + this.ToasterMsg("(Outbound) Please enter departure and arrival city or airport") + return; + } + if (JSON.stringify(FlightoutboundList[outboundlastNumber].to_airport) != JSON.stringify(value.destination) || JSON.stringify(FlightoutboundList[0].from_airport) != JSON.stringify(value.origin)) { + this.ToasterMsg("(Outbound) Departure must be different from arrival") + return; + }; + let Duplicate = false; + FlightoutboundList.forEach((e, index) => { + const duplicateIndex = FlightoutboundList.findIndex((item, i) => { + return i !== index && item.from_airport === e.from_airport && item.to_airport === e.to_airport; + }); + if (duplicateIndex !== -1) { + Duplicate = true; + } + }); + if (Duplicate) { + this.ToasterMsg('(Outbound) Duplicate flight details found for the same origin and destination airports.'); + return + } + // + + // In bound + let FlightinboundList = this.inbound.getRawValue(); + if (value?.trip_type == 'ROUNDTRIP') { + let inboundlastNumber = FlightinboundList.length - 1; + if (!FlightinboundList[inboundlastNumber].to_airport && !value.origin && !value.destination && !FlightinboundList[0].from_airport) { + this.ToasterMsg("(Inbound) Please enter departure and arrival city or airport") + return; + } + if (JSON.stringify(FlightinboundList[inboundlastNumber].to_airport) != JSON.stringify(value.origin) || JSON.stringify(FlightinboundList[0].from_airport) != JSON.stringify(value.destination)) { + this.ToasterMsg("(Inbound) Departure must be different from arrival") + return; + }; + Duplicate = false; + FlightinboundList.forEach((e, index) => { + const duplicateIndex = FlightinboundList.findIndex((item, i) => { + return i !== index && item.from_airport === e.from_airport && item.to_airport === e.to_airport; + }); + if (duplicateIndex !== -1) { + Duplicate = true; + } + }); + if (Duplicate) { + this.ToasterMsg('(Inbound) Duplicate flight details found for the same origin and destination airports.'); + return + } + } + let FlightRateVal = this.FlightsRate.getRawValue(); + let AllFlightDetailslist = []; + /// flight details + FlightoutboundList.forEach((e, i) => { + let obj = { + airline_code: e.airline_code, + flight_no: e.flight_no, + aircraft_type_id: e._aircraft_type, + from_airport: e.from_airport ? e.from_airport : "", + to_airport: e.to_airport ? e.to_airport : "", + departure_time: e.departure_Hour + ':' + e.departure_minutes + ':00', + is_next_day_departure: e.is_next_day_departure, + departure_terminal: e.departure_terminal, + is_next_day_arrival: e.is_next_day_arrival, + arrival_time: e.arrival_hour + ':' + e.arrival_minutes + ':00', + arrival_terminal: e.arrival_terminal, + flying_duration: e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00', + leg_nbr: i + 1, + seg_nbr: 1, + } + AllFlightDetailslist.push(obj); + }); + + FlightinboundList.forEach((e, i) => { + let obj = { + airline_code: e.airline_code, + flight_no: e.flight_no, + aircraft_type_id: e._aircraft_type, + from_airport: e.from_airport ? e.from_airport : "", + to_airport: e.to_airport ? e.to_airport : "", + departure_time: e.departure_Hour + ':' + e.departure_minutes + ':00', + is_next_day_departure: e.is_next_day_departure, + departure_terminal: e.departure_terminal, + is_next_day_arrival: e.is_next_day_arrival, + arrival_time: e.arrival_hour + ':' + e.arrival_minutes + ':00', + arrival_terminal: e.arrival_terminal, + flying_duration: e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00', + leg_nbr: i + 1, + seg_nbr: 2, + } + AllFlightDetailslist.push(obj); + }); + + // flight Rate + let FlightRate = [] + FlightRateVal.forEach(e => { + let Ratepostdata = new FlightRateArray(); + Ratepostdata.contract_id = e?.contract_id; + Ratepostdata.rbd = e?.rbd; + Ratepostdata.fare_family_group_id = e?.fare_family_group_id.toString(); + Ratepostdata.fare_family_name = e?.fare_family_name; + Ratepostdata.cabin_class = e?.cabin_class; + Ratepostdata.adt_base_fare = e?.adt_base_fare ? parseFloat(e?.adt_base_fare) : 0; + Ratepostdata.adt_tax = e?.adt_tax ? parseFloat(e?.adt_tax) : 0; + Ratepostdata.chd_base_fare = e?.chd_base_fare ? parseFloat(e?.chd_base_fare) : 0; + Ratepostdata.chd_tax = e?.chd_tax ? parseFloat(e?.chd_tax) : 0; + Ratepostdata.inf_base_fare = e?.inf_base_fare ? parseFloat(e?.inf_base_fare) : 0; + Ratepostdata.inf_tax = e?.inf_tax ? parseFloat(e?.inf_tax) : 0; + Ratepostdata.round_trip_discount_type = e?.round_trip_discount_type; + Ratepostdata.is_apply_discount_with_same_vc_only = e?.is_apply_discount_with_same_vc_only; + Ratepostdata.adult_round_trip_discount = e?.adult_round_trip_discount ? e?.adult_round_trip_discount : 0; + Ratepostdata.child_round_trip_discount = e?.child_round_trip_discount ? e?.child_round_trip_discount : 0; + Ratepostdata.infant_round_trip_discount = e?.infant_round_trip_discount ? e?.infant_round_trip_discount : 0; + Ratepostdata.seat_allocation = e?.seat_allocation ? parseFloat(e?.seat_allocation) : 0; + Ratepostdata.seat_booked = 0; + Ratepostdata.seat_cancelled = 0; + Ratepostdata.is_checked_bag_included = e?.is_checked_bag_included; + Ratepostdata.adt_check_bag = e?.adt_check_bag; + Ratepostdata.chd_check_bag = e?.chd_check_bag; + Ratepostdata.inf_check_bag = e?.inf_check_bag; + Ratepostdata._check_bag_unit = e?._check_bag_unit; + Ratepostdata.adt_cabin_bag = e?.adt_cabin_bag; + Ratepostdata.chd_cabin_bag = e?.chd_cabin_bag; + Ratepostdata.inf_cabin_bag = e?.inf_cabin_bag; + Ratepostdata._cabin_bag_unit = e?._cabin_bag_unit; + Ratepostdata.refund_type = e?.refund_type; + Ratepostdata.adt_fare_rule = e?.adt_fare_rule; + Ratepostdata.chd_fare_rule = e?.chd_fare_rule; + Ratepostdata.inf_fare_rule = e?.inf_fare_rule; + Ratepostdata.is_meal_included = e?.is_meal_included == 'Yes'; + Ratepostdata.meal_details = e?.meal_details; + Ratepostdata.inclusions = e?.inclusions; + Ratepostdata.pnr = value.pnr; + FlightRate.push(Ratepostdata) + }) + // Flight Contracts + let PostData = new FlightContracts(); + PostData.contract_name = value?.contract_name; + PostData.is_active = value?.is_active; + PostData.contract_description = value?.contract_description; + PostData.trip_type = value?.trip_type; + PostData.is_oneway_sale_allowed = value?.is_oneway_sale_allowed ? value?.is_oneway_sale_allowed : false; + PostData.origin = value?.origin + PostData.destination = value?.destination + PostData.no_of_legs = AllFlightDetailslist.length; + PostData.currency_code = value?.currency_code; + PostData.is_instant_confirmation = value.is_instant_confirmation == 'INSTANT'; + PostData.contracted_cabin_class = value?.contracted_cabin_class ? value?.contracted_cabin_class.join(',') : ''; + PostData.contracted_pax_type = value?.contracted_pax_type ? value?.contracted_pax_type.join(',') : ''; + PostData.validating_airline = value?.validating_airline; + PostData.is_multi_day = value?.is_multi_day ? value?.is_multi_day : false; + PostData.multi_day_operation_type = value?.multi_day_operation_type ? value?.multi_day_operation_type : ''; + if (value?.operation_from) PostData.operation_from = value?.operation_from ? this._commonService.convertDateToSave(value?.operation_from) : ''; + if (value?.operation_to) PostData.operation_to = value?.operation_to ? this._commonService.convertDateToSave(value?.operation_to) : ''; + if (value?.departure_dates) { + let departureDateList = []; + value.departure_dates.forEach(e => departureDateList.push(this._commonService.convertDateToSaveWithoutTime(e))) + PostData.departure_dates = departureDateList.length > 0 ? departureDateList.join(',') : ''; + } + if (value?.departure_days) PostData.departure_days = value?.departure_days.join(','); + if (value?.departure_date) PostData.departure_date = this._commonService.convertDateToSave(value?.departure_date); + if (value?.return_date) PostData.return_date = this._commonService.convertDateToSave(value?.return_date); + PostData.is_nearby_airports = value?.is_nearby_airports; + PostData.nearby_from_airports = value?.nearby_from_airports && value?.nearby_from_airports.length > 0 ? value?.nearby_from_airports.join(',') : ''; + PostData.nearby_to_airports = value?.nearby_to_airports && value?.nearby_to_airports.length > 0 ? value?.nearby_to_airports.join(',') : ''; + let requestform = new FlightContractReq(); + requestform.FlightContract = PostData; + requestform.FlightDetails = AllFlightDetailslist; + requestform.FlightRates = FlightRate; + this.ApiServ.Post('/FlightContract/SaveFlightContract', requestform).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + setTimeout(() => { + if (res['status']) this.router.navigate(['/Services/FlightInventory/Search']); + }, 500); + } + }); + + }; + + preventDefaultRemoval(value) { + let array = this.Formdata.get('contracted_pax_type').value + if (!array.includes(value)) { + this.Formdata.get('contracted_pax_type').setValue([value, ...array]) + } + }; + UpdateMultiDayOperation() { + let val = this.Formdata.get('is_multi_day')?.value; + if (val) { + this.Formdata.removeControl('departure_date'); + this.Formdata.addControl('multi_day_operation_type', this.validationService.required); + } else { + this.Formdata.removeControl('multi_day_operation_type'); + this.Formdata.removeControl('operation_from'); + this.Formdata.removeControl('operation_to'); + this.Formdata.removeControl('departure_dates'); + this.Formdata.removeControl('departure_days'); + this.Formdata.addControl('departure_date', this.validationService.required); + } + }; + UpdateFareType(group) { + let grpcontrols = group as FormGroup; + let val = grpcontrols.get('fare_type_applicability').value; + if (val == 'BOTH' || val == 'ROUNDTRIP') { + grpcontrols.get('round_trip_discount_type')?.enable(); + grpcontrols.get('adult_round_trip_discount')?.enable(); + grpcontrols.get('child_round_trip_discount')?.enable(); + grpcontrols.get('infant_round_trip_discount')?.enable(); + } else { + grpcontrols.get('round_trip_discount_type')?.disable(); + grpcontrols.get('adult_round_trip_discount')?.disable(); + grpcontrols.get('child_round_trip_discount')?.disable(); + grpcontrols.get('infant_round_trip_discount')?.disable(); + grpcontrols.get('round_trip_discount_type')?.setValue(''); + grpcontrols.get('adult_round_trip_discount')?.setValue(''); + grpcontrols.get('child_round_trip_discount')?.setValue(''); + grpcontrols.get('infant_round_trip_discount')?.setValue(''); + } + }; + + UpdateMultiDayOperationType() { + let val = this.Formdata.get('multi_day_operation_type')?.value; + if (val == 'RANGE') { + this.Formdata.addControl('operation_from', this.validationService.required); + this.Formdata.addControl('operation_to', this.validationService.required); + this.Formdata.addControl('departure_days', this.validationService.required); + this.Formdata.removeControl('departure_dates'); + } else if (val == 'SPECIFICDATES') { + this.Formdata.addControl('departure_dates', this.validationService.required); + this.Formdata.removeControl('departure_days'); + this.Formdata.removeControl('operation_from'); + this.Formdata.removeControl('operation_to'); + } else { + this.Formdata.removeControl('departure_days'); + this.Formdata.removeControl('operation_from'); + this.Formdata.removeControl('operation_to'); + this.Formdata.removeControl('departure_dates'); + } + }; + AllSelectedCabinClass = [] + ContractedCabins() { + let val = this.Formdata.controls['contracted_cabin_class'].value; + if (val && val.length > 0) { + let string = val.join(','); + this.AllSelectedCabinClass = this._staticService.CabinsClassType.filter(e => string.includes(e.value)); + this.FlightsRate.controls.forEach(e => { + if (e.get('cabin_class').value && !string.includes(e.get('cabin_class').value)) e.get('cabin_class').setValue(''); + }) + } else { + this.AllSelectedCabinClass = []; + } + }; + + UpdateTripType() { + let val = this.Formdata.controls['trip_type'].value; + if (val == 'ONEWAY') { + this.UpdateALLFlightsRateFormGroup(true); + this.Formdata.addControl('is_multi_day', this.Fb.control(false)); + this.Formdata.removeControl('return_date'); + this.Formdata.removeControl('is_oneway_sale_allowed'); + this.inbound.clear(); + } + else if (val == 'ROUNDTRIP') { + this.UpdateALLFlightsRateFormGroup(false); + this.UpdateDepartureDate(false); + this.addFlightGroupBtn(true); + this.Formdata.addControl('is_oneway_sale_allowed', this.Fb.control(false)); + this.Formdata.addControl('return_date', this.validationService.required); + this.Formdata.removeControl('is_multi_day'); + } else { + this.UpdateALLFlightsRateFormGroup(false); + this.Formdata.removeControl('is_multi_day'); + this.Formdata.removeControl('return_date'); + this.Formdata.removeControl('is_oneway_sale_allowed'); + this.inbound.clear(); + } + this.AddUpdatePaxWiseControls(); + this.UpdateMultiDayOperation(); + } + UpdateDepartureDate(check) { + let val = this.Formdata.controls['departure_date']?.value; + if (val) { + if (check && this.Formdata.controls['return_date']?.value && new Date(val) > new Date(this.Formdata.controls['return_date'].value)) { + this.Formdata.controls['return_date'].setValue(new Date(val)); + } + this.ReturnDateMinDate = val; + } else { + this.ReturnDateMinDate = new Date() + } + }; + + UpdateALLFlightsRateFormGroup(check) { + this.FlightsRate.controls.forEach((e, index) => { + if (e) { + let formgroup = e as FormGroup; + if (check) { + formgroup.addControl('round_trip_discount_type', this.Fb.control(null)); + formgroup.addControl('adult_round_trip_discount', this.Fb.control(null)); + } else { + formgroup.removeControl('round_trip_discount_type'); + formgroup.removeControl('adult_round_trip_discount'); + formgroup.removeControl('child_round_trip_discount'); + formgroup.removeControl('infant_round_trip_discount'); + } + } + }) + }; + UpdateFlightsRateFormGroup() { + let val = this.Formdata.controls['trip_type'].value; + let grp = this.FlightsRate.controls[this.FlightsRate.controls.length - 1] as FormGroup; + if (val == 'ONEWAY') { + grp.addControl('round_trip_discount_type', this.Fb.control(null)); + grp.addControl('adult_round_trip_discount', this.Fb.control(null)); + } else { + grp.removeControl('round_trip_discount_type'); + grp.removeControl('adult_round_trip_discount'); + grp.removeControl('child_round_trip_discount'); + grp.removeControl('infant_round_trip_discount'); + } + }; + Editid; + AllSelectedAirports = []; + AllSelectedAircraft = []; + AllSelectedAirline = []; + GetFlightContract() { + this.Editid = this.activateRoute.snapshot.paramMap.get('RuleId'); + if (this.Editid) { + this.ApiServ.Get('/FlightContract/CloneGetFlightContractByID/' + this.Editid).subscribe(res => { + if (res) { + this.SetValue(res.data); + this.GetAllAirData(res.data); + } + }) + } + }; + SetValue(data) { + this.SetValueFlightContract(data.FlightContract); + this.SetValueFlightDetails(data.FlightDetails); + this.SetValueFlightRates(data.FlightRates); + }; + SetValueFlightContract(data) { + console.log(data); + this.Formdata.get('contract_name')?.setValue(data?.contract_name); + this.Formdata.get('is_active')?.setValue(data?.is_active); + this.Formdata.get('contract_description')?.setValue(data?.contract_description); + this.Formdata.get('trip_type')?.setValue(data?.trip_type); + this.UpdateTripType(); + this.Formdata.get('is_oneway_sale_allowed')?.setValue(data?.is_oneway_sale_allowed); + this.Formdata.get('origin')?.setValue(data?.origin); + this.Formdata.get('destination')?.setValue(data?.destination); + this.Formdata.get('no_of_legs')?.setValue(data?.no_of_legs); + this.Formdata.get('currency_code')?.setValue(data?.currency_code); + this.Formdata.get('is_instant_confirmation')?.setValue(data?.is_instant_confirmation ? 'INSTANT' : 'MANUAL'); + this.Formdata.get('contracted_cabin_class')?.setValue(data?.contracted_cabin_class ? data?.contracted_cabin_class.split(',') : []); + this.ContractedCabins(); + this.Formdata.get('contracted_pax_type')?.setValue(data?.contracted_pax_type ? data?.contracted_pax_type.split(',') : []); + this.UpdateAllPaxWiseControls(); + this.Formdata.get('validating_airline')?.setValue(data?.validating_airline); + this.Formdata.get('is_multi_day')?.setValue(data?.is_multi_day); + this.UpdateMultiDayOperation(); + this.Formdata.get('multi_day_operation_type')?.setValue(data?.multi_day_operation_type); + this.UpdateMultiDayOperationType(); + this.Formdata.get('operation_from')?.setValue(null); + this.Formdata.get('operation_to')?.setValue(null); + this.Formdata.get('departure_date')?.setValue(null); + this.Formdata.get('return_date')?.setValue(null); + this.Formdata.get('departure_dates')?.setValue(null) + // if (data.departure_dates && this.Formdata.get('departure_dates')) { + // let allDate = data.departure_dates.split(','); + // if (allDate && allDate.length > 0) { + // this.Formdata.get('departure_dates').setValue(allDate.map(e => new Date(e))) + // } + // }; + // this.Formdata.get('departure_date')?.setValue(data?.departure_date ? new Date(data.departure_date) : null); + // this.Formdata.get('return_date')?.setValue(data?.return_date ? new Date(data.return_date) : null); + this.Formdata.get('departure_days')?.setValue(data?.departure_days.split(',')); + this.Formdata.get('is_nearby_airports')?.setValue(data?.is_nearby_airports); + this.UpdateNearByAirport(); + this.Formdata.get('nearby_from_airports')?.setValue(data?.nearby_from_airports.split(',')); + this.Formdata.get('nearby_to_airports')?.setValue(data?.nearby_to_airports.split(',')); + } + SetValueFlightDetails(data) { + console.log(data); + let outbondlist = data.filter(e => e.seg_nbr == 1).sort((a, b) => a.leg_nbr - b.leg_nbr); + outbondlist.forEach((e, i) => { + if (i != 0) this.addFlightGroupBtn(false); + this.outbound.controls[i]?.get('airline_code')?.setValue(e.airline_code); + this.outbound.controls[i]?.get('flight_no')?.setValue(e.flight_no); + this.outbound.controls[i]?.get('_aircraft_type')?.setValue(e.aircraft_type_id); + this.outbound.controls[i]?.get('from_airport')?.setValue(e.from_airport); + this.outbound.controls[i]?.get('to_airport')?.setValue(e.to_airport); + this.outbound.controls[i]?.get('is_next_day_departure')?.setValue(e.is_next_day_departure); + this.outbound.controls[i]?.get('departure_terminal')?.setValue(e.departure_terminal); + this.outbound.controls[i]?.get('is_next_day_arrival')?.setValue(e.is_next_day_arrival); + this.outbound.controls[i]?.get('arrival_terminal')?.setValue(e.arrival_terminal); + if (e.departure_time) { + this.outbound.controls[i]?.get('departure_Hour')?.setValue(e.departure_time.split(':')[0]); + this.outbound.controls[i]?.get('departure_minutes')?.setValue(e.departure_time.split(':')[1]); + } + if (e.arrival_time) { + this.outbound.controls[i]?.get('arrival_hour')?.setValue(e.arrival_time.split(':')[0]); + this.outbound.controls[i]?.get('arrival_minutes')?.setValue(e.arrival_time.split(':')[1]); + } + if (e.flying_duration) { + this.outbound.controls[i]?.get('flying_duration_hour')?.setValue(e.flying_duration.split(':')[0]); + this.outbound.controls[i]?.get('flying_duration_minutes')?.setValue(e.flying_duration.split(':')[1]); + } + }) + let inbondlist = data.filter(e => e.seg_nbr == 2); + if (inbondlist && inbondlist.length > 0) { + inbondlist = inbondlist.sort((a, b) => a.leg_nbr - b.leg_nbr); + inbondlist.forEach((e, i) => { + if (i != 0) this.addFlightGroupBtn(true); + this.inbound.controls[i]?.get('airline_code')?.setValue(e.airline_code); + this.inbound.controls[i]?.get('flight_no')?.setValue(e.flight_no); + this.inbound.controls[i]?.get('_aircraft_type')?.setValue(e.aircraft_type_id); + this.inbound.controls[i]?.get('from_airport')?.setValue(e.from_airport); + this.inbound.controls[i]?.get('to_airport')?.setValue(e.to_airport); + this.inbound.controls[i]?.get('is_next_day_departure')?.setValue(e.is_next_day_departure); + this.inbound.controls[i]?.get('departure_terminal')?.setValue(e.departure_terminal); + this.inbound.controls[i]?.get('is_next_day_arrival')?.setValue(e.is_next_day_arrival); + this.inbound.controls[i]?.get('arrival_terminal')?.setValue(e.arrival_terminal); + if (e.departure_time) { + this.inbound.controls[i]?.get('departure_Hour')?.setValue(e.departure_time.split(':')[0]); + this.inbound.controls[i]?.get('departure_minutes')?.setValue(e.departure_time.split(':')[1]); + } + if (e.arrival_time) { + this.inbound.controls[i]?.get('arrival_hour')?.setValue(e.arrival_time.split(':')[0]); + this.inbound.controls[i]?.get('arrival_minutes')?.setValue(e.arrival_time.split(':')[1]); + } + if (e.flying_duration) { + this.inbound.controls[i]?.get('flying_duration_hour')?.setValue(e.flying_duration.split(':')[0]); + this.inbound.controls[i]?.get('flying_duration_minutes')?.setValue(e.flying_duration.split(':')[1]); + } + }) + } + }; + // don't remove this code + SetValueFlightRates(data, iscopyUi?) { + console.log(data); + data.forEach((e, i) => { + if (iscopyUi) { + e = data[0]; + } else { + if (i != 0) this.addFlightsRateGroupBtn(); + } + this.FlightsRate.controls[i].get('rbd')?.setValue(e?.rbd) + this.FlightsRate.controls[i].get('fare_family_group_id')?.setValue(e?.fare_family_group_id); + this.FlightsRate.controls[i].get('fare_family_name')?.setValue(e?.fare_family_name); + this.FlightsRate.controls[i].get('cabin_class')?.setValue(e?.cabin_class); + this.FlightsRate.controls[i].get('adt_base_fare')?.setValue(e?.adt_base_fare); + this.FlightsRate.controls[i].get('adt_tax')?.setValue(e?.adt_tax); + this.FlightsRate.controls[i].get('chd_base_fare')?.setValue(e?.chd_base_fare); + this.FlightsRate.controls[i].get('chd_tax')?.setValue(e?.chd_tax); + this.FlightsRate.controls[i].get('inf_base_fare')?.setValue(e?.inf_base_fare); + this.FlightsRate.controls[i].get('inf_tax')?.setValue(e?.inf_tax); + this.FlightsRate.controls[i].get('round_trip_discount_type')?.setValue(e?.round_trip_discount_type); + this.FlightsRate.controls[i].get('is_apply_discount_with_same_vc_only')?.setValue(e?.is_apply_discount_with_same_vc_only); + this.FlightsRate.controls[i].get('adult_round_trip_discount')?.setValue(e?.adult_round_trip_discount); + this.FlightsRate.controls[i].get('child_round_trip_discount')?.setValue(e?.child_round_trip_discount); + this.FlightsRate.controls[i].get('infant_round_trip_discount')?.setValue(e?.infant_round_trip_discount); + this.FlightsRate.controls[i].get('seat_allocation')?.setValue(e?.seat_allocation) + this.FlightsRate.controls[i].get('is_checked_bag_included')?.setValue(e?.is_checked_bag_included); + this.UpdateBag(this.FlightsRate.controls[i]) + this.FlightsRate.controls[i].get('adt_check_bag')?.setValue(e?.adt_check_bag); + this.FlightsRate.controls[i].get('chd_check_bag')?.setValue(e?.chd_check_bag); + this.FlightsRate.controls[i].get('inf_check_bag')?.setValue(e?.inf_check_bag); + this.FlightsRate.controls[i].get('_check_bag_unit')?.setValue(e?._check_bag_unit); + this.FlightsRate.controls[i].get('adt_cabin_bag')?.setValue(e?.adt_cabin_bag); + this.FlightsRate.controls[i].get('chd_cabin_bag')?.setValue(e?.chd_cabin_bag); + this.FlightsRate.controls[i].get('inf_cabin_bag')?.setValue(e?.inf_cabin_bag); + this.FlightsRate.controls[i].get('_cabin_bag_unit')?.setValue(e?._cabin_bag_unit); + this.FlightsRate.controls[i].get('refund_type')?.setValue(e?.refund_type); + this.FlightsRate.controls[i].get('adt_fare_rule')?.setValue(e?.adt_fare_rule); + this.FlightsRate.controls[i].get('chd_fare_rule')?.setValue(e?.chd_fare_rule); + this.FlightsRate.controls[i].get('inf_fare_rule')?.setValue(e?.inf_fare_rule); + this.FlightsRate.controls[i].get('is_meal_included')?.setValue(e?.is_meal_included ? 'Yes' : 'No'); + this.UpdateMealTypeIncluded(this.FlightsRate.controls[i]); + this.FlightsRate.controls[i].get('meal_details')?.setValue(e?.meal_details); + this.FlightsRate.controls[i].get('inclusions')?.setValue(e?.inclusions); + this.FlightsRate.controls[i].get('pnr')?.setValue(e?.pnr); + }) + }; + copyFlightRatesGroup(ind, e?) { + // data.forEach((e, i) => { + // this.addFlightsRateGroupBtn(); + this.FlightsRate.insert(ind + 1, this.Fb.group({ + rbd: this.validationService.required, + fare_family_group_id: this.validationService.required, + fare_family_name: this.validationService.required, + cabin_class: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + seat_allocation: this.validationService.number, + is_checked_bag_included: [false], + is_apply_discount_with_same_vc_only: [false], + adt_check_bag: [{ value: '', disabled: true }], + _check_bag_unit: [{ value: '', disabled: true }], + adt_cabin_bag: this.validationService.required, + _cabin_bag_unit: this.validationService.required, + refund_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + is_meal_included: this.validationService.required, + meal_details: [], + inclusions: [], + })); + this.AddUpdatePaxWiseControls(); + this.UpdateFlightsRateFormGroup(); + this.FlightsRate.controls[ind + 1].get('rbd')?.setValue(e?.rbd) + this.FlightsRate.controls[ind + 1].get('fare_family_group_id')?.setValue(e?.fare_family_group_id); + this.FlightsRate.controls[ind + 1].get('fare_family_name')?.setValue(e?.fare_family_name); + this.FlightsRate.controls[ind + 1].get('cabin_class')?.setValue(e?.cabin_class); + this.FlightsRate.controls[ind + 1].get('adt_base_fare')?.setValue(e?.adt_base_fare); + this.FlightsRate.controls[ind + 1].get('adt_tax')?.setValue(e?.adt_tax); + this.FlightsRate.controls[ind + 1].get('chd_base_fare')?.setValue(e?.chd_base_fare); + this.FlightsRate.controls[ind + 1].get('chd_tax')?.setValue(e?.chd_tax); + this.FlightsRate.controls[ind + 1].get('inf_base_fare')?.setValue(e?.inf_base_fare); + this.FlightsRate.controls[ind + 1].get('inf_tax')?.setValue(e?.inf_tax); + this.FlightsRate.controls[ind + 1].get('round_trip_discount_type')?.setValue(e?.round_trip_discount_type); + this.FlightsRate.controls[ind + 1].get('is_apply_discount_with_same_vc_only')?.setValue(e?.is_apply_discount_with_same_vc_only); + this.FlightsRate.controls[ind + 1].get('adult_round_trip_discount')?.setValue(e?.adult_round_trip_discount); + this.FlightsRate.controls[ind + 1].get('child_round_trip_discount')?.setValue(e?.child_round_trip_discount); + this.FlightsRate.controls[ind + 1].get('infant_round_trip_discount')?.setValue(e?.infant_round_trip_discount); + this.FlightsRate.controls[ind + 1].get('seat_allocation')?.setValue(e?.seat_allocation) + this.FlightsRate.controls[ind + 1].get('is_checked_bag_included')?.setValue(e?.is_checked_bag_included); + this.UpdateBag(this.FlightsRate.controls[ind + 1]) + this.FlightsRate.controls[ind + 1].get('adt_check_bag')?.setValue(e?.adt_check_bag); + this.FlightsRate.controls[ind + 1].get('chd_check_bag')?.setValue(e?.chd_check_bag); + this.FlightsRate.controls[ind + 1].get('inf_check_bag')?.setValue(e?.inf_check_bag); + this.FlightsRate.controls[ind + 1].get('_check_bag_unit')?.setValue(e?._check_bag_unit); + this.FlightsRate.controls[ind + 1].get('adt_cabin_bag')?.setValue(e?.adt_cabin_bag); + this.FlightsRate.controls[ind + 1].get('chd_cabin_bag')?.setValue(e?.chd_cabin_bag); + this.FlightsRate.controls[ind + 1].get('inf_cabin_bag')?.setValue(e?.inf_cabin_bag); + this.FlightsRate.controls[ind + 1].get('_cabin_bag_unit')?.setValue(e?._cabin_bag_unit); + this.FlightsRate.controls[ind + 1].get('refund_type')?.setValue(e?.refund_type); + this.FlightsRate.controls[ind + 1].get('adt_fare_rule')?.setValue(e?.adt_fare_rule); + this.FlightsRate.controls[ind + 1].get('chd_fare_rule')?.setValue(e?.chd_fare_rule); + this.FlightsRate.controls[ind + 1].get('inf_fare_rule')?.setValue(e?.inf_fare_rule); + this.FlightsRate.controls[ind + 1].get('is_meal_included')?.setValue(e?.is_meal_included ? 'Yes' : 'No'); + this.UpdateMealTypeIncluded(this.FlightsRate.controls[ind + 1]); + this.FlightsRate.controls[ind + 1].get('meal_details')?.setValue(e?.meal_details); + this.FlightsRate.controls[ind + 1].get('inclusions')?.setValue(e?.inclusions); + this.FlightsRate.controls[ind + 1].get('pnr')?.setValue(e?.pnr); + // }) + }; + getIsMeal(iscopyUi, e) { + if (iscopyUi) { + return (e?.is_meal_included ? 'Yes' : 'No'); + } else { + return (e?.is_meal_included); + } + }; + GetAllAirData(res) { + this.AllSelectedAirports.push(res.FlightContract.origin); + this.AllSelectedAirports.push(res.FlightContract.origin); + this.AllSelectedAirline.push(res.FlightContract.validating_airline); + if (res.FlightContract.nearby_from_airports) { + this.AllSelectedAirports.push(...res.FlightContract.nearby_from_airports.split(',')); + } + if (res.FlightContract.nearby_to_airports) { + this.AllSelectedAirports.push(...res.FlightContract.nearby_to_airports.split(',')); + }; + if (res.FlightDetails && res.FlightDetails.length > 0) { + res.FlightDetails.forEach(e => { + this.AllSelectedAirports.push(e.from_airport); + this.AllSelectedAirports.push(e.to_airport); + this.AllSelectedAircraft.push(e.aircraft_type_id); + this.AllSelectedAirline.push(e.airline_code); + }); + }; + this._flightContractService.GetAirportsByAirportCode(this.AllSelectedAirports.join(',')); + this._flightContractService.GetAircraftTypeById(this.AllSelectedAircraft.join(',')); + this._flightContractService.GetAirlineByAirlineCode(this.AllSelectedAirline.join(',')); + } + // static dropdown + Option = [ + { value: 'Yes', displayName: 'Yes' }, + { value: 'No', displayName: 'No' }, + ]; + updateAirportSelection(name: string, val: any) { + const controlMap = { + 'orgin': this.outbound.controls[0].get('from_airport'), + 'destination': this.inbound?.controls?.[0]?.get('from_airport') + }; + if (val && controlMap[name]) { + controlMap[name].setValue(val); + } else { + controlMap[name]?.setValue(null); + } + }; + + + selectAllDays() { + const weekDays = this._staticService.WeekDaysList.map(day => day.Itemkey2); + this.Formdata.controls['departure_days'].setValue(weekDays); + this.allDaysSelected = true; + }; + + IsAllDaysSelected(): boolean { + let alldays = this._staticService.WeekDaysList.every(e => { + if (this.Formdata.controls['departure_days']?.value && this.Formdata.controls['departure_days']?.value.includes(e.Itemkey2)) { + return true + } + return false + }) + return alldays + } + + clearAllDays() { + this.Formdata.controls['departure_days'].setValue([]); + this.allDaysSelected = false; + } + + + storeDestAirportList(form, i) { + let fb = form as FormArray; + if (fb.controls[i].get('to_airport').value) { + if (fb.controls[i + 1]) { + fb.controls[i + 1].get('from_airport').setValue(fb.controls[i].get('to_airport').value); + }; + }; + }; + + backClick() { + this.router.navigateByUrl("Services/FlightInventory/Search"); + } +} diff --git a/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.html b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.html new file mode 100644 index 0000000..457d0e9 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.html @@ -0,0 +1,600 @@ + + +
    +
    +
    +

    Apply Edit to

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    + +
    + Departure Date +
    + Please + select date type +
    +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + Please + select from date +
    + +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + Please + select to date + Please + select to date greater than from date +
    +
    +
    +
    + + + +
    +
    +
    +

    Departure Days

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Outbound Flight - + {{OutBondDate}} +

    +
    +
    +
    +
    +
    +
    +
    + + + {{item.airline_name}} + ({{item.airline_code}}) + + +
    +
    + + +
    +
    + + + +
    +
    + + + {{item.ct}} + ({{item.ac}}) + +
    +
    + + + {{item.ct}} + ({{item.ac}}) + +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + +
    +
    + + +
    +
    + + Next Day Arrival + +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + Departure Next Day +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Inbound Flight - + {{InBondDate}} +

    +
    +
    +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    + +
    + + {{item.ct}} + ({{item.ac}}) + +
    +
    +
    + +
    + + {{item.ct}} + ({{item.ac}}) + +
    +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + Next Day Arrival + +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + Departure Next Day +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.ts b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.ts new file mode 100644 index 0000000..e511de1 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-flight-details/edit-flight-details.component.ts @@ -0,0 +1,475 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightDetailDto } from 'src/app/core/models/flight-service/flight-contracts.model'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; + +@Component({ + selector: 'app-edit-flight-details', + templateUrl: './edit-flight-details.component.html', +}) +export class EditFlightDetailsComponent implements OnInit { + + constructor( + public _staticService: StaticDataService, + public activateRoute: ActivatedRoute, + public validationService: ValidationService, + public _flightContractService: FlightContractService, + private Fb: FormBuilder, + public _commonService: CommonFunctionService, + private ApiServ: API, + public router: Router, + ) { } + ContractId; + Formdata: FormGroup; + ngOnInit(): void { + this.PageSetUp(); + }; + Defaultdate = new Date(); + + + PageSetUp() { + this.ContractId = this.activateRoute.snapshot.paramMap.get('ContractId'); + this.GetFlightContratByID(); + }; + + FlightContractDetails; + DatesListArray = [] + GetFlightContratByID() { + this.ApiServ.Get('/FlightContract/GetFlightContractByID/' + this.ContractId).subscribe(res => { + if (res) { + this.FlightContractDetails = res.data; + if (this.FlightContractDetails.departure_dates && this.FlightContractDetails.multi_day_operation_type == 'SPECIFICDATES') { + let datelist = this.FlightContractDetails.departure_dates.split(','); + if (datelist && datelist.length > 0) { + this.DatesListArray = datelist.map(e => { + let date = new Date(e) + date.setHours(0, 0, 0, 0); + return moment(date).format('YYYY-MM-DD') + }); + } + }; + if (this.FlightContractDetails?.operation_from && this.FlightContractDetails?.operation_to) { + let from_date = new Date(this.FlightContractDetails.operation_from); + let to_date = new Date(this.FlightContractDetails.operation_from); + if (this.FlightContractDetails.departure_dates && this.FlightContractDetails.multi_day_operation_type == 'SPECIFICDATES') { + let datelist = this.FlightContractDetails.departure_dates.split(','); + let dates = []; + datelist.forEach(e => { + if (new Date(e) >= new Date()) dates.push(e) + }); + from_date = new Date(dates[0]); + to_date = new Date(datelist[datelist.length - 1]); + } + let current_date = new Date(); + from_date.setHours(0, 0, 0, 0); + to_date.setHours(0, 0, 0, 0); + current_date.setHours(0, 0, 0, 0); + if (from_date.getTime() < current_date.getTime() && to_date.getTime() > current_date.getTime()) { + this.Defaultdate = current_date; + } else { + this.Defaultdate = from_date; + } + } + this.OnIntForm(); + } + }); + }; + WeekDaysList = []; + OnIntForm() { + this.Formdata = this.Fb.group({ + Default: [''], + is_multi_day: [false], + outbond: this.Fb.array([]), + inbond: this.Fb.array([]), + }); + if (this.FlightContractDetails?.is_multi_day) { + this.Formdata.addControl('date_type', this.validationService.required); + this.Formdata.addControl('from_date', this.validationService.required); + this.Formdata.addControl('to_date', this.validationService.required); + if (this.FlightContractDetails.multi_day_operation_type == 'RANGE') { + this._staticService.WeekDaysList.forEach(e => { + if (this.FlightContractDetails?.departure_days?.includes(e.Itemkey2)) this.WeekDaysList.push(e.Itemkey2); + }) + this.Formdata.addControl('days', this.Fb.control('')); + }; + } else { + this.Formdata.get('Default').setValue(this.FlightContractDetails.departure_date); + this.GetFlightDetailsList(); + }; + }; + + get outbond() { + return this.Formdata.get('outbond') as FormArray; + }; + get inbond() { + return this.Formdata.get('inbond') as FormArray; + }; + + GetFlightDetailsList() { + if ( + this.Formdata.get('date_type')?.invalid || + this.Formdata.get('from_date')?.invalid || + this.Formdata.get('to_date')?.invalid + ) { + this.validationService.showValidationsMsg(this.Formdata); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + let value = this.Formdata.getRawValue(); + let requestObject = { + contract_id: this.ContractId, + date_type: value.date_type, + from_date: '', + to_date: '', + days: '', + flight_details: [], + }; + if (this.FlightContractDetails?.is_multi_day) { + requestObject.from_date = this._commonService.convertDateToSave(value.from_date); + requestObject.to_date = this._commonService.convertDateToSave(value.to_date); + requestObject.days = value.days ? value.days.join(',') : ''; + } else { + requestObject.from_date = this._commonService.convertDateToSave(value.Default); + requestObject.to_date = this._commonService.convertDateToSave(value.Default); + const date = moment(value.Default); + const dayName = date.format('dddd'); + requestObject.days = dayName; + }; + this.ApiServ.Post('/FlightContract/GetAllFlightDetailsBySearch', requestObject).subscribe(res => { + if (res) { + if (res['status']) { + this.FlightContractListBind(res.data) + } else { + this._commonService.showMessage(res['status'], res['message']) + } + } + }); + }; + OutBondDate; + InBondDate; + DepartureDate; + FlightContractListBind(legs) { + this.outbond.clear(); + this.GetAllSelectedData(legs); + let outbondlist = legs.filter(e => e.seg_nbr == 1).sort((a, b) => a.leg_nbr - b.leg_nbr); + this.DepartureDate = outbondlist[0].departure_date; + this.OutBondDate = this._commonService.convertDateToShow(outbondlist[0].departure_date); + outbondlist.forEach((object, i) => { + this.addFlightGroupBtn(true); + this.outbond.controls[i].get('airline_code').setValue(object['airline_code']); + this.outbond.controls[i].get('flight_no').setValue(object['flight_no']); + this.outbond.controls[i].get('_aircraft_type').setValue(object['aircraft_type_id']); + this.outbond.controls[i].get('from_airport').setValue(object['from_airport']); + this.outbond.controls[i].get('to_airport').setValue(object['to_airport']); + this.outbond.controls[i].get('departure_terminal').setValue(object['departure_terminal']); + this.outbond.controls[i].get('is_next_day_arrival').setValue(object['is_next_day_arrival']); + this.outbond.controls[i].get('arrival_terminal').setValue(object['arrival_terminal']); + this.outbond.controls[i].get('is_next_day_departure').setValue(object['is_next_day_departure']); + if (object['departure_time']) { + let hour = object['departure_time'].split(':')[0]; + let minutes = object['departure_time'].split(':')[1]; + this.outbond.controls[i].get('departure_Hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.outbond.controls[i].get('departure_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + if (object['arrival_time']) { + let hour = object['arrival_time'].split(':')[0]; + let minutes = object['arrival_time'].split(':')[1]; + this.outbond.controls[i].get('arrival_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.outbond.controls[i].get('arrival_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + if (object['flying_duration']) { + let hour = object['flying_duration'].split(':')[0]; + let minutes = object['flying_duration'].split(':')[1]; + this.outbond.controls[i].get('flying_duration_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.outbond.controls[i].get('flying_duration_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + }); + let inbondlist = legs.filter(e => e.seg_nbr == 2); + if (inbondlist && inbondlist.length > 0) { + this.InBondDate = this._commonService.convertDateToShow(inbondlist[0].departure_date); + inbondlist = inbondlist.sort((a, b) => a.leg_nbr - b.leg_nbr); + inbondlist.forEach((object, i) => { + this.addFlightGroupBtn(false); + this.inbond.controls[i].get('airline_code').setValue(object['airline_code']); + this.inbond.controls[i].get('flight_no').setValue(object['flight_no']); + this.inbond.controls[i].get('_aircraft_type').setValue(object['aircraft_type_id']); + this.inbond.controls[i].get('from_airport').setValue(object['from_airport']); + this.inbond.controls[i].get('to_airport').setValue(object['to_airport']); + this.inbond.controls[i].get('departure_terminal').setValue(object['departure_terminal']); + this.inbond.controls[i].get('is_next_day_arrival').setValue(object['is_next_day_arrival']); + this.inbond.controls[i].get('arrival_terminal').setValue(object['arrival_terminal']); + this.inbond.controls[i].get('is_next_day_departure').setValue(object['is_next_day_departure']); + if (object['departure_time']) { + let hour = object['departure_time'].split(':')[0]; + let minutes = object['departure_time'].split(':')[1]; + this.inbond.controls[i].get('departure_Hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.inbond.controls[i].get('departure_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + if (object['arrival_time']) { + let hour = object['arrival_time'].split(':')[0]; + let minutes = object['arrival_time'].split(':')[1]; + this.inbond.controls[i].get('arrival_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.inbond.controls[i].get('arrival_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + if (object['flying_duration']) { + let hour = object['flying_duration'].split(':')[0]; + let minutes = object['flying_duration'].split(':')[1]; + this.inbond.controls[i].get('flying_duration_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.inbond.controls[i].get('flying_duration_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + }); + } + }; + + GetAllSelectedData(data) { + let all_aircraft_type = data.map(e => e.aircraft_type_id); + let AllAirline = data.map(e => e.airline_code); + let AllAirports = []; + data.forEach(e => { + AllAirports.push(e.from_airport); + AllAirports.push(e.to_airport); + }); + if (all_aircraft_type.length > 0) this.GetAircraftTypeById(all_aircraft_type.join(',')); + if (AllAirports.length > 0) this.GetAirportsByAirportCode(AllAirports.join(',')); + if (AllAirline.length > 0) this.GetAirlineByAirlineCode(AllAirline.join(',')); + }; + + addFlightGroupBtn(check) { + let formgroup = check ? this.outbond : this.inbond + formgroup.push( + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: [{ value: null, disabled: true }, Validators.required], + to_airport: [{ value: null, disabled: true }, Validators.required], + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: [''], + is_next_day_arrival: [{ value: false, disabled: true }], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: [''], + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [{ value: false, disabled: true }], + }) + ); + }; + UpdateControlsValidation(group, name, type) { + if (type == 'add') { + group.get(name)?.addValidators([Validators.required]); + group.get(name)?.updateValueAndValidity(); + } else { + group.get(name)?.clearValidators(); + group.get(name)?.updateValueAndValidity(); + group.get(name)?.markAsUntouched(); + }; + }; + + Saveflightdetails() { + if (this.Formdata.invalid) { + this.validationService.showValidationsMsg(this.Formdata); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + let value = this.Formdata.getRawValue(); + let requestObject = { + contract_id: this.ContractId, + date_type: value.date_type, + from_date: '', + to_date: '', + days: '', + flight_details: [], + }; + if (this.FlightContractDetails?.is_multi_day) { + requestObject.from_date = this._commonService.convertDateToSave(value.from_date); + requestObject['to_date'] = this._commonService.convertDateToSave(value.to_date); + requestObject.days = value.days ? value.days.join(',') : ''; + } else { + requestObject.from_date = this._commonService.convertDateToSave(this.DepartureDate); + requestObject.to_date = this._commonService.convertDateToSave(this.DepartureDate); + const date = moment(this.DepartureDate); + const dayName = date.format('dddd'); + requestObject.days = dayName; + } + value.outbond.forEach((e, i) => { + let fligtDetlPostData = new FlightDetailDto(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + fligtDetlPostData.aircraft_type_id = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = (e.arrival_hour || '00') + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = (e.flying_duration_hour || '00') + ':' + (e.flying_duration_minutes || '00') + ':00'; + fligtDetlPostData.leg_nbr = i + 1; + fligtDetlPostData.seg_nbr = 1; + requestObject.flight_details.push(fligtDetlPostData); + }); + if (value.inbond && value.inbond.length > 0) { + value.inbond.forEach((e, i) => { + let fligtDetlPostData = new FlightDetailDto(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + fligtDetlPostData.aircraft_type_id = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = (e.arrival_hour || '00') + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = (e.flying_duration_hour || '00') + ':' + (e.flying_duration_minutes || '00') + ':00'; + fligtDetlPostData.leg_nbr = i + 1; + fligtDetlPostData.seg_nbr = 2; + requestObject.flight_details.push(fligtDetlPostData); + }); + } + this.ApiServ.Post('/FlightContract/UpdateFlightDetails', requestObject).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + setTimeout(() => { + if (res['status']) this.router.navigate(['/Services/FlightInventory/Search']); + }, 500); + } + }); + }; + weekdaylist + checkDateForHighlight(date) { + if (!this.FlightContractDetails.is_multi_day) { + return false; // If not multi-day event, don't highlight any date + } + let currentDate = new Date(date.year, date.month, date.day); + currentDate.setHours(0, 0, 0, 0); + if (this.FlightContractDetails?.multi_day_operation_type === 'RANGE') { + let fromDate = new Date(this.FlightContractDetails.operation_from); + let toDate = new Date(this.FlightContractDetails.operation_to); + fromDate.setHours(0, 0, 0, 0); + toDate.setHours(0, 0, 0, 0); + if (currentDate < fromDate || currentDate > toDate) { + return false; // currentDate is outside the range, don't highlight + } + return this.FlightContractDetails.departure_days.includes(currentDate.toLocaleDateString('en-US', { weekday: 'long' })); + } else { + return this.DatesListArray.some(e => e == moment(currentDate).format('YYYY-MM-DD')); + } + } + + @ViewChild('from_date') from_date; + @ViewChild('to_date') to_date; + onSelect(date, caleder) { + if (date && !this.checkDateForHighlight(date)) { + if (caleder == 'from_date') { + this.from_date.overlayVisible = true; + this.Formdata.get('from_date').setValue(null); + } else { + this.to_date.overlayVisible = true; + this.Formdata.get('to_date').setValue(null); + } + }; + }; + + ResetForm() { + this.Formdata.reset(); + }; + + GetAircraftTypeById(data) { + let obj = { + aircraft_type_id: data + } + this.ApiServ.Post('/MasterSearch/GetAircraftTypeById', obj).subscribe(res => { + if (res) { + this._flightContractService.AllAirCraftList = res.data; + setTimeout(() => { + this._flightContractService.AllAirCraftList = []; + }, 500); + } + }); + }; + GetAirportsByAirportCode(data) { + let obj = { + airport_code: data + } + this.ApiServ.AdminGoPost('/Airport/GetAirportsByAirportCode', obj).subscribe(res => { + if (res) { + if (res.Result && res.Result.length > 0) { + this._flightContractService.AirportList = res.Result; + this._flightContractService.AirportList = this._flightContractService.AirportList.map(e => ({ 'ac': e.airport_code, 'ct': e.city_name })); + } + setTimeout(() => { + this._flightContractService.AirportList = []; + }, 500); + } + }); + }; + GetAirlineByAirlineCode(data) { + let obj = { + airline_code: data + } + this.ApiServ.AdminGoPost('/MasterSearch/GetAirlineByAirlineCode', obj).subscribe(res => { + if (res) { + this._flightContractService.AirlineList = res.Result; + setTimeout(() => { + this._flightContractService.AirlineList = []; + }, 500); + + } + }); + }; + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (toDate && control.value < toDate) { + return { 'range': true }; + } + } + return null; + }; + } + Update_Validation() { + let from_date = this.Formdata.get('from_date').value; + if (from_date) { + this.Formdata.get("to_date").clearValidators(); + this.Formdata.get("to_date").setErrors(null); + this.Formdata.get("to_date").addValidators(Validators.compose([Validators.required, this.dateValidation(from_date)])); + this.Formdata.get("to_date").updateValueAndValidity(); + } + } + backClick() { + this.router.navigateByUrl("Services/FlightInventory/Search"); + } + selectAllDays() { + const weekDays = this.WeekDaysList.map(day => day); + this.Formdata.controls['days'].setValue(weekDays); + }; + + IsAllDaysSelected(): boolean { + let alldays = this.WeekDaysList.every(e => { + if (this.Formdata.controls['days']?.value && this.Formdata.controls['days']?.value.includes(e)) { + return true + } + return false + }) + return alldays + } + + clearAllDays() { + this.Formdata.controls['days'].setValue([]); + } +} diff --git a/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.html b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.html new file mode 100644 index 0000000..a08f38d --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.html @@ -0,0 +1,1128 @@ + +
    +
    +
    +

    Date Filter

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    + +
    + Departure Date +
    + Please + select date type +
    +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + Please + select from date +
    +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + Please + select to date + Please + select to date greater than from date +
    +
    +
    +
    + + + +
    +
    +
    +

    Departure Days

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Outbound Days

    +
    + +
    +
    + +
    +
    + Please + select rbd +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Fare Family Group

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Round Trip Discount Type

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Check Bag Unit

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Cabin Bag Unit

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    +

    Refund Type

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Confirmation Type

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +

    Meal Included

    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    +
    Date
    +
    +
    Return Date
    +
    +
    + Stop Sale +
    +
    +
    + Fare Family Group +
    +
    +
    + Fare Family Name +
    +
    +
    + Adult Base Fare +
    +
    +
    + Adult Taxes +
    +
    +
    + Child Base Fare +
    +
    +
    + Child Taxes +
    +
    +
    + Infant Base Fare +
    +
    +
    + Infant Taxes +
    +
    +
    + Round Trip Discount Type +
    +
    +
    + Apply discount with same VC Only +
    +
    +
    + Adult Round Trip Discount +
    (on Base fare)
    +
    +
    +
    + Child Round Trip Discount +
    (on Base fare)
    +
    +
    +
    + Infant Round Trip Discount +
    (on Base fare)
    +
    +
    +
    + Seats Allocation +
    +
    +
    + Booked Seats +
    +
    +
    + Remaining Seats +
    +
    +
    + Cancelled Seats +
    +
    +
    + Checked Bag Included +
    +
    +
    + Adult Check Bag +
    +
    +
    + Child Check Bag +
    +
    +
    + Infant Check Bag +
    +
    +
    + Check Bag Unit +
    +
    +
    + Adult Cabin Bag
    +
    +
    + Child Cabin Bag
    +
    +
    + Infant Cabin Bag
    +
    +
    + Cabin Bag Unit
    +
    +
    + Refund Type
    +
    +
    + PNR +
    +
    +
    + Confirmation type +
    +
    +
    + Adult Fare Rule
    +
    +
    + Child Fare Rule
    +
    +
    + Infant Fare Rule
    +
    +
    + Meal Included
    +
    +
    + Meal Details
    +
    +
    + Inclusions
    +
    +
    + Updated By
    +
    +
    + Updated On
    +
    + {{item.get('departure_date').value}} + + {{item.get('return_date').value}} + +
    + +
    +
    +
    + + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    + +
    +
    +
    +
    +
    + + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    Confirmation Type
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.ts b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.ts new file mode 100644 index 0000000..ab3c74a --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-manage/edit-rate-inventory/edit-rate-inventory.component.ts @@ -0,0 +1,664 @@ +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormControl, FormGroup, Validators, AbstractControl, ValidatorFn } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { NgSelectComponent } from '@ng-select/ng-select'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightRateArray } from 'src/app/core/models/flight-service/flight-contracts.model'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; + +@Component({ + selector: 'app-edit-rate-inventory', + templateUrl: './edit-rate-inventory.component.html', +}) +export class EditRateInventoryComponent implements OnInit { + + constructor( + public _staticService: StaticDataService, + public activateRoute: ActivatedRoute, + public validationService: ValidationService, + public _flightContractService: FlightContractService, + private Fb: FormBuilder, + public _commonService: CommonFunctionService, + private ApiServ: API, + public router: Router, + ) { } + + + ContractId; + Defaultdate; + Formdata: FormGroup; + ngOnInit(): void { + this.PageSetUp(); + }; + PageSetUp() { + this.ContractId = this.activateRoute.snapshot.paramMap.get('ContractId'); + this.GetFlightContratByID(); + }; + + FlightContractDetails; + DatesListArray = []; + FareFamilyList = []; + IsChild = false; + IsInfant = false; + GetFlightContratByID() { + this.ApiServ.Get('/FlightContract/GetFlightContractByID/' + this.ContractId).subscribe(res => { + if (res) { + this.FlightContractDetails = res.data; + if (this.FlightContractDetails.departure_dates && this.FlightContractDetails.multi_day_operation_type == 'SPECIFICDATES') { + let datelist = this.FlightContractDetails.departure_dates.split(','); + if (datelist && datelist.length > 0) { + this.DatesListArray = datelist.map(e => { + let date = new Date(e); + date.setHours(0, 0, 0, 0); + return moment(date).format('YYYY-MM-DD') + }); + } + }; + if (this.FlightContractDetails?.operation_from && this.FlightContractDetails?.operation_to) { + let from_date = new Date(this.FlightContractDetails.operation_from); + let to_date = new Date(this.FlightContractDetails.operation_from); + if (this.FlightContractDetails.departure_dates && this.FlightContractDetails.multi_day_operation_type == 'SPECIFICDATES') { + let datelist = this.FlightContractDetails.departure_dates.split(','); + let dates = []; + datelist.forEach(e => { + if (new Date(e) >= new Date()) dates.push(e) + }); + from_date = new Date(dates[0]); + to_date = new Date(datelist[datelist.length - 1]); + } + let current_date = new Date(); + from_date.setHours(0, 0, 0, 0); + to_date.setHours(0, 0, 0, 0); + current_date.setHours(0, 0, 0, 0); + if (from_date.getTime() < current_date.getTime() && to_date.getTime() > current_date.getTime()) { + this.Defaultdate = current_date; + } else { + this.Defaultdate = from_date; + } + } + if (this.FlightContractDetails['contracted_pax_type'].includes('C')) this.IsChild = true; + if (this.FlightContractDetails['contracted_pax_type'].includes('I')) this.IsInfant = true; + this.OnIntForm(); + for (let index = 1; index <= 3; index++) { + this.FareFamilyList.push(index) + }; + } + }); + }; + WeekDaysList = []; + AtoZ = [] + OnIntForm() { + this.Formdata = this.Fb.group({ + Default: [''], + _rbd: this.validationService.required, + currency: [this.FlightContractDetails.currency_code], + contracted_pax_type: [this.FlightContractDetails.contracted_pax_type], + FlightsRate: this.Fb.array([]) + }); + this.AtoZ = this.FlightContractDetails.rbd?.split(',') || []; + this.AtoZ = [...new Set(this.AtoZ)]; + if (this.FlightContractDetails?.is_multi_day) { + this.Formdata.addControl('date_type', this.validationService.required); + this.Formdata.addControl('from_date', this.validationService.required); + this.Formdata.addControl('to_date', this.validationService.required); + if (this.FlightContractDetails.multi_day_operation_type == 'RANGE') { + this._staticService.WeekDaysList.forEach(e => { + if (this.FlightContractDetails?.departure_days?.includes(e.Itemkey2)) this.WeekDaysList.push(e.Itemkey2); + }) + this.Formdata.addControl('days', this.Fb.control('')); + }; + } else { + this.Formdata.get('Default').setValue(this.FlightContractDetails.departure_date); + }; + }; + ResetForm() { + this.Formdata.get('_rbd')?.setValue(''); + this.Formdata.get('contracted_pax_type')?.setValue(''); + this.Formdata.get('date_type')?.setValue(''); + this.Formdata.get('from_date')?.setValue(null); + this.Formdata.get('to_date')?.setValue(null); + this.Formdata.get('days')?.setValue(null); + this.Formdata.markAsUntouched(); + } + get FlightsRate() { + return this.Formdata.get('FlightsRate') as FormArray; + } + + GetFlightRateList() { + if ( + this.Formdata.get('_rbd')?.invalid || + this.Formdata.get('date_type')?.invalid || + this.Formdata.get('from_date')?.invalid || + this.Formdata.get('to_date')?.invalid + ) { + this.validationService.showValidationsMsg(this.Formdata); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + let value = this.Formdata.getRawValue(); + let requestObject = { + contract_id: this.ContractId, + date_type: value.date_type, + from_date: '', + to_date: '', + days: '', + rbd: value._rbd, + flight_details: [], + }; + if (this.FlightContractDetails?.is_multi_day) { + requestObject.from_date = this._commonService.convertDateToSave(value.from_date); + requestObject.to_date = this._commonService.convertDateToSave(value.to_date); + requestObject.days = value.days ? value.days.join(',') : ''; + } else { + requestObject.from_date = this._commonService.convertDateToSave(value.Default); + requestObject.to_date = this._commonService.convertDateToSave(value.Default); + const date = moment(value.Default); + const dayName = date.format('dddd'); + requestObject.days = dayName; + }; + this.ApiServ.Post('/FlightContract/GetAllFlightRateBySearch', requestObject).subscribe(res => { + if (res) { + if (res['status']) this.SetValForm(res.data); + if (!res['status']) this._commonService.showMessage(res['status'], res['message']); + } + }); + }; + SaveFlightsRate() { + if (this.FlightsRate.invalid) { + this.validationService.showValidationsMsg(this.FlightsRate); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + let value = this.FlightsRate.getRawValue(); + let FlightRate = []; + value.forEach((e, i) => { + if (this.FlightsRate.controls[i].dirty) { + let postObject = new FlightRateArray(); + postObject.contract_id = this.ContractId; + postObject.contract_date_unique_id = e.contract_date_unique_id; + postObject.rate_id = e.rate_id; + postObject.fare_family_group_id = e.fare_family_group_id.toString(); + postObject.fare_family_name = e.fare_family_name; + postObject.adt_base_fare = e.adt_base_fare ? parseFloat(e.adt_base_fare) : 0; + postObject.adt_tax = e.adt_tax ? parseFloat(e.adt_tax) : 0; + postObject.chd_base_fare = e?.chd_base_fare ? parseFloat(e?.chd_base_fare) : 0; + postObject.chd_tax = e.chd_tax ? parseFloat(e.chd_tax) : 0; + postObject.inf_base_fare = e?.inf_base_fare ? parseFloat(e?.inf_base_fare) : 0; + postObject.inf_tax = e?.inf_tax ? parseFloat(e?.inf_tax) : 0; + postObject.round_trip_discount_type = e.round_trip_discount_type; + postObject.is_apply_discount_with_same_vc_only = e.is_apply_discount_with_same_vc_only; + postObject.adult_round_trip_discount = e.adult_round_trip_discount ? parseFloat(e.adult_round_trip_discount) : 0; + postObject.child_round_trip_discount = e?.child_round_trip_discount ? parseFloat(e?.child_round_trip_discount) : 0; + postObject.infant_round_trip_discount = e?.infant_round_trip_discount ? parseFloat(e?.infant_round_trip_discount) : 0; + postObject.seat_allocation = e?.seat_allocation ? parseFloat(e?.seat_allocation) : 0; + postObject.is_checked_bag_included = e.is_checked_bag_included; + postObject.adt_check_bag = e.adt_check_bag; + postObject.chd_check_bag = e?.chd_check_bag ? e?.chd_check_bag : ''; + postObject.inf_check_bag = e?.inf_check_bag ? e?.inf_check_bag : ''; + postObject._check_bag_unit = e._check_bag_unit; + postObject.adt_cabin_bag = e.adt_cabin_bag; + postObject.chd_cabin_bag = e?.chd_cabin_bag ? e?.chd_cabin_bag : ''; + postObject.inf_cabin_bag = e?.inf_cabin_bag ? e?.inf_cabin_bag : ''; + postObject._cabin_bag_unit = e._cabin_bag_unit; + postObject.refund_type = e.refund_type; + postObject.adt_fare_rule = e.adt_fare_rule; + postObject.chd_fare_rule = e?.chd_fare_rule ? e?.chd_fare_rule : ''; + postObject.inf_fare_rule = e?.inf_fare_rule ? e?.inf_fare_rule : ''; + postObject.is_meal_included = e.is_meal_included == 'Yes' ? true : false; + postObject.meal_details = e.meal_details; + postObject.inclusions = e.inclusions; + postObject.pnr = e.pnr; + postObject.is_instant_confirmation = e.is_instant_confirmation == 'INSTANT' ? true : false; + postObject.is_stop_sale = e.is_stop_sale; + FlightRate.push(postObject); + } + }); + this.ApiServ.Post('/FlightContract/UpdateFlightRate', FlightRate).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + setTimeout(() => { + res['status'] ? this.router.navigate(['/Services/FlightInventory/Search']) : ''; + }, 500); + } + }); + }; + SetValForm(RateList) { + this.FlightsRate.clear(); + let datesort = RateList.sort((a, b) => { + const timestampA = new Date(a.departure_date).getTime(); + const timestampB = new Date(b.departure_date).getTime(); + return timestampA - timestampB; + }); + datesort.forEach((object, i) => { + this.addFlightsRateGroupBtn(); + this.FlightsRate.controls[i]?.get('contract_date_unique_id')?.setValue(object?.contract_date_unique_id); + this.FlightsRate.controls[i]?.get('rate_id')?.setValue(object?.rate_id); + this.FlightsRate.controls[i]?.get('departure_date')?.setValue(object?.departure_date ? moment(object?.departure_date).format('DD MMM YYYY') : ''); + this.FlightsRate.controls[i]?.get('return_date')?.setValue(object?.return_date ? moment(object?.return_date).format('DD MMM YYYY') : ''); + this.FlightsRate.controls[i]?.get('is_stop_sale')?.setValue(object?.is_stop_sale); + this.FlightsRate.controls[i]?.get('fare_family_group_id')?.setValue(object?.fare_family_group_id); + this.FlightsRate.controls[i]?.get('fare_family_name')?.setValue(object?.fare_family_name); + this.FlightsRate.controls[i]?.get('adt_base_fare')?.setValue(object?.adt_base_fare); + this.FlightsRate.controls[i]?.get('adt_tax')?.setValue(object?.adt_tax); + this.FlightsRate.controls[i]?.get('chd_base_fare')?.setValue(object?.chd_base_fare); + this.FlightsRate.controls[i]?.get('chd_tax')?.setValue(object?.chd_tax); + this.FlightsRate.controls[i]?.get('inf_base_fare')?.setValue(object?.inf_base_fare); + this.FlightsRate.controls[i]?.get('inf_tax')?.setValue(object?.inf_tax); + if (this.FlightContractDetails?.trip_type == 'ONEWAY') { + this.FlightsRate.controls[i]?.get('round_trip_discount_type')?.setValue(object?.round_trip_discount_type); + this.FlightsRate.controls[i]?.get('is_apply_discount_with_same_vc_only')?.setValue(object?.is_apply_discount_with_same_vc_only); + this.UpdateFareType(this.FlightsRate.controls[i]); + this.FlightsRate.controls[i]?.get('adult_round_trip_discount')?.setValue(object?.adult_round_trip_discount); + this.FlightsRate.controls[i]?.get('child_round_trip_discount')?.setValue(object?.child_round_trip_discount); + this.FlightsRate.controls[i]?.get('infant_round_trip_discount')?.setValue(object?.infant_round_trip_discount); + } + this.FlightsRate.controls[i]?.get('seat_allocation')?.setValue(object?.seat_allocation); + this.FlightsRate.controls[i]?.get('seat_booked')?.setValue(object?.seat_booked); + this.FlightsRate.controls[i]?.get('seat_cancelled')?.setValue(object?.seat_cancelled); + this.FlightsRate.controls[i]?.get('seat_remains')?.setValue(object?.seat_remains); + this.FlightsRate.controls[i]?.get('is_checked_bag_included')?.setValue(object?.is_checked_bag_included); + this.UpdateBag(this.FlightsRate.controls[i]); + if (object?.is_checked_bag_included) { + this.FlightsRate.controls[i]?.get('adt_check_bag')?.setValue(object?.adt_check_bag); + this.FlightsRate.controls[i]?.get('chd_check_bag')?.setValue(object?.chd_check_bag); + this.FlightsRate.controls[i]?.get('inf_check_bag')?.setValue(object?.inf_check_bag); + this.FlightsRate.controls[i]?.get('_check_bag_unit')?.setValue(object?._check_bag_unit); + } + this.FlightsRate.controls[i]?.get('adt_cabin_bag')?.setValue(object?.adt_cabin_bag); + this.FlightsRate.controls[i]?.get('chd_cabin_bag')?.setValue(object?.chd_cabin_bag); + this.FlightsRate.controls[i]?.get('inf_cabin_bag')?.setValue(object?.inf_cabin_bag); + this.FlightsRate.controls[i]?.get('_cabin_bag_unit')?.setValue(object?._cabin_bag_unit); + this.FlightsRate.controls[i]?.get('refund_type')?.setValue(object?.refund_type); + this.FlightsRate.controls[i]?.get('pnr')?.setValue(object?.pnr); + this.FlightsRate.controls[i]?.get('adt_fare_rule')?.setValue(object?.adt_fare_rule); + this.FlightsRate.controls[i]?.get('chd_fare_rule')?.setValue(object?.chd_fare_rule); + this.FlightsRate.controls[i]?.get('inf_fare_rule')?.setValue(object?.inf_fare_rule); + this.FlightsRate.controls[i]?.get('is_instant_confirmation')?.setValue(object?.is_instant_confirmation ? 'INSTANT' : 'MANUAL'); + this.FlightsRate.controls[i]?.get('is_meal_included')?.setValue(object?.is_meal_included ? 'Yes' : 'No'); + this.UpdateMealTypeIncluded(this.FlightsRate.controls[i]); + if (object?.is_meal_included) { + this.FlightsRate.controls[i]?.get('meal_details')?.setValue(object?.meal_details); + } + this.FlightsRate.controls[i]?.get('inclusions')?.setValue(object?.inclusions); + this.FlightsRate.controls[i]?.get('updated_by')?.setValue(object?.updated_by); + this.FlightsRate.controls[i]?.get('updated_on')?.setValue(object?.updated_on ? this._commonService.convertDateToShow(object?.updated_on) : ''); + }); + }; + addFlightsRateGroupBtn() { + this.FlightsRate.push( + this.Fb.group({ + contract_date_unique_id: this.validationService.required, + rate_id: this.validationService.required, + departure_date: [''], + return_date: [''], + fare_family_group_id: this.validationService.required, + fare_family_name: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + round_trip_discount_type: [''], + seat_allocation: this.validationService.decimal, + seat_booked: [], + seat_remains: [], + seat_cancelled: [], + is_checked_bag_included: [false], + adt_check_bag: [{ value: '', disabled: true }], + _check_bag_unit: [{ value: '', disabled: true }], + adt_cabin_bag: this.validationService.required, + _cabin_bag_unit: this.validationService.required, + refund_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + is_meal_included: [false], + meal_details: [{ value: null, disabled: true }], + inclusions: [''], + pnr: [], + is_instant_confirmation: [false], + is_stop_sale: [false], + is_apply_discount_with_same_vc_only: [false], + updated_by: [], + updated_on: [], + }) + ); + this.AddUpdatePaxWiseControls(); + }; + // ------------------------------------------------------------------------------------------------------------------------ + AddUpdatePaxWiseControls() { + let grp = this.FlightsRate.controls[this.FlightsRate.controls.length - 1]; + if (this.IsChild) this.UpdatePaxWiseControls(grp, 'chd', true); + if (this.IsInfant) this.UpdatePaxWiseControls(grp, 'inf', true); + }; + UpdatePaxWiseControls(group, name, check) { + let grp = group as FormGroup; + let discountName = name == 'chd' ? 'child' : 'infant'; + if (check) { + grp.addControl(name + '_base_fare', this.validationService.decimal); + grp.addControl(name + '_tax', this.validationService.decimal); + grp.addControl(name + '_check_bag', this.Fb.control({ value: null, disabled: true })); + grp.addControl(name + '_cabin_bag', this.validationService.required); + grp.addControl(name + '_fare_rule', this.validationService.required); + grp.addControl(discountName + '_round_trip_discount', this.Fb.control(null)); + } else { + grp.removeControl(name + '_base_fare'); + grp.removeControl(name + '_tax'); + grp.removeControl(name + '_check_bag'); + grp.removeControl(name + '_cabin_bag'); + grp.removeControl(name + '_fare_rule'); + grp.removeControl(discountName + '_round_trip_discount'); + } + }; + UpdateBag(grp) { + let group = grp as FormGroup; + let controls = [ + 'adt_check_bag', + 'chd_check_bag', + 'inf_check_bag', + '_check_bag_unit', + // 'adt_cabin_bag', + // 'chd_cabin_bag', + // 'inf_cabin_bag', + // '_cabin_bag_unit', + ]; + if (group.get('is_checked_bag_included').value) controls.forEach(e => this.UpdateControlsValidation(group, e, 'add')); + else controls.forEach(e => this.UpdateControlsValidation(group, e, 'remove')); + if (group.get('is_checked_bag_included').value) controls.forEach(e => group.get(e)?.enable()); + else { + controls.forEach(e => { + group.get(e)?.disable(); + group.get(e)?.setValue(''); + }); + } + }; + UpdateValidationforDiscountTypegroup(group, event) { + let grpcontrols = group as FormGroup; + let vaidation_type = event ? 'add' : 'remove'; + this.UpdateControlsValidation(grpcontrols, 'adult_round_trip_discount', vaidation_type); + if (this.IsChild) { + this.UpdateControlsValidation(grpcontrols, 'child_round_trip_discount', vaidation_type) + } + if (this.IsInfant) { + this.UpdateControlsValidation(grpcontrols, 'infant_round_trip_discount', vaidation_type) + } + + } + UpdateFareType(group) { + let grpcontrols = group as FormGroup; + if (this.FlightContractDetails?.trip_type == 'ONEWAY') { + grpcontrols.addControl('adult_round_trip_discount', new FormControl('')); + if (this.IsChild) { + grpcontrols.addControl('child_round_trip_discount', new FormControl('')); + } + if (this.IsInfant) { + grpcontrols.addControl('infant_round_trip_discount', new FormControl('')); + } + } + this.UpdateValidationforDiscountTypegroup(group, grpcontrols.get('round_trip_discount_type').value); + }; + UpdateMealTypeIncluded(grp) { + let group = grp as FormGroup; + if (group.get('is_meal_included').value == 'Yes') { + group.get('meal_details').enable() + this.UpdateControlsValidation(group, 'meal_details', 'add'); + } + else { + group.get('meal_details').disable(); + group.get('meal_details').setValue(''); + this.UpdateControlsValidation(group, 'meal_details', 'remove'); + } + }; + UpdateControlsValidation(group, name, type) { + if (type == 'add') { + group.get(name)?.addValidators([Validators.required]); + group.get(name)?.updateValueAndValidity(); + } else { + group.get(name)?.clearValidators(); + group.get(name)?.updateValueAndValidity(); + group.get(name)?.markAsUntouched(); + }; + }; + // ----------------------------------------------------------------------------------------------------------------------- + checkDateForHighlight(date) { + if (!this.FlightContractDetails.is_multi_day) { + return false; // If not multi-day event, don't highlight any date + } + let currentDate = new Date(date.year, date.month, date.day); + currentDate.setHours(0, 0, 0, 0); + if (this.FlightContractDetails?.multi_day_operation_type === 'RANGE') { + let fromDate = new Date(this.FlightContractDetails.operation_from); + let toDate = new Date(this.FlightContractDetails.operation_to); + fromDate.setHours(0, 0, 0, 0); + toDate.setHours(0, 0, 0, 0); + if (currentDate < fromDate || currentDate > toDate) { + return false; // currentDate is outside the range, don't highlight + } + return this.FlightContractDetails.departure_days.includes(currentDate.toLocaleDateString('en-US', { weekday: 'long' })); + } else { + return this.DatesListArray.some(e => e == moment(currentDate).format('YYYY-MM-DD')); + } + }; + @ViewChild('from_date') from_date; + @ViewChild('to_date') to_date; + onSelect(date, caleder) { + if (date && !this.checkDateForHighlight(date)) { + if (caleder == 'from_date') { + this.from_date.overlayVisible = true; + this.Formdata.get('from_date').setValue(null); + } else { + this.to_date.overlayVisible = true; + this.Formdata.get('to_date').setValue(null); + } + }; + }; + Option = [ + { value: 'Yes' }, + { value: 'No' }, + ]; + + + // copy on UI function + @ViewChild('is_stop_sale') is_stop_sale: ElementRef; + @ViewChild('fare_family_group_id') fare_family_group_id: NgSelectComponent; + @ViewChild('fare_family_name') fare_family_name: ElementRef; + @ViewChild('adt_base_fare') adt_base_fare: ElementRef; + @ViewChild('adt_tax') adt_tax: ElementRef; + @ViewChild('chd_base_fare') chd_base_fare: ElementRef; + @ViewChild('chd_tax') chd_tax: ElementRef; + @ViewChild('inf_base_fare') inf_base_fare: ElementRef; + @ViewChild('inf_tax') inf_tax: ElementRef; + @ViewChild('round_trip_discount_type') round_trip_discount_type: NgSelectComponent; + @ViewChild('is_apply_discount_with_same_vc_only') is_apply_discount_with_same_vc_only: ElementRef; + @ViewChild('adult_round_trip_discount') adult_round_trip_discount: ElementRef; + @ViewChild('child_round_trip_discount') child_round_trip_discount: ElementRef; + @ViewChild('infant_round_trip_discount') infant_round_trip_discount: ElementRef; + @ViewChild('seat_allocation') seat_allocation: ElementRef; + @ViewChild('is_checked_bag_included') is_checked_bag_included: ElementRef; + @ViewChild('adt_check_bag') adt_check_bag: ElementRef; + @ViewChild('chd_check_bag') chd_check_bag: ElementRef; + @ViewChild('inf_check_bag') inf_check_bag: ElementRef; + @ViewChild('_check_bag_unit') _check_bag_unit: NgSelectComponent; + @ViewChild('adt_cabin_bag') adt_cabin_bag: ElementRef; + @ViewChild('chd_cabin_bag') chd_cabin_bag: ElementRef; + @ViewChild('inf_cabin_bag') inf_cabin_bag: ElementRef; + @ViewChild('_cabin_bag_unit') _cabin_bag_unit: NgSelectComponent; + @ViewChild('refund_type') refund_type: NgSelectComponent; + @ViewChild('pnr') pnr: ElementRef; + @ViewChild('is_instant_confirmation') is_instant_confirmation: NgSelectComponent; + @ViewChild('adt_fare_rule') adt_fare_rule: ElementRef; + @ViewChild('chd_fare_rule') chd_fare_rule: ElementRef; + @ViewChild('inf_fare_rule') inf_fare_rule: ElementRef; + @ViewChild('is_meal_included') is_meal_included: NgSelectComponent; + @ViewChild('meal_details') meal_details: ElementRef; + @ViewChild('inclusions') inclusions: ElementRef; + + MainFormGrpCopyOnUI(type, name, ViewChild) { + if (type == 'CheckBox') { + this.FlightsRate.controls.forEach((group) => { + group.get(name)?.setValue(ViewChild['_checked']); + group.markAsDirty(); + }) + } else if (type == 'dropdown') { + if (ViewChild?.selectedValues[0]?.value) this.FlightsRate.controls.forEach((group) => { + group.get(name)?.setValue(ViewChild.selectedValues[0]?.value); + group.markAsDirty(); + }) + else this.FlightsRate.controls.forEach((group) => { + group.get(name)?.setValue(ViewChild.selectedValues[0]); + group.markAsDirty(); + }) + } else if (type == 'text') { + if (ViewChild?.nativeElement?.value) this.FlightsRate.controls.forEach((group) => { + group.get(name)?.setValue(ViewChild.nativeElement.value); + group.markAsDirty(); + }) + else this.FlightsRate.controls.forEach((group) => { + group.get(name)?.setValue(ViewChild.value); + group.markAsDirty(); + }) + } + this.FlightsRate.updateValueAndValidity(); + }; + copyOnUiFareTypeApplicability(ViewChild, check, name) { + this.FlightsRate.controls.forEach((group) => { + if (check == 'dropdown') { + if (ViewChild?.selectedValues[0]?.value) group.get(name)?.setValue(ViewChild.selectedValues[0]?.value) + else group.get(name)?.setValue(ViewChild.selectedValues[0]) + group.markAsDirty(); + } else if (check == 'text') { + if (ViewChild?.nativeElement?.value) group.get(name)?.setValue(ViewChild.nativeElement.value) + else group.get(name)?.setValue(ViewChild.value) + group.markAsDirty(); + } + }); + }; + copyOnUiCheckedBagIncluded(ViewChild, check, name) { + this.FlightsRate.controls.forEach((group) => { + if (check == 'main') { + group.get('is_checked_bag_included')?.setValue(ViewChild['_checked']); + this.UpdateBag(group); + group.markAsDirty(); + } else { + if (group.get('is_checked_bag_included').value) { + if (check == 'dropdown') { + if (ViewChild?.selectedValues[0]?.value) group.get(name)?.setValue(ViewChild.selectedValues[0]?.value) + else group.get(name)?.setValue(ViewChild.selectedValues[0]) + group.markAsDirty(); + } else if (check == 'text') { + if (ViewChild?.nativeElement?.value) group.get(name)?.setValue(ViewChild.nativeElement.value) + else group.get(name)?.setValue(ViewChild.value) + group.markAsDirty(); + } + }; + } + }); + }; + copyOnUiMealIncluded(ViewChild, check, name) { + this.FlightsRate.controls.forEach((group) => { + if (check == 'main') { + if (ViewChild?.selectedValues[0]?.value) group.get('is_meal_included')?.setValue(ViewChild.selectedValues[0]?.value); + else group.get('is_meal_included')?.setValue(ViewChild.selectedValues[0]) + this.UpdateMealTypeIncluded(group); + group.markAsDirty(); + } else { + if (group.get('is_meal_included').value == 'Yes') { + if (check == 'text') { + if (ViewChild?.nativeElement?.value) group.get(name)?.setValue(ViewChild.nativeElement.value) + else group.get(name)?.setValue(ViewChild.value) + group.markAsDirty(); + }; + }; + } + }); + } + copyOnUi() { + this.FlightsRate.controls.forEach((group) => { + group.get('is_stop_sale')?.setValue(this.is_stop_sale['_checked']); + group.get('fare_family_group_id')?.setValue(this.fare_family_group_id?.selectedValues[0] || null); + group.get('fare_family_name')?.setValue(this.fare_family_name.nativeElement.value); + group.get('adt_base_fare')?.setValue(this.adt_base_fare.nativeElement.value); + group.get('adt_tax')?.setValue(this.adt_tax.nativeElement.value); + group.get('chd_base_fare')?.setValue(this.chd_base_fare.nativeElement.value); + group.get('chd_tax')?.setValue(this.chd_tax.nativeElement.value); + group.get('inf_base_fare')?.setValue(this.inf_base_fare.nativeElement.value); + group.get('inf_tax')?.setValue(this.inf_tax.nativeElement.value); + if (this.FlightContractDetails?.trip_type == 'ONEWAY') { + group.get('round_trip_discount_type')?.setValue(this.round_trip_discount_type?.selectedValues[0]?.value); + this.UpdateValidationforDiscountTypegroup(group, this.round_trip_discount_type?.selectedValues[0]?.value); + group.get('is_apply_discount_with_same_vc_only')?.setValue(this.is_apply_discount_with_same_vc_only['_checked']); + group.get('adult_round_trip_discount')?.setValue(this.adult_round_trip_discount.nativeElement.value); + group.get('child_round_trip_discount')?.setValue(this.child_round_trip_discount.nativeElement.value); + group.get('infant_round_trip_discount')?.setValue(this.infant_round_trip_discount.nativeElement.value); + } + group.get('seat_allocation')?.setValue(this.seat_allocation.nativeElement.value); + group.get('is_checked_bag_included')?.setValue(this.is_checked_bag_included['_checked']); + this.UpdateBag(group); + if (this.is_checked_bag_included['_checked']) { + group.get('adt_check_bag')?.setValue(this.adt_check_bag.nativeElement.value); + group.get('chd_check_bag')?.setValue(this.chd_check_bag.nativeElement.value); + group.get('inf_check_bag')?.setValue(this.inf_check_bag.nativeElement.value); + group.get('_check_bag_unit')?.setValue(this._check_bag_unit?.selectedValues[0]?.value); + } + group.get('adt_cabin_bag')?.setValue(this.adt_cabin_bag.nativeElement.value); + group.get('chd_cabin_bag')?.setValue(this.chd_cabin_bag.nativeElement.value); + group.get('inf_cabin_bag')?.setValue(this.inf_cabin_bag.nativeElement.value); + group.get('_cabin_bag_unit')?.setValue(this._cabin_bag_unit?.selectedValues[0]?.value); + group.get('refund_type')?.setValue(this.refund_type?.selectedValues[0]?.value); + group.get('pnr')?.setValue(this.pnr.nativeElement.value); + group.get('is_instant_confirmation')?.setValue(this.is_instant_confirmation?.selectedValues[0]?.value); + group.get('adt_fare_rule')?.setValue(this.adt_fare_rule.nativeElement.value); + group.get('chd_fare_rule')?.setValue(this.chd_fare_rule.nativeElement.value); + group.get('inf_fare_rule')?.setValue(this.inf_fare_rule.nativeElement.value); + group.get('is_meal_included')?.setValue(this.is_meal_included?.selectedValues[0]?.value); + this.UpdateMealTypeIncluded(group); + group.get('meal_details')?.setValue(this.meal_details.nativeElement.value); + group.get('inclusions')?.setValue(this.inclusions.nativeElement.value); + }) + + }; + + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (toDate && control.value < toDate) { + return { 'range': true }; + } + } + return null; + }; + } + Update_Validation() { + let from_date = this.Formdata.get('from_date').value; + if (from_date) { + this.Formdata.get("to_date").clearValidators(); + this.Formdata.get("to_date").setErrors(null); + this.Formdata.get("to_date").addValidators(Validators.compose([Validators.required, this.dateValidation(from_date)])); + this.Formdata.get("to_date").updateValueAndValidity(); + } + } + backClick() { + this.router.navigateByUrl("Services/FlightInventory/Search"); + } + selectAllDays() { + const weekDays = this.WeekDaysList.map(day => day); + this.Formdata.controls['days'].setValue(weekDays); + }; + + IsAllDaysSelected(): boolean { + let alldays = this.WeekDaysList.every(e => { + if (this.Formdata.controls['days']?.value && this.Formdata.controls['days']?.value.includes(e)) { + return true + } + return false + }) + return alldays + } + + clearAllDays() { + this.Formdata.controls['days'].setValue([]); + } +} diff --git a/src/app/modules/services/flight-inventory/flight-inventory-manage/flight-inventory-manage.module.ts b/src/app/modules/services/flight-inventory/flight-inventory-manage/flight-inventory-manage.module.ts new file mode 100644 index 0000000..aceec10 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-manage/flight-inventory-manage.module.ts @@ -0,0 +1,48 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { EditFlightDetailsComponent } from './edit-flight-details/edit-flight-details.component'; +import { CalendarModule } from 'primeng/calendar'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { EditRateInventoryComponent } from './edit-rate-inventory/edit-rate-inventory.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { ToastModule } from 'primeng/toast'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'EditFlight/:ContractId', + component: EditFlightDetailsComponent, + }, + { + path: 'EditRateInventory/:ContractId', + component: EditRateInventoryComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ + EditFlightDetailsComponent, + EditRateInventoryComponent + ], + imports: [ + CommonModule, + ToastModule, + NgSelectModule, + CalendarModule, + ReactiveFormsModule, + FormsModule, + TooltipModule, + MatCheckboxModule, + RouterModule.forChild(routes), + ], + providers:[FlightContractService] +}) +export class FlightInventoryManageModule { } diff --git a/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.html b/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.html new file mode 100644 index 0000000..57b240f --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.html @@ -0,0 +1,564 @@ + +
    +
    +
    +

    Flight Inventory

    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + + + +
    +
    +
    +

    Trip Type

    +
    + +
    +
    +
    + One Way + Round + Trip +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Validating Airline

    +
    + +
    +
    +
    + {{item.airline_name}} + ({{item.airline_code}}) + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Origin

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Destination

    +
    + +
    +
    +
    + {{item.ct}} + ({{item.ac}}) +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Departure Days

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    + +
    + Departure Date + Return + Date +
    + + Please select date type +
    +
    +
    +
    + + + + + Please select from date +
    +
    +
    +
    + + + + + Please select to date + Please + select to date greater than from date +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Currency

    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Refund Type

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    RBD

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cabin Class

    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Confirmation Type

    +
    + +
    +
    + +
    +
    +
    +
    +
    + Multi Day Operation +
    +
    + One-way sale allowed +
    +
    +
    +
    + + + + + + Download + Sample excel file +
    + +
    +
    +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Contract ID + + + + Contract Name + + + + + Validating Airline + + + + Trip Type + + + + Flight No. + + + + Origin + + + + Destination + + + + + + Contracted Cabins + + + + Contracted Pax Types + + + + Multi Day Operation + + + + Currency + + + + Updated By + + + + Updated On + + + + Status + + + Action + + + + + {{data.contract_id}} + {{data.contract_name}} + {{data.validating_airline}} + {{data.trip_type}} + {{data.flight_no}} + {{data.origin}} + {{data.destination}} + + + {{data.contracted_cabin_class}} + {{data.contracted_pax_type}} + {{data.Custom_multi_day}} + {{data.currency_code}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + {{data.status}} + + + +
    + + + + + + + + +
    + + +
    + + + No data found + + +
    +
    + + +
    +
    + + + Please + enter contract name +
    +
    + + +
    +
    + + + + +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.ts b/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.ts new file mode 100644 index 0000000..5cd2c69 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory-search/flight-inventory-search.component.ts @@ -0,0 +1,333 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightDetailsSearchModel } from 'src/app/core/models/flight-service/flight-contracts.model'; +import { FlightContractSearhObj } from 'src/app/core/models/flight-service/flight-service-search/flight-service-search.model'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-flight-inventory-search', + templateUrl: './flight-inventory-search.component.html', +}) +export class FlightInventorySearchComponent implements OnInit { + Formdata: FormGroup; + AirlineList; + FlightAllDetails; + Cdn_url = environment.cdnFileUrl; + constructor( + public ApiServ: API, + public fb: FormBuilder, + public router: Router, + public _commonService: CommonFunctionService, + public _staticService: StaticDataService, + public _flightContractService: FlightContractService, + public validationService: ValidationService + ) { } + cols: any[]; + tripType = [ + { value: 'ONEWAY', displayName: 'One Way' }, + { value: 'ROUNDTRIP', displayName: 'Round Trip' }, + ]; + confirmation_type = [ + { value: 'INSTANT', displayName: 'Instant' }, + { value: 'MANUAL', displayName: 'Manual' }, +]; + ngOnInit(): void { + this.pageSetUp() + } + pageSetUp() { + this.OnInitForm(); + this.cols = [ + { field: 'contract_id', header: 'Contract Id' }, + { field: 'contract_name', header: 'Contract Name' }, + { field: 'validating_airline', header: 'Validating Airline' }, + { field: 'trip_type', header: 'Trip Type' }, + { field: 'flight_no', header: 'Flight No' }, + { field: 'origin', header: 'Origin' }, + { field: 'destination', header: 'Destination' }, + { field: 'contracted_cabin_class', header: 'Contracted Cabins' }, + { field: 'contracted_pax_type', header: 'Contracted Pax Types' }, + { field: 'Custom_multi_day', header: 'Multi Day Operation' }, + { field: 'currency_code', header: 'Currency' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + { field: 'status', header: 'Status' }, + ]; + }; + + OnInitForm() { + this.Formdata = this.fb.group({ + contract_name: [null], + airline_code : [null], + validating_airline: [null], + flight_no: [null], + trip_type: [null], + cabin_class: [null], + origin: [null], + destination: [null], + departure_days: [null], + date_type: [null], + from_date: [null], + to_date: [null], + pnr: [null], + currency_code: [null], + refund_type: [null], + rbd: [null], + confirmation_type: [], + is_multi_day: [false], + is_oneway_sale_allowed: [false], + }); + // remove this when User want Round Trip + if (this._commonService.clientId == '2109111018200000021') { + this.Formdata.get('trip_type').setValue('ONEWAY'); + } + }; + FlightContractForm: FormGroup; + OnInitFlightContractForm(data) { + this.FlightContractForm = this.fb.group({ + contract_id: [data.contract_id], + contract_name: [data.contract_name, Validators.required], + contract_description: [data.contract_description], + }) + }; + saveFlightContract() { + let value = this.FlightContractForm.getRawValue(); + if (this.FlightContractForm.status == "INVALID") { + this.validationService.showValidationsMsg(this.FlightContractForm); + return; + } + let payloadObject = { + contract_id: value.contract_id, + contract_name: value.contract_name, + contract_description: value.contract_description, + }; + this.ApiServ.Post('/FlightContract/UpdateContractFlight', payloadObject).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + this.displayPosition = false; + if (res['status']) this.GetFlightDetails(); + } + }); + }; + + GetFlightDetails() { + let value = this.Formdata.getRawValue(); + if (this.Formdata.status == "INVALID") { + this.validationService.showValidationsMsg(this.Formdata); + setTimeout(() => { + this.validationService.scrollToError(); + }, 50); + return; + } + let Postdata = new FlightDetailsSearchModel(); + Postdata.contract_name = value.contract_name ? value.contract_name : ''; + Postdata.validating_airline = value.validating_airline ? value.validating_airline : ''; + Postdata.airline_code = value.airline_code ? value.airline_code : ''; + Postdata.trip_type = value.trip_type ? value.trip_type : ''; + Postdata.flight_no = value.flight_no ? value.flight_no : ''; + Postdata.cabin_class = value.cabin_class ? value.cabin_class: ''; + Postdata.origin = value.origin ? value.origin : ''; + Postdata.destination = value.destination ? value.destination : ''; + Postdata.departure_days = value.departure_days ? value.departure_days.join(',') : ''; + Postdata.date_type = value.date_type ? value.date_type : ''; + Postdata.from_date = value.from_date ? this._commonService.convertDateToSave(value.from_date) : ''; + Postdata.to_date = value.to_date ? this._commonService.convertDateToSave(value.to_date) : ''; + Postdata.pnr = value.pnr ? value.pnr : ''; + Postdata.currency_code = value.currency_code ? value.currency_code : ''; + Postdata.refund_type = value.refund_type ? value.refund_type : ''; + Postdata.rbd = value.rbd ? value.rbd : ''; + Postdata.confirmation_type = value.confirmation_type ? value.confirmation_type: ''; + Postdata.is_multi_day = value.is_multi_day ? value.is_multi_day : false; + Postdata.is_oneway_sale_allowed = value.is_oneway_sale_allowed ? value.is_oneway_sale_allowed : false; + this.ApiServ.Post('/FlightContract/GetAllFlightContractBySearch', Postdata).subscribe(res => { + if (res) { + this.FlightAllDetails = res.data; + if (res.data && res.data.length > 0) { + this.FlightAllDetails.forEach(e => { + e['Custom_confirmation_type'] = e.confirmation_type ? 'Yes' : 'No'; + e['Custom_multi_day'] = e.is_multi_day ? 'Yes' : 'No'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['status'] = e.is_active ? 'Active' : 'Deactive'; + }); + } + } + }); + }; + updateStatus(id, val) { + let obj = { + Id: id, + Status: !val, + }; + this.ApiServ.Post('/FlightContract/UpdateStatusContractFlight', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetFlightDetails() : ''; + } + }); + } + + + ResetForm() { + let val = this.Formdata.getRawValue() + Object.keys(val).forEach(e => { + if (e == 'is_multi_day') this.Formdata.get(e).setValue(false); + // remove this when User want Round Trip + else if (e == 'trip_type') { + if(this._commonService.clientId == '2109111018200000021')this.Formdata.get(e).setValue('ONEWAY'); + else this.Formdata.get(e).setValue(null); + } + else this.Formdata.get(e).setValue(null); + }) + }; + // + + editRateInventry(contract_id) { + let obj = { id: contract_id }; + this.router.navigate(['/Services/FlightServices/Manage/EditRateAndInventory'], { queryParams: obj }); + }; + + displayPosition: boolean; + position: string; + closeFlightContract() { + this.displayPosition = false; + this.FlightContractForm.reset(); + }; + showPositionDialog(position: string, data) { + this.OnInitFlightContractForm(data); + this.position = position; + this.displayPosition = true; + }; + + + EditFlightDetails(ContractId) { + this.router.navigate(['/Services/FlightInventory/Manage/EditFlight/' + ContractId]); + }; + CloneFlightRule(ContractId) { + this.router.navigate(['/Services/FlightInventory/Clone/' + ContractId]); + }; + EditRateInventry(ContractId) { + this.router.navigate(['/Services/FlightInventory/Manage/EditRateInventory/' + ContractId]); + }; + SelectImage(e, filedata) { + if (e.currentFiles.length != 0) { + let file = e.files[0]; + if (file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { + const reader = new FileReader(); + console.log(file) + reader.readAsText(file); // Read as binary data + reader.onload = (res) => { + const binaryString = res.target.result as string; + const hasScriptTag = this._commonService.hasScriptTagInBinary(binaryString); + if (hasScriptTag) { + filedata.clear(); + this._commonService.showMessage(false, 'Invalid file (contains script tag)'); + } else { + //base 64 + // this.HotelRoomForm.get(contol).setValue(file); + // if (fileInfo && fileInfo.length > 0 && fileArr && fileArr.length > 0) { + var formdata = new FormData(); + // fileArr.forEach((x) => { + formdata.append("file", file); + // }); + filedata.clear(); + // let file_info_list = JSON.stringify(fileInfo).replaceAll('ExtranetRoomId', edit_id); + this.ApiServ.PostFileExtranet("/FlightContract/UploadFlightContrctFromFile", formdata).subscribe(res=>{ + if(res){ + this._commonService.showMessage(res.status,res.message); + } + }); + // } + }; + } + } + } + + } + DateTypeSelection() { + let date_type = this.Formdata.value.date_type; + let from_date = this.Formdata.get('from_date').value; + this.Formdata.get("from_date").clearValidators(); + this.Formdata.get("from_date").setErrors(null); + this.Formdata.get("to_date").clearValidators(); + this.Formdata.get("to_date").setErrors(null); + if (date_type && date_type != "") { + this.Formdata.get("from_date").addValidators([Validators.required]); + this.Formdata.get("to_date").addValidators([Validators.required,this.dateValidation(from_date)]); + } + this.Formdata.get("from_date").updateValueAndValidity(); + this.Formdata.get("from_date").markAsUntouched(); + this.Formdata.get("to_date").updateValueAndValidity(); + this.Formdata.get("to_date").markAsUntouched(); + this.clearDateType(); + this.ManageDateValidations(); + } + + clearDateType() { + // Trigger 'SelectDateEvent' if both 'from_date' and 'to_date' are unset. + if(!this.Formdata.get("from_date").value && !this.Formdata.get("to_date").value) this.SelectDateEvent(); + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (toDate && control.value <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + Update_Validation(){ + let from_date = this.Formdata.get('from_date').value; + if(from_date){ + this.Formdata.get("to_date").clearValidators(); + this.Formdata.get("to_date").setErrors(null); + this.Formdata.get("to_date").addValidators(Validators.compose([Validators.required,this.dateValidation(from_date)])); + // this.Formdata.get("date_to").markAsTouched(); + this.Formdata.get("to_date").updateValueAndValidity(); + } + this.ManageDateValidations(); + } + + SelectDateEvent() { + let from_date = this.Formdata.value.from_date; + let to_date = this.Formdata.value.to_date; + this.Formdata.get("date_type").clearValidators(); + this.Formdata.get("date_type").setErrors(null); + if ((from_date || to_date) && (from_date != "" || to_date != "")) { + this.Formdata.get("date_type").addValidators([Validators.required]); + } + this.Formdata.get("date_type").updateValueAndValidity(); + // this.Formdata.get("date_type").markAsUntouched(); + this.Update_Validation() + } + ManageDateValidations() { + const from_date = this.Formdata.get('from_date').value; + const to_date = this.Formdata.get('to_date').value; + const date_type = this.Formdata.get('date_type').value; + const hasValue = from_date || to_date || date_type; + if (hasValue) { + this.Formdata.get("date_type").setValidators(date_type ? null : Validators.required); + this.Formdata.get("from_date").setValidators(from_date ? null : Validators.required); + if(from_date){ + this.Formdata.get("to_date").addValidators([Validators.required, this.dateValidation(from_date)]); + } + } else { + this.Formdata.get("from_date").clearValidators(); + this.Formdata.get("to_date").clearValidators(); + this.Formdata.get("date_type").clearValidators(); + } + + this.Formdata.get("from_date").updateValueAndValidity(); + this.Formdata.get("to_date").updateValueAndValidity(); + this.Formdata.get("date_type").updateValueAndValidity(); + } + btnClick() { + this.router.navigateByUrl("Services/FlightInventory/Add"); + } +} diff --git a/src/app/modules/services/flight-inventory/flight-inventory.module.ts b/src/app/modules/services/flight-inventory/flight-inventory.module.ts new file mode 100644 index 0000000..4eead87 --- /dev/null +++ b/src/app/modules/services/flight-inventory/flight-inventory.module.ts @@ -0,0 +1,67 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { FlightInventorySearchComponent } from './flight-inventory-search/flight-inventory-search.component'; +import { FlightInventoryAddComponent } from './flight-inventory-add/flight-inventory-add.component'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'primeng/calendar'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { ToastModule } from 'primeng/toast'; +import { TableModule } from 'primeng/table'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MessageService } from 'primeng/api'; +import { InputTextModule } from 'primeng/inputtext'; +import { DialogModule } from 'primeng/dialog'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FileUploadModule } from 'primeng/fileupload'; +import { FlightContractService } from 'src/app/core/services/flight-contract.service.ts/flight-contract.service'; + +const routes: Routes = [ + { + path: 'Search', + component: FlightInventorySearchComponent, + }, + { + path: 'Add', + component: FlightInventoryAddComponent, + }, + { + path: 'Clone/:RuleId', + component: FlightInventoryAddComponent, + }, + { + path: 'Manage', + loadChildren: () => + import('./flight-inventory-manage/flight-inventory-manage.module').then( + (m) => m.FlightInventoryManageModule + ), + }, +] + +@NgModule({ + declarations: [ + FlightInventorySearchComponent, + FlightInventoryAddComponent + ], + imports: [ + ToastModule, + TableModule, + DialogModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + RouterModule.forChild(routes), + ], + providers: [MessageService,FlightContractService], +}) +export class FlightInventoryModule { } diff --git a/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.html b/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.html new file mode 100644 index 0000000..bc124e6 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.html @@ -0,0 +1,1125 @@ +
    + + Back +
    +
    Add Flight Contract
    +
    +
    +
    +
    + + + Please + contract name +
    +
    +
    + + +
    +
    +
    + + + +
    + +
    Trip Type
    +
    + +
    +
    + Please + select trip type +
    +
    + + + +
    + +
    From
    +
    + +
    +
    + Please + select from +
    +
    + + + +
    + +
    To
    +
    + +
    +
    + Please + select to +
    + +
    + + + Please + enter pnr +
    +
    + + + +
    + +
    Currency Code
    +
    + +
    +
    + Please + select currency +
    +
    + + + +
    + +
    Confirmation Type
    +
    + +
    +
    + Please + select confirmation type +
    +
    + + + +
    + +
    Contracted Cabins
    +
    + +
    +
    + Please + select contracted cabins +
    +
    + + + +
    + +
    Contracted Pax Types
    +
    + +
    +
    + Please + select contracted pax types +
    +
    + + + +
    + +
    Validating Airline
    +
    + +
    +
    + Please + select validating airline +
    +
    +
    + Is Multi Day Operation + +
    +
    +
    + + + Please + select outbound date +
    +
    + + +
    +
    + + + +
    + +
    Multi Day Operation Type
    +
    + +
    +
    + Please + select multi day operation type +
    +
    + + + Please + select operation valid from +
    +
    + + + Please + select operation valid to +
    +
    + + + +
    + +
    Outbound Days
    +
    + +
    +
    + Please + select outbound days +
    +
    + + + + Please + select outbound dates +
    +
    +
    +
    +
    Outbound
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    Airline code
    +
    Flight no.Aircraft TypeOriginDestinationDeparture TimeDeparture TerminalIs Next Day ArrivalArrival TimeArrival TerminalFlying TimeIs Departure Next Day
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    Return
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    Airline code
    +
    Flight no.Aircraft TypeOriginDestinationDeparture TimeDeparture TerminalIs Next Day ArrivalArrival TimeArrival TerminalFlying TimeIs Departure Next Day
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    Fare details
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    RBD
    +
    Cabin ClassAdult Base FareAdult TaxesChild Base FareChild TaxesInfant Base FareInfant TaxesSeats AllocationAdult Check BagChild Check BagInfant Check BagCheck Bag UnitAdult Cabin BagChild Cabin BagInfant Cabin BagCabin Bag UnitFare TypeAdult Fare RuleChild Fare RuleInfant Fare RuleMeal IncludedMeal DetailsInclusions
    +
    + + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + Is Active +
    +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.ts b/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.ts new file mode 100644 index 0000000..61e4bb7 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-add/flight-services-add.component.ts @@ -0,0 +1,605 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightContractDTO, FlightDetailDto, FlightsRateDto } from 'src/app/core/models/flight-service/flight-contracts.model'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-flight-services-add', + templateUrl: './flight-services-add.component.html', +}) +export class FlightServicesAddComponent implements OnInit { + + + constructor(public ApiServ: API, public Fb: FormBuilder, + public validationService: ValidationService, public CommonVar: StaticDataService, + public MsgService: MessageService, public router: Router) { } + Formdata: FormGroup; + CurrencyList; + AirCabinClassList; + AirPaxTypeList; + AtoZ = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + lovKeyDataObj = { + AirCabinClass: [], + AirPaxType: [], + AirTripType: [], + DaySelect: [], + AirBaggageUnit: [], + AirFareType: [], + }; + AirportListFrom; + AirportListTO; + AirlineList; + AllAircraftTypeList; + + + ngOnInit(): void { + this.GetCurrency(); + this.GetLOVKeys('AirCabinClass,AirPaxType,AirTripType,DaySelect,AirBaggageUnit,AirFareType'); + this.OnInitForm(); + this.GetAllAircraftType(); + } + + ToasterMsg(msg) { + this.MsgService.add({ + severity: "error", + detail: msg, + }); + } + + + + OnInitForm() { + this.Formdata = this.Fb.group({ + contract_name: this.validationService.required, + contract_description: [''], + _trip_type: [1, Validators.required], + from_airport: this.validationService.required, + to_airport: this.validationService.required, + pnr: this.validationService.required, + currency_code: this.validationService.required, + is_instant_confirmation: ['Instant', Validators.required], + contracted_cabin: this.validationService.required, + contracted_pax_types: this.validationService.required, + validating_airline: this.validationService.required, + is_multi_day: [false], + outbound_date: this.validationService.required, + return_date: [''], + is_multi_day_range: [''], + operation_from: [''], + operation_to: [''], + outbound_days: [''], + outbound_dates: [''], + + FlightDetail: this.Fb.array([ + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: this.validationService.required, + to_airport: this.validationService.required, + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + arrival_hour: [''], + arrival_minutes: [''], + arrival_terminal: [''], + flying_duration_hour: [''], + flying_duration_minutes: [''], + is_next_day_departure: [false], + }) + ]), + + FlightsRate: this.Fb.array([ + this.Fb.group({ + rbd: this.validationService.required, + cabin_class: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + chd_base_fare: this.validationService.decimal, + chd_tax: this.validationService.decimal, + inf_base_fare: this.validationService.decimal, + inf_tax: this.validationService.decimal, + seat_allocation: this.validationService.number, + seat_booked: [''], // + seat_remaining: [''], // + adt_check_bag: this.validationService.number, + chd_check_bag: this.validationService.number, + inf_check_bag: this.validationService.number, + _check_bag_unit: this.validationService.required, + adt_cabin_bag: this.validationService.number, + chd_cabin_bag: this.validationService.number, + inf_cabin_bag: this.validationService.number, + _cabin_bag_unit: this.validationService.required, + _fare_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + chd_fare_rule: this.validationService.required, + inf_fare_rule: this.validationService.required, + is_meal_included: [''], + meal_details: [''], + inclusions: [''], + is_instant_confirmation: [''], + is_stop_sale: [''], + }) + ]), + is_active: [false] + }); + }; + + get FlightDetail() { + return this.Formdata.get('FlightDetail') as FormArray; + } + get FlightsRate() { + return this.Formdata.get('FlightsRate') as FormArray; + } + get FlightRateDetail() { + return this.Formdata.get('FlightRateDetail') as FormArray; + } + + addFlightGroupBtn(FormName) { + let formgroup; + FormName == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.FlightRateDetail; + + formgroup.push( + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: this.validationService.required, + to_airport: this.validationService.required, + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + arrival_hour: [''], + arrival_minutes: [''], + arrival_terminal: [''], + flying_duration_hour: [''], + flying_duration_minutes: [''], + is_next_day_departure: [false], + }) + ); + }; + addFlightsRateGroupBtn() { + this.FlightsRate.push(this.Fb.group({ + rbd: this.validationService.required, + cabin_class: this.validationService.required, + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + chd_base_fare: this.validationService.decimal, + chd_tax: this.validationService.decimal, + inf_base_fare: this.validationService.decimal, + inf_tax: this.validationService.decimal, + seat_allocation: this.validationService.number, + seat_booked: [''], // + seat_remaining: [''], // + adt_check_bag: this.validationService.number, + chd_check_bag: this.validationService.number, + inf_check_bag: this.validationService.number, + _check_bag_unit: this.validationService.required, + adt_cabin_bag: this.validationService.number, + chd_cabin_bag: this.validationService.number, + inf_cabin_bag: this.validationService.number, + _cabin_bag_unit: this.validationService.required, + _fare_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + chd_fare_rule: this.validationService.required, + inf_fare_rule: this.validationService.required, + is_meal_included: [''], + meal_details: [''], + inclusions: [''], + is_instant_confirmation: [''], + is_stop_sale: [''], + })) + } + removeFlightGroupBtn(ind, formname) { + let formgroup; + formname == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.FlightRateDetail; + formgroup.removeAt(ind); + }; + + removeFlightsRateGroupBtn(ind) { + this.FlightsRate.removeAt(ind); + }; + RemoveFlightrRoundArr() { + this.Formdata.removeControl('FlightRateDetail'); + }; + + AddFLightRoundArr() { + this.Formdata.addControl( + 'FlightRateDetail', this.Fb.array([ + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: this.validationService.required, + to_airport: this.validationService.required, + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + arrival_hour: [''], + arrival_minutes: [''], + arrival_terminal: [''], + flying_duration_hour: [''], + flying_duration_minutes: [''], + is_next_day_departure: [false], + }) + ]) + ); + }; + + trip_type(val) { + console.log(val) + if (val == 2) { + this.Formdata.get('is_multi_day').setValue(false) + this.AddFLightRoundArr() + } else this.RemoveFlightrRoundArr() + + } + + GetCurrency() { + this.ApiServ.Get('/Currency/GetCurrency').subscribe(obj => { + if (obj) { + this.CurrencyList = obj; + } + }) + } + + getAirportDetails(val, check) { + if (val.length >= 3) { + this.ApiServ.Get('/MasterSearch/GetAllMasterSearch/en/' + val).subscribe(obj => { + if (obj) { + if (check) this.AirportListFrom = obj; + if (!check) this.AirportListTO = obj; + } + }); + } + } + GetAllAirline(val) { + if (val) { + this.ApiServ.Get('/MasterSearch/GetAllAirline/en/' + val).subscribe(obj => { + if (obj) { + this.AirlineList = obj; + } + }); + } + } + + GetAllAircraftType() { + this.ApiServ.Get('/MasterSearch/GetAllAircraftType').subscribe(obj => { + if (obj) { + this.AllAircraftTypeList = obj; + } + }); + } + + + + + + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + }; + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + }; + + + + // validation + + nextdayarrivelcheck(check, ind, formname) { + if (check) { + this.AddOutboundtvalid(ind, 'arrival_hour', 'add', formname); + this.AddOutboundtvalid(ind, 'arrival_minutes', 'add', formname); + this.AddOutboundtvalid(ind, 'arrival_terminal', 'add', formname); + this.AddOutboundtvalid(ind, 'flying_duration_hour', 'add', formname); + this.AddOutboundtvalid(ind, 'flying_duration_minutes', 'add', formname); + } else { + this.AddOutboundtvalid(ind, 'arrival_hour', 'remove', formname); + this.AddOutboundtvalid(ind, 'arrival_minutes', 'remove', formname); + this.AddOutboundtvalid(ind, 'arrival_terminal', 'remove', formname); + this.AddOutboundtvalid(ind, 'flying_duration_hour', 'remove', formname); + this.AddOutboundtvalid(ind, 'flying_duration_minutes', 'remove', formname); + } + + } + + + MealTypeIncludedcheck(val, ind) { + console.log(val) + if (val == 'Yes') this.addvalidMealTypeIncluded(ind, 'meal_details', 'add') + else this.addvalidMealTypeIncluded(ind, 'meal_details', 'remove') + + } + + AddOutboundtvalid(index, name, type, formname) { + let formgroup; + formname == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.FlightRateDetail + if (type == 'add') { + formgroup.controls[index].get(name).addValidators([Validators.required]); + formgroup.controls[index].get(name).updateValueAndValidity(); + } else { + formgroup.controls[index].get(name).clearValidators(); + formgroup.controls[index].get(name).updateValueAndValidity(); + formgroup.controls[index].get(name).markAsUntouched(); + } + }; + addvalidMealTypeIncluded(index, name, type) { + if (type == 'add') { + this.FlightsRate.controls[index].get(name).addValidators([Validators.required]); + this.FlightsRate.controls[index].get(name).updateValueAndValidity(); + } else { + this.FlightsRate.controls[index].get(name).clearValidators(); + this.FlightsRate.controls[index].get(name).updateValueAndValidity(); + this.FlightsRate.controls[index].get(name).markAsUntouched(); + } + }; + addvalid(name, type) { + if (type == 'add') { + this.Formdata.controls[name].addValidators([Validators.required]); + this.Formdata.controls[name].updateValueAndValidity(); + } else { + this.Formdata.controls[name].clearValidators(); + this.Formdata.controls[name].updateValueAndValidity(); + this.Formdata.controls[name].markAsUntouched(); + } + }; + // + multi_day_check(val) { + console.log(val) + if (val) { + this.addvalid('is_multi_day_range', 'add'); + this.addvalid('operation_from', 'add'); + this.addvalid('operation_to', 'add'); + } else { + this.addvalid('is_multi_day_range', 'remove'); + this.addvalid('operation_from', 'remove'); + this.addvalid('operation_to', 'remove'); + this.Formdata.get('is_multi_day_range').setValue('') + } + } + multi_day_range(val) { + if (val == 'Range') { + this.addvalid('outbound_dates', 'remove'); + this.addvalid('outbound_days', 'add'); + } else { + this.addvalid('outbound_days', 'remove'); + this.addvalid('outbound_dates', 'add'); + } + } + + // save + saveData() { + let value = this.Formdata.getRawValue(); + let OutbondList = this.FlightDetail.getRawValue(); + let lastNumber = OutbondList.length - 1; + + console.log(value) + if (this.Formdata.status == "INVALID") { + this.validationService.showValidationsMsg(this.Formdata); + return; + } + if (!OutbondList[lastNumber].to_airport && !value.to_airport && !value.from_airport && !OutbondList[0].from_airport) { + this.ToasterMsg("Please enter departure and arrival city or airport") + return; + } + if (OutbondList[lastNumber].to_airport != value.to_airport || OutbondList[0].from_airport != value.from_airport) { + this.ToasterMsg("Departure must be different from arrival") + return; + }; + + let FlightRateVal = this.FlightsRate.getRawValue(); + let date = moment(new Date).format('YYYY-MM-DD'); + let AllFlightDetailslist = []; + + + /// flight details + + OutbondList.map((e, i) => { + let fligtDetlPostData = new FlightDetailDto(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + // fligtDetlPostData._aircraft_type = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = date + 'T' + e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = date + 'T' + e.arrival_hour + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = date + 'T' + e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00'; + fligtDetlPostData._sector_type = '1'; + fligtDetlPostData.leg_nbr = i + 1; + console.log(fligtDetlPostData); + AllFlightDetailslist.push(fligtDetlPostData); + }); + + if (value._trip_type == 2) { + let returnList = this.FlightRateDetail.getRawValue(); + let last = returnList.length - 1; + if (!returnList[last].to_airport && !value.to_airport && !value.from_airport && !returnList[0].from_airport) { + this.ToasterMsg("Please enter departure and arrival city or airport") + return; + } + if (returnList[last].to_airport != value.from_airport || returnList[0].from_airport != value.to_airport) { + this.ToasterMsg("Departure must be different from arrival") + return; + }; + returnList.map((e, i) => { + let fligtDetlPostData = new FlightDetailDto(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + // fligtDetlPostData._aircraft_type = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = date + 'T' + e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = date + 'T' + e.arrival_hour + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = date + 'T' + e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00'; + fligtDetlPostData._sector_type = '2'; + fligtDetlPostData.leg_nbr = i + 1; + console.log(fligtDetlPostData); + AllFlightDetailslist.push(fligtDetlPostData); + }); + }; + + + // flight Rate + let FlightRate = [] + FlightRateVal.map(e => { + let Ratepostdata = new FlightsRateDto(); + Ratepostdata.rbd = e.rbd; + Ratepostdata.cabin_class = this.checkClassType(e.cabin_class); + Ratepostdata.adt_base_fare = e.adt_base_fare; + Ratepostdata.adt_tax = e.adt_tax; + Ratepostdata.chd_base_fare = e.chd_base_fare; + Ratepostdata.chd_tax = e.chd_tax; + Ratepostdata.inf_base_fare = e.inf_base_fare; + Ratepostdata.inf_tax = e.inf_tax; + Ratepostdata.seat_allocation = e.seat_allocation; + Ratepostdata.seat_booked = 0; // + Ratepostdata.seat_remaining = 0; // + Ratepostdata.adt_check_bag = e.adt_check_bag; + Ratepostdata.chd_check_bag = e.chd_check_bag; + Ratepostdata.inf_check_bag = e.inf_check_bag; + Ratepostdata._check_bag_unit = e._check_bag_unit; + Ratepostdata.adt_cabin_bag = e.adt_cabin_bag; + Ratepostdata.adt_fare_rule = e.adt_fare_rule; + Ratepostdata.chd_cabin_bag = e.chd_cabin_bag; + Ratepostdata.inf_cabin_bag = e.inf_cabin_bag; + Ratepostdata._cabin_bag_unit = e._cabin_bag_unit; + Ratepostdata._fare_type = e._fare_type; + Ratepostdata.adt_fare_rule = e.adt_fare_rule; + Ratepostdata.chd_fare_rule = e.chd_fare_rule; + Ratepostdata.is_meal_included = e.is_meal_included == 'Yes' ? true : false; + Ratepostdata.meal_details = e.is_meal_included == 'Yes' ? e.meal_details : ''; + Ratepostdata.inclusions = e.inclusions; + Ratepostdata.inf_fare_rule = e.inf_fare_rule; + Ratepostdata.pnr = value.pnr; + FlightRate.push(Ratepostdata) + + }) + + // Post data + + let PostData = new FlightContractDTO(); + PostData.contract_name = value.contract_name; + PostData.contract_description = value.contract_description; + PostData._trip_type = value._trip_type.toString(); + PostData.from_airport = value.from_airport; + PostData.to_airport = value.to_airport; + PostData.pnr = value.pnr; + PostData.is_instant_confirmation = value.is_instant_confirmation == 'Instant' ? true : false; + PostData.is_economy = false; + PostData.is_premium_economy = false; + PostData.is_business = false; + PostData.is_first_class = false; + + value.contracted_cabin ? value.contracted_cabin.map(e => { + e == 1 ? PostData.is_economy = true : ''; + e == 2 ? PostData.is_premium_economy = true : ''; + e == 3 ? PostData.is_business = true : ''; + e == 4 ? PostData.is_first_class = true : ''; + }) : '' + PostData.is_adult = false; + PostData.is_child = false; + PostData.is_infant = false; + value.contracted_pax_types ? value.contracted_pax_types.map(e => { + e == 1 ? PostData.is_adult = true : ''; + e == 2 ? PostData.is_child = true : ''; + e == 3 ? PostData.is_infant = true : ''; + }) : '' + PostData.is_all_pax_type = PostData.is_adult && PostData.is_child && PostData.is_infant ? true : false; + PostData.validating_airline = value.validating_airline; + PostData.is_multi_day = value.is_multi_day; + PostData.outbound_date = moment(value.outbound_date).format('YYYY-MM-DD'); + PostData.return_date = value._trip_type == 2 ? value.return_date ? moment(value.return_date).format('YYYY-MM-DD') : '' : date; + PostData.is_multi_day_range = value.is_multi_day_range == 'Range' ? true : false; + PostData.operation_from = value.is_multi_day ? value.operation_from ? moment(value.operation_from).format('YYYY-MM-DD') : '' : date; + PostData.operation_to = value.is_multi_day ? value.operation_to ? moment(value.operation_to).format('YYYY-MM-DD') : '' : date; + PostData.outbound_days = value.is_multi_day && value.is_multi_day_range == 'Range' ? value.outbound_days.join(',') : ''; + let outbond_dates = [] + value.outbound_dates ? value.outbound_dates.map(e => outbond_dates.push(moment(e).format('YYYY-MM-DD'))) : '' + PostData.outbound_dates = value.is_multi_day && value.is_multi_day_range != 'Range' ? outbond_dates ? outbond_dates.join(',') : '' : ''; + PostData.supplier_id = ''; + PostData.is_active = value.is_active; + PostData.currency_code = value.currency_code; + PostData.flightDetail = AllFlightDetailslist; + PostData.flightRate = FlightRate; + PostData.org_id = '2105311837100000021'; + + console.log(PostData) + this.ApiServ.Post('/FlightContract/SaveFlightContracts', PostData).subscribe(obj => { + if (obj) { + this.MsgService.add({ + severity: obj["status"] ? "success" : "error", + detail: obj["message"], + }); + obj["status"] ? setTimeout(() => { + this.router.navigate(['/Services/FlightServices/Search']) + }, 500) : ''; + } + }); + + }; + + // + + checkClassType(classType) { + let value = '' + if (classType == 4) { + value = 'F' + } else if (classType == 3) { + value = 'J' + } else if (classType == 2) { + value = 'W' + } else if (classType == 1) { + value = 'Y' + } + return value + } + + + // static dropdown + + + Confirmation_Type = [ + { id: 0, name: 'Instant' }, + { id: 1, name: 'Manual' }, + ]; + Multi_day_type = [ + { name: 'Range' }, + { name: 'Specific Dates' }, + + ]; + + Option = [ + { id: 2, name: 'Yes' }, + { id: 3, name: 'No' }, + ]; + + +} diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.html b/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.html new file mode 100644 index 0000000..5db6ff0 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.html @@ -0,0 +1,56 @@ +
    +
    Add Flight Contract
    +
    +
    + + +
    +
    + + +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Contracted Pax Types
    +
    + +
    +
    +
    +
    +
    + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.ts b/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.ts new file mode 100644 index 0000000..693e1a8 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-contract/edit-contract-details.ts @@ -0,0 +1,117 @@ +import { Component, Inject } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ActivatedRoute } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { ContractDetailDto } from 'src/app/core/models/flight-service/flight-service-manage/edit-contract-details.model'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + templateUrl: './edit-contract-details.html', +}) +export class EditContractDetailsComponents { + + Formdata: FormGroup; + constructor(@Inject(MAT_DIALOG_DATA) public data: any, public ApiServ: API, + public Fb: FormBuilder, public route: ActivatedRoute, public MsgService: MessageService) { } + AircabinList; + AirpaxList; + cabin_type = []; + pax_type = []; + ngOnInit(): void { + this.Formdata = this.Fb.group({ + contract_name: [''], + contract_description: [''], + contracted_cabins: [null], + contracted_pax_types: [null] + }); + + this.GetLOVHotelPickupPointType(); + } + + + GetLOVHotelPickupPointType() { + let formdata = { + "lov_types": [ + { "lov_type": "AirCabinClass" }, + { "lov_type": "AirPaxType" }, + ], + "lov_lang": "en" + } + this.ApiServ.Post("/LovMaster/GetLov", formdata).subscribe(data => { + if (data) { + this.AircabinList = data.responseObject[0].keys; + this.AirpaxList = data.responseObject[1].keys; + this.ApiServ.Get('/FlightContract/GetFlightContract?ContractId=' + this.data.contractId).subscribe(data => { + console.log(data) + this.SetFormValue(data.responseObject) + }); + } + }); + }; + + + + +SetFormValue(data) { + this.cabin_type = [] + this.pax_type = [] + Object.keys(data).forEach(e => { + if (e == 'contract_name' || e == 'contract_description') { + this.Formdata.get(e).setValue(data[e]) + } else if (e == 'is_all_pax_type' || e == 'is_premium_economy' || e == 'is_economy' || e == 'is_business' || e == 'is_first_class') { + let arr = [] + + 'is_economy' == e && data[e] ? this.cabin_type.push(1) : '' + 'is_premium_economy' == e && data[e] ? this.cabin_type.push(2) : '' + 'is_business' == e && data[e] ? this.cabin_type.push(3) : '' + 'is_first_class' == e && data[e] ? this.cabin_type.push(4) : '' + this.Formdata.get('contracted_cabins').setValue(this.cabin_type); + } else if (e == 'is_adult' || e == 'is_child' || e == 'is_infant') { + e == 'is_adult' && data[e] ? this.pax_type.push(1) : '' + e == 'is_child' && data[e] ? this.pax_type.push(2) : '' + e == 'is_infant' && data[e] ? this.pax_type.push(3) : '' + this.Formdata.get('contracted_pax_types').setValue(this.pax_type) + } + }); +}; +saveformData() { + let value = this.Formdata.getRawValue(); + let postdata = new ContractDetailDto(); + postdata.contract_name = value.contract_name; + postdata.contract_description = value.contract_description; + postdata.contract_id = this.data.contractId; + postdata.is_economy = false; + postdata.is_premium_economy = false; + postdata.is_business = false; + postdata.is_first_class = false; + value.contracted_cabins ? value.contracted_cabins.map(e => { + e == 1 ? postdata.is_economy = true : ''; + e == 2 ? postdata.is_premium_economy = true : ''; + e == 3 ? postdata.is_business = true : ''; + e == 4 ? postdata.is_first_class = true : ''; + }) : '' + postdata.is_adult = false; + postdata.is_child = false; + postdata.is_infant = false + value.contracted_pax_types ? value.contracted_pax_types.map(e => { + e == 1 ? postdata.is_adult = true : ''; + e == 2 ? postdata.is_child = true : ''; + e == 3 ? postdata.is_infant = true : ''; + }) : '' + postdata.is_all_pax_type = postdata.is_adult && postdata.is_child && postdata.is_infant ? true : false; + + this.ApiServ.Post("/FlightContract/UpdateContractDetails", postdata).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + } + }); +} + + + +} + diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.html b/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.html new file mode 100644 index 0000000..97f8c3f --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.html @@ -0,0 +1,604 @@ +
    + + Back +
    +
    Date Filter
    +
    +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + Please + select dates +
    +
    + + + +
    + +
    Outbound Days
    +
    + +
    +
    + Please + select days +
    +
    +
    +
    +
    Depature
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    Airline code
    +
    Flight no.Aircraft TypeOriginDestinationDeparture TimeDeparture TerminalIs Next Day ArrivalArrival TimeArrival TerminalFlying TimeIs Departure Next Day
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    + +
    Return
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    Airline code
    +
    Flight no.Aircraft TypeOriginDestinationDeparture TimeDeparture TerminalIs Next Day ArrivalArrival TimeArrival TerminalFlying TimeIs Departure Next Day
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    + + + +
    + +
    Pickup Time
    +
    + +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    + +
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.ts b/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.ts new file mode 100644 index 0000000..69d2fc0 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-flight-details/edit-flight-details.component.ts @@ -0,0 +1,546 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Route, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { StaticDataService } from 'src/app/core/common/static-data.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FlightDetailobj, UpdateFlightDetail } from 'src/app/core/models/flight-service/flight-service-manage/edit-flight-details.model'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-edit-flight-details', + templateUrl: './edit-flight-details.component.html', +}) +export class EditFlightDetailsComponent implements OnInit { + + constructor(public router: ActivatedRoute, + private ApiServ: API, + public Fb: FormBuilder, public CommonVar: StaticDataService, + public validationService: ValidationService, + public MsgService: MessageService, public route: Router + ) { } + contract_id; + Formdata: FormGroup; + SearchForm: FormGroup; + is_search = false; + is_round_trip = false; + AirportListFrom; + AirportListTO; + lovKeyDataObj = { + DaySelect: [], + }; + AirlineList; + datelist; + AllAircraftTypeList + @ViewChild('calender') calender + + + + + ngOnInit(): void { + this.GetAllAircraftType(); + this.checkIsRangetype(); + this.OnIntForm(); + this.GetLOVKeys('DaySelect'); + } + + checkDateForHighlight(date) { + let month = date.month > 9 ? date.month : '0' + date.month; + let d = new Date(date.year, date.month, date.day); + let new_Date = month + '-' + date.day + '-' + date.year; + let Checkformat = moment(new_Date).format('MM-DD-YYYY') + let validate; + validate = false; + if (new_Date == Checkformat) { + let format = moment(d).format('MM-DD-YYYY') + let valid = this.datelist.filter(e => e == format) + if (valid.length > 0) { + validate = true; + } + } + return validate + } + + checkIsRangetype() { + this.router.queryParams.subscribe(obj => { + this.contract_id = obj['id'] + this.ApiServ.Get('/FlightContract/GetFlightDates?ContractId=' + this.contract_id).subscribe(data => { + if (data) { + this.GetFlightDetails(); + if (data.responseObject.is_multi_day && !data.responseObject.is_round_trip) { + this.SetTimeAvali(data.responseObject.dates); + this.is_search = false; + this.setFilterValid(true); + } else { + this.is_search = true; + this.AddFLightRoundArr(); + this.Formdata.removeControl('date') + this.Formdata.removeControl('days') + } + if (data.responseObject.is_round_trip) { + this.is_round_trip = true; + } + + } + }); + }) + } + formDate; + SetTimeAvali(allDate) { + this.datelist = allDate.split(','); + let obj = []; + this.datelist.map(e => { + obj.push(moment(e).format('MM-DD-YYYY')); + }) + this.datelist = obj; + } + // + DateRangecheck() { + let date_range = this.Formdata.get('date').value + if (date_range[1]) { + this.calender.overlayVisible = false; + let AllSelectDate = [] + this.datelist.filter(e => { + let from = moment(date_range[0]).format('MM:DD:YYYY').split(':') + let To = moment(date_range[1]).format('DD:MMM:YYYY').split(':') + let maindate = moment(e).format('DD:MMM:YYYY').split(':') + if (from[1] == maindate[1] || To[1] == maindate[1]) { + let date = new Date(e).getDate(); + let St = new Date(date_range[0]).getDate(); + let et = new Date(date_range[1]).getDate(); + (date >= St && date <= et) ? AllSelectDate.push(e) : '' + } + }) + this.formDate = AllSelectDate; + console.log(AllSelectDate) + } + } + + GetFlightDetails() { + this.ApiServ.Get('/FlightContract/GetFlightDetails?ContractId=' + this.contract_id).subscribe(data => { + if (data) { + this.SetValForm(data.responseObject) + } + }); + } + + + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + }; + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + }; + + OnIntForm() { + this.Formdata = this.Fb.group({ + date: this.validationService.required, + days: this.validationService.required, + FlightDetail: this.Fb.array([ + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: [{ value: '', disabled: true }, Validators.required], + to_airport: [{ value: '', disabled: true }, Validators.required], + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + sector_nbr: [], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: this.validationService.required, + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [false], + }) + ]) + + }); + } + + get FlightDetail() { + return this.Formdata.get('FlightDetail') as FormArray; + } + get Return_flight() { + return this.Formdata.get('Return_flight') as FormArray; + } + + + + // all hit + + + GetAllAirline(val) { + if (val) { + this.ApiServ.Get('/MasterSearch/GetAllAirline/en/' + val).subscribe(obj => { + if (obj) { + this.AirlineList = obj; + } + }); + } + } + + GetAllAircraftType() { + this.ApiServ.Get('/MasterSearch/GetAllAircraftType').subscribe(obj => { + if (obj) { + this.AllAircraftTypeList = obj; + } + }); + } + + getAirportDetails(val, check) { + if (val.length >= 3) { + this.ApiServ.Get('/MasterSearch/GetAllMasterSearch/en/' + val).subscribe(obj => { + if (obj) { + if (check) this.AirportListFrom = obj; + if (!check) this.AirportListTO = obj; + } + }); + } + } + + addFlightGroupBtn(FormName) { + let formgroup + FormName == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.Return_flight + formgroup.push( + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: [{ value: '', disabled: true }, Validators.required], + to_airport: [{ value: '', disabled: true }, Validators.required], + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + sector_nbr: [''], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: this.validationService.required, + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [false], + }) + ) + }; + removeFlightGroupBtn(ind, formname) { + let formgroup + formname == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.Return_flight + formgroup.removeAt(ind); + }; + Saveflightdetails() { + if (this.Formdata.status == "INVALID") { + this.validationService.showValidationsMsg(this.Formdata); + return; + } + let value = this.Formdata.getRawValue(); + let OutbondList = this.FlightDetail.getRawValue() + let returnList = this.Return_flight ? this.Return_flight.getRawValue() : [] + let date = moment(new Date).format('YYYY-MM-DD'); + let AllFlightDetailslist = []; + OutbondList.map((e, i) => { + let fligtDetlPostData = new FlightDetailobj(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + // fligtDetlPostData._aircraft_type = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = date + 'T' + e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = date + 'T' + e.arrival_hour + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = date + 'T' + e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00'; + fligtDetlPostData._sector_type = '1'; + fligtDetlPostData.sector_nbr = e.sector_nbr; + fligtDetlPostData.leg_nbr = i + 1; + AllFlightDetailslist.push(fligtDetlPostData); + }); + + this.is_search ? returnList.map((e, i) => { + let fligtDetlPostData = new FlightDetailobj(); + fligtDetlPostData.airline_code = e.airline_code + fligtDetlPostData.flight_no = e.flight_no; + // fligtDetlPostData._aircraft_type = e._aircraft_type; + fligtDetlPostData.from_airport = e.from_airport; + fligtDetlPostData.to_airport = e.to_airport; + fligtDetlPostData.departure_time = date + 'T' + e.departure_Hour + ':' + e.departure_minutes + ':00'; + fligtDetlPostData.is_next_day_departure = e.is_next_day_departure; + fligtDetlPostData.departure_terminal = e.departure_terminal; + fligtDetlPostData.is_next_day_arrival = e.is_next_day_arrival; + fligtDetlPostData.arrival_time = date + 'T' + e.arrival_hour + ':' + e.arrival_minutes + ':00'; + fligtDetlPostData.arrival_terminal = e.arrival_terminal; + fligtDetlPostData.flying_duration = date + 'T' + e.flying_duration_hour + ':' + e.flying_duration_minutes + ':00'; + fligtDetlPostData._sector_type = '2'; + fligtDetlPostData.sector_nbr = e.sector_nbr; + fligtDetlPostData.leg_nbr = i + 1; + AllFlightDetailslist.push(fligtDetlPostData); + }) : ''; + + let postdata = new UpdateFlightDetail(); + postdata.contract_id = this.contract_id; + postdata.departure_dates = this.is_search ? '' : this.formDate.join(','); + postdata.flight_detail = AllFlightDetailslist; + postdata.outbound_days = this.is_search ? '' : value.days.join(','); + this.ApiServ.Post('/FlightContract/UpdateFlightDetails', postdata).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + data["status"] ? setTimeout(() => { + this.route.navigate(['/Services/FlightServices/Search']) + }, 500) : ''; + } + }); + + + }; + SetValForm(Obj) { + let departure = Obj.filter(e => e._sector_type == '1') + let Round = Obj.filter(e => e._sector_type == '2') + let departure_arr = departure.sort((a, b) => a.leg_nbr - b.leg_nbr) + let round_arr = Round.sort((a, b) => a.leg_nbr - b.leg_nbr) + departure_arr ? departure_arr.map((list_obj, i) => { + i == 0 ? '' : this.addFlightGroupBtn('FlightDetail') + Object.keys(list_obj).forEach(d => { + if (d == 'arrival_hour') { + this.FlightDetail.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'sector_nbr') { + this.FlightDetail.controls[i].get('sector_nbr').setValue(list_obj[d]) + } else if (d == 'airline_code') { + this.GetAllAirline(list_obj[d]) + this.FlightDetail.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'flight_no' || d == '_aircraft_type' || d == 'arrival_terminal' || + d == 'departure_terminal' || d == 'is_next_day_arrival' || d == 'is_next_day_departure') { + this.FlightDetail.controls[i].get(d).setValue(list_obj[d]) + + } else if (d == 'from_airport' || d == 'to_airport') { + d == 'from_airport' ? this.getAirportDetails(list_obj[d], true) : this.getAirportDetails(list_obj[d], false) + this.FlightDetail.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'departure_time') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.FlightDetail.controls[i].get('departure_Hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.FlightDetail.controls[i].get('departure_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + + } else if (d == 'arrival_time') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.FlightDetail.controls[i].get('arrival_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.FlightDetail.controls[i].get('arrival_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } else if (d == 'flying_duration') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.FlightDetail.controls[i].get('flying_duration_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.FlightDetail.controls[i].get('flying_duration_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + }); + }) : ''; + + round_arr ? round_arr.map((list_obj, i) => { + i == 0 ? '' : this.addFlightGroupBtn('Return_flight') + Object.keys(list_obj).forEach(d => { + if (d == 'arrival_hour') { + this.Return_flight.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'sector_nbr') { + this.Return_flight.controls[i].get('sector_nbr').setValue(list_obj[d]) + } + else if (d == 'airline_code') { + this.GetAllAirline(list_obj[d]) + this.Return_flight.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'flight_no' || d == '_aircraft_type' || d == 'arrival_terminal' || + d == 'departure_terminal' || d == 'is_next_day_arrival' || d == 'is_next_day_departure') { + this.Return_flight.controls[i].get(d).setValue(list_obj[d]) + + } else if (d == 'from_airport' || d == 'to_airport') { + d == 'from_airport' ? this.getAirportDetails(list_obj[d], true) : this.getAirportDetails(list_obj[d], false) + this.Return_flight.controls[i].get(d).setValue(list_obj[d]) + } else if (d == 'departure_time') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.Return_flight.controls[i].get('departure_Hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.Return_flight.controls[i].get('departure_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + + } else if (d == 'arrival_time') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.Return_flight.controls[i].get('arrival_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.Return_flight.controls[i].get('arrival_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } else if (d == 'flying_duration') { + let hour = moment(list_obj[d]).format('h:mm').split(':')[0] + let minutes = moment(list_obj[d]).format('h:mm').split(':')[1] + this.Return_flight.controls[i].get('flying_duration_hour').setValue(hour.length != 2 ? '0' + hour : hour) + this.Return_flight.controls[i].get('flying_duration_minutes').setValue(minutes.length != 2 ? '0' + minutes : minutes) + } + }); + }) : ''; + + + }; + + /// validation form + setFilterValid(check) { + if (check) { + this.addvalid('date', 'add'); + this.addvalid('days', 'add'); + } else { + this.addvalid('date', 'remove'); + this.addvalid('days', 'remove'); + } + }; + + addvalid(name, type) { + if (type == 'add') { + this.Formdata.controls[name].addValidators([Validators.required]); + this.Formdata.controls[name].updateValueAndValidity(); + } else { + this.Formdata.controls[name].clearValidators(); + this.Formdata.controls[name].updateValueAndValidity(); + this.Formdata.controls[name].markAsUntouched(); + } + }; + + // validation + // nextdayarrivelcheck(check, ind, formname) { + // if (check) { + // this.AddOutboundtvalid(ind, 'arrival_hour', 'add', formname); + // this.AddOutboundtvalid(ind, 'arrival_minutes', 'add', formname); + // this.AddOutboundtvalid(ind, 'arrival_terminal', 'add', formname); + // this.AddOutboundtvalid(ind, 'flying_duration_hour', 'add', formname); + // this.AddOutboundtvalid(ind, 'flying_duration_minutes', 'add', formname); + // } else { + // this.AddOutboundtvalid(ind, 'arrival_hour', 'remove', formname); + // this.AddOutboundtvalid(ind, 'arrival_minutes', 'remove', formname); + // this.AddOutboundtvalid(ind, 'arrival_terminal', 'remove', formname); + // this.AddOutboundtvalid(ind, 'flying_duration_hour', 'remove', formname); + // this.AddOutboundtvalid(ind, 'flying_duration_minutes', 'remove', formname); + // } + + // } + + AddOutboundtvalid(index, name, type, formname) { + let formgroup; + formname == 'FlightDetail' ? formgroup = this.FlightDetail : formgroup = this.Return_flight + if (type == 'add') { + formgroup.controls[index].get(name).addValidators([Validators.required]); + formgroup.controls[index].get(name).updateValueAndValidity(); + } else { + formgroup.controls[index].get(name).clearValidators(); + formgroup.controls[index].get(name).updateValueAndValidity(); + formgroup.controls[index].get(name).markAsUntouched(); + } + }; + + + AddFLightRoundArr() { + this.Formdata.addControl( + 'Return_flight', this.Fb.array([ + this.Fb.group({ + airline_code: this.validationService.required, + flight_no: this.validationService.required, + _aircraft_type: this.validationService.required, + from_airport: [{ value: '', disabled: true }, Validators.required], + to_airport: [{ value: '', disabled: true }, Validators.required], + departure_Hour: this.validationService.required, + departure_minutes: this.validationService.required, + departure_terminal: this.validationService.required, + is_next_day_arrival: [false], + sector_nbr: [''], + arrival_hour: this.validationService.required, + arrival_minutes: this.validationService.required, + arrival_terminal: this.validationService.required, + flying_duration_hour: this.validationService.required, + flying_duration_minutes: this.validationService.required, + is_next_day_departure: [false], + }) + ]) + ); + }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + rangeDates: Date[]; + cities = [ + { id: 1, name: 'Oneway' }, + { id: 2, name: 'Roundtrip' }, + ]; + AirlineCode = [ + { id: 0, name: 'Select' }, + { id: 1, name: 'EK' }, + ]; + selectAirlineCode = this.AirlineCode[0].name; + + AircraftType = [ + { id: 0, name: 'Select' }, + { id: 1, name: 'a' }, + { id: 1, name: 'b' }, + { id: 1, name: 'c' }, + ]; + selectAircraftType = this.AircraftType[0].name; + date1: Date; + date2: Date; + date3: Date; + date4: Date; + // rangeDates: Date[]; + selectedCity = this.cities[0].name; + + + + +} diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.html b/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.html new file mode 100644 index 0000000..b0d0369 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.html @@ -0,0 +1,659 @@ +
    + + Back +
    +
    Date Filter
    +
    +
    +
    + + + +
    + + {{date.day}} + + + {{date.day}} + +
    +
    + +
    +
    + + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    + + + +
    + +
    Outbound Days
    +
    + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + Stop Sale + +
    +
    +
    + Adult Base Fare + +
    +
    +
    + Adult Taxes + +
    +
    +
    + Child Base Fare + +
    +
    +
    + Child Taxes + +
    +
    +
    + Infant Base Fare + +
    +
    +
    + Infant Taxes + +
    +
    +
    + Seats Allocation + +
    +
    +
    + Adult Check Bag + +
    +
    +
    + Child Check Bag + +
    +
    +
    + Infant Check Bag + +
    +
    +
    + Check Bag Unit + +
    +
    +
    + Adult Cabin Bag + +
    +
    +
    + Child Cabin Bag + +
    +
    +
    + Infant Cabin Bag + +
    +
    +
    + Cabin Bag Unit + +
    +
    +
    + Fare Type + +
    +
    +
    + PNR + +
    +
    +
    + Confirmation Type + +
    +
    +
    + Adult Fare Rule + +
    +
    +
    + Child Fare Rule + +
    +
    +
    + Infant Fare Rule + +
    +
    +
    + Meal Included + +
    +
    +
    + Meal Details + +
    +
    +
    + Inclusions + +
    +
    + {{list.get('outbound_date').value | date : "dd MMM YYYY" }} + & {{list.get('return_date').value | date : "dd MMM YYYY" }} + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    + +
    O
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.ts b/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.ts new file mode 100644 index 0000000..d60531c --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/edit-rate-and-inventory/edit-rate-and-inventory.component.ts @@ -0,0 +1,380 @@ +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { NgSelectComponent } from '@ng-select/ng-select'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { dtoFlightRate, FlightRateobj, UpdateFlightRate } from 'src/app/core/models/flight-service/flight-service-manage/edit-Rate-inventry.model'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-edit-rate-and-inventory', + templateUrl: './edit-rate-and-inventory.component.html', +}) +export class EditRateAndInventoryComponent implements OnInit { + value: Date; + constructor(public router: ActivatedRoute, + private ApiServ: API, public fb: FormBuilder, + public validationService: ValidationService, public MsgService: MessageService, public route: Router) { } + contract_id; + formdata: FormGroup; + SearchForm: FormGroup; + AtoZ = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + is_search = false + lovKeyDataObj = { + AirCabinClass: [], + AirPaxType: [], + AirTripType: [], + DaySelect: [], + AirBaggageUnit: [], + AirFareType: [], + }; + // all Copy ui + + @ViewChild('is_stop_sale') is_stop_sale: ElementRef; + @ViewChild('adt_base_fare') adt_base_fare: ElementRef; + @ViewChild('adt_tax') adt_tax: ElementRef; + @ViewChild('chd_base_fare') chd_base_fare: ElementRef; + @ViewChild('chd_tax') chd_tax: ElementRef; + @ViewChild('inf_base_fare') inf_base_fare: ElementRef; + @ViewChild('inf_tax') inf_tax: ElementRef; + @ViewChild('pnr') pnr: ElementRef; + @ViewChild('seat_allocation') seat_allocation: ElementRef; + @ViewChild('adt_check_bag') adt_check_bag: ElementRef; + @ViewChild('chd_check_bag') chd_check_bag: ElementRef; + @ViewChild('inf_check_bag') inf_check_bag: ElementRef; + @ViewChild('_check_bag_unit') _check_bag_unit: NgSelectComponent + @ViewChild('adt_cabin_bag') adt_cabin_bag: ElementRef; + @ViewChild('chd_cabin_bag') chd_cabin_bag: ElementRef; + @ViewChild('inf_cabin_bag') inf_cabin_bag: ElementRef; + @ViewChild('_cabin_bag_unit') _cabin_bag_unit: NgSelectComponent; + @ViewChild('_fare_type') _fare_type: NgSelectComponent; + @ViewChild('is_instant_confirmation') is_instant_confirmation: NgSelectComponent; + @ViewChild('adt_fare_rule') adt_fare_rule: ElementRef; + @ViewChild('chd_fare_rule') chd_fare_rule: ElementRef; + @ViewChild('inf_fare_rule') inf_fare_rule: ElementRef; + @ViewChild('is_meal_included') is_meal_included: ElementRef; + @ViewChild('meal_details') meal_details: ElementRef + @ViewChild('inclusions') inclusions: ElementRef + ngOnInit(): void { + this.GetLOVKeys('AirCabinClass,AirPaxType,AirTripType,DaySelect,AirBaggageUnit,AirFareType'); + this.SearchForm = this.fb.group({ + date: [''], + days: [''], + _rbd: [''], + currency: [''], + }); + + this.formdata = this.fb.group({ + FlightRate: this.fb.array([ + ]) + }); + this.checkIsRangetype(); + this.GetFlightRate(); + }; + checkIsRangetype() { + this.router.queryParams.subscribe(obj => { + this.contract_id = obj['id'] + this.ApiServ.Get('/FlightContract/GetFlightDates?ContractId=' + obj['id']).subscribe(data => { + if (data) { + if (data.responseObject.is_multi_day && !data.responseObject.is_round_trip) { + this.is_search = false; + this.SetTimeAvali(data.responseObject.dates); + } else this.is_search = true; + } + this.SearchForm.get('currency').setValue(data.responseObject.currency_code); + }); + }) + } + get FlightRate() { + return this.formdata.get('FlightRate') as FormArray; + } + + copyOnUi() { + let value = this.FlightRate.getRawValue(); + value.map((obj, i) => { + Object.keys(obj).forEach(e => { + if (e == 'is_stop_sale') { + this.FlightRate.controls[i].get(e).setValue(this.is_stop_sale['_checked']) + } else if (e == 'adt_base_fare') { + this.FlightRate.controls[i].get(e).setValue(this.adt_base_fare.nativeElement.value) + } else if (e == 'adt_tax') { + this.FlightRate.controls[i].get(e).setValue(this.adt_tax.nativeElement.value) + } else if (e == 'chd_base_fare') { + this.FlightRate.controls[i].get(e).setValue(this.chd_base_fare.nativeElement.value) + } else if (e == 'inf_base_fare') { + this.FlightRate.controls[i].get(e).setValue(this.inf_base_fare.nativeElement.value) + } else if (e == 'inf_tax') { + this.FlightRate.controls[i].get(e).setValue(this.inf_tax.nativeElement.value) + } else if (e == 'seat_allocation') { + this.FlightRate.controls[i].get(e).setValue(this.seat_allocation.nativeElement.value) + } else if (e == 'adt_check_bag') { + this.FlightRate.controls[i].get(e).setValue(this.adt_check_bag.nativeElement.value) + } else if (e == 'chd_check_bag') { + this.FlightRate.controls[i].get(e).setValue(this.chd_check_bag.nativeElement.value) + } else if (e == 'inf_check_bag') { + this.FlightRate.controls[i].get(e).setValue(this.inf_check_bag.nativeElement.value) + } else if (e == 'adt_cabin_bag') { + this.FlightRate.controls[i].get(e).setValue(this.adt_cabin_bag.nativeElement.value) + } else if (e == 'chd_cabin_bag') { + this.FlightRate.controls[i].get(e).setValue(this.chd_cabin_bag.nativeElement.value) + } else if (e == 'inf_cabin_bag') { + this.FlightRate.controls[i].get(e).setValue(this.inf_cabin_bag.nativeElement.value) + } else if (e == 'adt_fare_rule') { + this.FlightRate.controls[i].get(e).setValue(this.adt_fare_rule.nativeElement.value) + } else if (e == 'chd_fare_rule') { + this.FlightRate.controls[i].get(e).setValue(this.chd_fare_rule.nativeElement.value) + } else if (e == 'inf_fare_rule') { + this.FlightRate.controls[i].get(e).setValue(this.inf_fare_rule.nativeElement.value) + } else if (e == 'is_meal_included') { + this.FlightRate.controls[i].get(e).setValue(this.is_meal_included['_checked'] ? 'Yes' : 'No') + } else if (e == 'meal_details') { + this.FlightRate.controls[i].get(e).setValue(this.meal_details.nativeElement.value) + } else if (e == 'inclusions') { + this.FlightRate.controls[i].get(e).setValue(this.inclusions.nativeElement.value) + console.log(this.inclusions.nativeElement) + } else if (e == '_check_bag_unit') { + let check_bag = this._check_bag_unit.selectedValues[0] ? this._check_bag_unit.selectedValues[0].lov_key : ''; + this.FlightRate.controls[i].get(e).setValue(check_bag); + } else if (e == '_cabin_bag_unit') { + let cabin_bag = this._cabin_bag_unit.selectedValues[0] ? this._cabin_bag_unit.selectedValues[0].lov_key : ''; + this.FlightRate.controls[i].get(e).setValue(cabin_bag); + } else if (e == '_fare_type') { + let fare_type = this._fare_type.selectedValues[0] ? this._fare_type.selectedValues[0].lov_key : ''; + this.FlightRate.controls[i].get(e).setValue(fare_type); + } else if (e == 'is_instant_confirmation') { + let fare_type = this.is_instant_confirmation.selectedValues[0] ? this.is_instant_confirmation.selectedValues[0].name : ''; + this.FlightRate.controls[i].get(e).setValue(fare_type); + } else if (e == 'chd_tax') { + this.FlightRate.controls[i].get(e).setValue(this.chd_tax.nativeElement.value); + } else if (e == 'pnr') { + this.FlightRate.controls[i].get(e).setValue(this.pnr.nativeElement.value); + } + }) + }) + + }; + + addformgroup() { + this.FlightRate.push( + this.fb.group({ + rate_id: [''], + outbound_date: [''], + adt_base_fare: this.validationService.decimal, + adt_tax: this.validationService.decimal, + chd_base_fare: this.validationService.decimal, + chd_tax: this.validationService.decimal, + inf_base_fare: this.validationService.decimal, + inf_tax: this.validationService.decimal, + seat_allocation: this.validationService.number, + adt_check_bag: this.validationService.number, + chd_check_bag: this.validationService.number, + inf_check_bag: this.validationService.number, + _check_bag_unit: this.validationService.required, + adt_cabin_bag: this.validationService.number, + chd_cabin_bag: this.validationService.number, + inf_cabin_bag: this.validationService.number, + _cabin_bag_unit: this.validationService.required, + _fare_type: this.validationService.required, + adt_fare_rule: this.validationService.required, + chd_fare_rule: this.validationService.required, + inf_fare_rule: this.validationService.required, + is_meal_included: this.validationService.required, + meal_details: [''], + inclusions: [''], + pnr: this.validationService.required, + return_date: [''], + is_instant_confirmation: this.validationService.required, + is_stop_sale: [false], + }) + ) + } + + GetFlightRate() { + let postdata = new FlightRateobj(); + let val = this.SearchForm.getRawValue(); + postdata._id = this.contract_id; + postdata._from_date = val.date[0] ? moment(val.date[0]).format('YYYY-MM-DD') : ''; + postdata._rbd = val._rbd ? val._rbd : ''; + postdata._to_date = val.date[1] ? moment(val.date[1]).format('YYYY-MM-DD') : ''; + postdata.days = val.days ? val.days.join(',') : ''; + + this.ApiServ.Post('/FlightContract/GetFlightRate', postdata).subscribe(data => { + if (data) { + this.formdata.reset(); + this.FlightRate.clear(); + if (data.responseObject) { + this.addformgroup() + this.SetValue(data.responseObject); + } + } + }); + }; + + + + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + }; + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + }; + + saveRateDetails() { + if (this.formdata.status == "INVALID") { + this.validationService.showValidationsMsg(this.formdata); + return; + } + let value = this.FlightRate.getRawValue(); + let flight_list_arr = []; + value.map(e => { + let post_obj = new dtoFlightRate(); + post_obj.rate_id = e.rate_id; + post_obj.outbound_date = e.outbound_date; + post_obj.adt_base_fare = e.adt_base_fare; + post_obj.adt_tax = e.adt_tax; + post_obj.chd_base_fare = e.chd_base_fare; + post_obj.chd_tax = e.chd_tax; + post_obj.inf_base_fare = e.inf_base_fare; + post_obj.inf_tax = e.inf_tax; + post_obj.seat_allocation = e.seat_allocation; + post_obj.adt_check_bag = e.adt_check_bag; + post_obj.chd_check_bag = e.chd_check_bag; + post_obj.inf_check_bag = e.inf_check_bag; + post_obj._check_bag_unit = e._check_bag_unit; + post_obj.adt_cabin_bag = e.adt_cabin_bag; + post_obj.chd_cabin_bag = e.chd_cabin_bag; + post_obj.inf_cabin_bag = e.inf_cabin_bag; + post_obj._cabin_bag_unit = e._cabin_bag_unit; + post_obj._fare_type = e._fare_type; + post_obj.adt_fare_rule = e.adt_fare_rule; + post_obj.chd_fare_rule = e.chd_fare_rule; + post_obj.inf_fare_rule = e.inf_fare_rule; + post_obj.is_meal_included = e.is_meal_included == 'Yes' ? true : false; + post_obj.meal_details = e.is_meal_included == 'Yes' ? e.meal_details : ''; + post_obj.inclusions = e.inclusions; + post_obj.pnr = e.pnr; + post_obj.is_instant_confirmation = e.is_instant_confirmation == 'Instant' ? true : false; + post_obj.is_stop_sale = e.is_stop_sale; + flight_list_arr.push(post_obj); + }) + + let postdata = new UpdateFlightRate(); + postdata.contract_id = this.contract_id; + postdata.flight_rate = flight_list_arr; + + this.ApiServ.Post('/FlightContract/UpdateRatesAndInventory', postdata).subscribe(data => { + if (data) { + this.MsgService.add({ + severity: data["status"] ? "success" : "error", + detail: data["message"], + }); + data["status"] ? setTimeout(() => { + this.route.navigate(['/Services/FlightServices/Search']) + }, 500) : ''; + } + }) + }; + + SetValue(data) { + + data ? data.map((obj, i) => { + i != 0 ? this.addformgroup() : '' + Object.keys(obj).forEach(e => { + if (e == 'is_meal_included') this.FlightRate.controls[i].get(e).setValue(obj[e] ? 'Yes' : 'No'); + else if (e == 'is_instant_confirmation') this.FlightRate.controls[i].get(e).setValue(obj[e] ? 'Instant' : 'Manual'); + else this.FlightRate.controls[i].get(e).setValue(obj[e]); + }) + }) : '' + }; + + Confirmation_Type = [ + { id: 0, name: 'Instant' }, + { id: 1, name: 'Manual' }, + ]; + + Option = [ + { id: 2, name: 'Yes' }, + { id: 3, name: 'No' }, + ]; + + formDate; + datelist + SetTimeAvali(allDate) { + this.datelist = allDate.split(','); + let obj = []; + this.datelist.map(e => { + obj.push(moment(e).format('MM-DD-YYYY')); + }) + this.datelist = obj; + } + @ViewChild('calender') calender + DateRangecheck() { + let date_range = this.SearchForm.get('date').value + if (date_range[1]) { + this.calender.overlayVisible = false; + let AllSelectDate = [] + this.datelist.filter(e => { + let from = moment(date_range[0]).format('MM:DD:YYYY').split(':') + let To = moment(date_range[1]).format('DD:MMM:YYYY').split(':') + let maindate = moment(e).format('DD:MMM:YYYY').split(':') + if (from[1] == maindate[1] || To[1] == maindate[1]) { + let date = new Date(e).getDate(); + let St = new Date(date_range[0]).getDate(); + let et = new Date(date_range[1]).getDate(); + (date >= St && date <= et) ? AllSelectDate.push(e) : '' + } + }) + this.formDate = AllSelectDate; + // this.GetFlightRate() + }; + }; + + checkDateForHighlight(date) { + let month = date.month > 9 ? date.month : '0' + date.month; + let d = new Date(date.year, date.month, date.day); + let new_Date = month + '-' + date.day + '-' + date.year; + let Checkformat = moment(new_Date).format('MM-DD-YYYY') + let validate; + validate = false; + if (new_Date == Checkformat) { + let format = moment(d).format('MM-DD-YYYY') + let valid = this.datelist.filter(e => e == format) + if (valid.length > 0) { + validate = true; + } + } + return validate; + } + + MealTypeIncludedcheck(val, ind) { + console.log(val) + if (val == 'Yes') this.addvalidMealTypeIncluded(ind, 'meal_details', 'add') + else this.addvalidMealTypeIncluded(ind, 'meal_details', 'remove') + + } + + addvalidMealTypeIncluded(index, name, type) { + if (type == 'add') { + this.formdata.controls[index].get(name).addValidators([Validators.required]); + this.formdata.controls[index].get(name).updateValueAndValidity(); + } else { + this.formdata.controls[index].get(name).clearValidators(); + this.formdata.controls[index].get(name).updateValueAndValidity(); + this.formdata.controls[index].get(name).markAsUntouched(); + } + }; +} diff --git a/src/app/modules/services/flight-services/flight-services-manage/flight-services-manage.module.ts b/src/app/modules/services/flight-services/flight-services-manage/flight-services-manage.module.ts new file mode 100644 index 0000000..047d2a8 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-manage/flight-services-manage.module.ts @@ -0,0 +1,74 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { EditContractDetailsComponents } from './edit-contract/edit-contract-details'; +import { EditFlightDetailsComponent } from './edit-flight-details/edit-flight-details.component'; +import { EditRateAndInventoryComponent } from './edit-rate-and-inventory/edit-rate-and-inventory.component'; +import { RouterModule, Routes } from '@angular/router'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { CheckboxModule } from 'primeng/checkbox'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TreeModule } from 'primeng/tree'; +import { CalendarModule } from 'primeng/calendar'; +import { MessageService } from 'primeng/api'; +import { ToastModule } from 'primeng/toast'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'EditRateAndInventory', + component: EditRateAndInventoryComponent, + }, + { + path: 'EditFlight', + component: EditFlightDetailsComponent, + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ + EditFlightDetailsComponent, + EditRateAndInventoryComponent, + EditContractDetailsComponents + ], + imports: [ + CommonModule, + CommonModule, + ButtonModule, + NgSelectModule, + TreeModule, + ToolbarModule, + TableModule, + MatMenuModule, + MatButtonModule, + CheckboxModule, + InputTextModule, + InputNumberModule, + CalendarModule, + FormsModule, + MatDialogModule, + // FormsModule, + TooltipModule, + ReactiveFormsModule, + MatButtonModule, + MatCheckboxModule, + ToastModule, + RouterModule.forChild(routes), + + ], + providers: [MessageService], +}) +export class FlightServicesManageModule { } diff --git a/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.html b/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.html new file mode 100644 index 0000000..ceacf81 --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.html @@ -0,0 +1,436 @@ +
    +
    +
    +

    Search Flight Contract

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    + +
    Trip Type
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Airline
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    + +
    Origin
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Destination
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Departure Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Return Days
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + Is Multi Day Operation +
    +
    +
    +
    + + + +
    + +
    Currency
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Fare Type
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    RBD
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Cabin Class
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    + +
    Confirmation Type
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Contract Id + + + + Contract Name + + + + Supplier Name + + + + Trip Type + + + + Airline + + + + Flight No. + + + + Origin + + + + Destination + + + + PNR + + + + Is Multi Day Operation + + + + Currency + + + + Status + + + Action + + + + + {{ FlightAllDetails.contract_id }} + {{ FlightAllDetails.contract_name }} + {{ FlightAllDetails.supplier_name }} + {{FlightAllDetails._trip_type == lovKeyDataObj.AirTripType[0].lov_key ? + lovKeyDataObj.AirTripType[0].lov_value : lovKeyDataObj.AirTripType[1].lov_value }} + {{FlightAllDetails.validating_airline }} + {{FlightAllDetails.flight_no }} + {{FlightAllDetails.from_airport }} + {{FlightAllDetails.to_airport }} + {{FlightAllDetails.pnr }} + {{FlightAllDetails.is_multi_day ? 'Yes' : 'NO' }} + {{FlightAllDetails.currency_code }} + + {{FlightAllDetails.is_active + ? 'Active' : 'Deactive' }} + + +
    + + + + + + + + +
    + + +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.ts b/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.ts new file mode 100644 index 0000000..00a66ec --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services-search/flight-services-search.component.ts @@ -0,0 +1,349 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Product } from 'src/app/core/services/product'; +import { ProductService } from 'src/app/core/services/product.service'; +import * as FileSaver from 'file-saver'; +import { MatDialog } from '@angular/material/dialog'; +import { MatMenuTrigger } from '@angular/material/menu'; +import { EditContractDetailsComponents } from '../flight-services-manage/edit-contract/edit-contract-details'; +import { API } from 'src/app/core/services/api.service'; +import { FlightContractSearhObj } from 'src/app/core/models/flight-service/flight-service-search/flight-service-search.model'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { Router } from '@angular/router'; +@Component({ + selector: 'app-flight-services-search', + templateUrl: './flight-services-search.component.html', +}) +export class FlightServicesSearchComponent implements OnInit { + @ViewChild('menuTrigger') menuTrigger: MatMenuTrigger; + lovKeyDataObj = { + AirCabinClass: [], + AirPaxType: [], + AirTripType: [], + DaySelect: [], + AirBaggageUnit: [], + AirFareType: [], + }; + Formdata: FormGroup; + CurrencyList; + AirlineList; + AirportListFrom; + AirportListTO; + AtoZ = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + FlightAllDetails; + constructor( + private productService: ProductService, + public dialog: MatDialog, + public ApiServ: API, + public fb: FormBuilder, + public MsgService: MessageService, + public router: Router + ) { } + + ngOnInit(): void { + this.OnInitForm(); + this.GetLOVKeys('AirCabinClass,AirPaxType,AirTripType,DaySelect,AirBaggageUnit,AirFareType'); + this.GetCurrency(); + + } + + OnInitForm() { + this.Formdata = this.fb.group({ + contract_name: [''], + supplier_name: [''], + _trip_type: [''], + airline_code: [''], + flight_no: [''], + from_airport: [''], + to_airport: [''], + is_multi_day: [false], + pnr: [''], + currency_code: [''], + fare_type: [''], + Cabin_Class: [], + is_instant_confirmation: [''], + rbd: [''], + ret_days: [''], + dep_days: [''], + departure_date: [''], + return_date: [''], + }); + } + + + + GetFlightDetails() { + let value = this.Formdata.getRawValue(); + let Postdata = new FlightContractSearhObj(); + Postdata.contract_name = value.contract_name; + Postdata.supplier_name = value.supplier_name; + Postdata._trip_type = value._trip_type.toString(); + Postdata.airline_code = value.airline_code; + Postdata.flight_no = value.flight_no; + Postdata.from_airport = value.from_airport; + Postdata.to_airport = value.to_airport; + Postdata.dep_from_date = value.departure_date[0] ? moment(value.departure_date[0]).format('YYYY-MM-DD') : ''; + Postdata.dep_to_date = value.departure_date[1] ? moment(value.departure_date[1]).format('YYYY-MM-DD') : ''; + Postdata.ret_from_date = value.return_date[0] ? moment(value.return_date[0]).format('YYYY-MM-DD') : ''; + Postdata.ret_to_date = value.return_date[1] ? moment(value.return_date[1]).format('YYYY-MM-DD') : ''; + Postdata.is_multi_day = value.is_multi_day; + Postdata.pnr = value.pnr; + Postdata.rbd = value.rbd; + Postdata.ret_days = value.ret_days ? value.ret_days.join(',') : ''; + Postdata.dep_days = value.dep_days ? value.dep_days.join(',') : ''; + Postdata.currency_code = value.currency_code; + Postdata.fare_type = value.fare_type ? value.fare_type : 0; + Postdata.is_instant_confirmation = value.is_instant_confirmation == 'Instant' && value.is_instant_confirmation ? true : false; + value.Cabin_Class == 1 ? Postdata.is_economy = true : Postdata.is_economy = false; + value.Cabin_Class == 2 ? Postdata.is_premium_economy = true : Postdata.is_premium_economy = false; + value.Cabin_Class == 3 ? Postdata.is_business = true : Postdata.is_business = false; + value.Cabin_Class == 4 ? Postdata.is_first_class = true : Postdata.is_first_class = false; + this.ApiServ.Post('/FlightContract/GetAllFlightContractView', Postdata).subscribe(obj => { + if (obj) { + this.FlightAllDetails = obj.responseObject; + } + }); + } + + GetLOVKeys(lov_key_names) { + let lov_key_names_arr = lov_key_names.split(','); + let lov_obj = { + "lov_types": [], + "lov_lang": "en" + }; + lov_key_names_arr.forEach(key_name => { + lov_obj.lov_types.push({ "lov_type": key_name }); + }); + this.ApiServ.Post('/LovMaster/GetLov', lov_obj).subscribe(lov_data => { + if (lov_data && lov_data.status) { + lov_key_names_arr.forEach(key_name => { + let arr = lov_data.responseObject.filter(el => el.lov_type == key_name); + arr.length > 0 ? this.lovKeyDataObj[key_name] = arr[0].keys : ''; + }); + } + }); + }; + + updateStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + UpdatedBy: '' + } + this.ApiServ.Post('/FlightContract/UpdateStatus', obj).subscribe(obj => { + if (obj) { + this.GetFlightDetails(); + this.MsgService.add({ + severity: obj["status"] ? "success" : "error", + detail: obj["message"], + }); + } + }); + } + GetAllAirline(val) { + if (val.value) { + this.ApiServ.Get('/MasterSearch/GetAllAirline/en/' + val.value).subscribe(obj => { + if (obj) { + this.AirlineList = obj; + } + }); + } + } + GetCurrency() { + this.ApiServ.Get('/Currency/GetCurrency').subscribe(obj => { + if (obj) { + this.CurrencyList = obj; + } + }) + } + // static dropdown + + Confirmation_Type = [ + { id: 0, name: 'Instant' }, + { id: 1, name: 'Manual' }, + ]; + + ResetVal() { + let val = this.Formdata.getRawValue() + Object.keys(val).forEach(e => { + if (e == 'is_multi_day') this.Formdata.get(e).setValue(false) + else this.Formdata.get(e).setValue(''); + + }) + } + + + getAirportDetails(val, check) { + if (val.value.length >= 3) { + this.ApiServ.Get('/MasterSearch/GetAllMasterSearch/en/' + val.value).subscribe(obj => { + if (obj) { + if (check) this.AirportListFrom = obj + if (!check) this.AirportListTO = obj + } + }); + } + } + + editRateInventry(contract_id) { + let obj = { id: contract_id }; + this.router.navigate(['/Services/FlightServices/Manage/EditRateAndInventory'], { queryParams: obj }); + }; + EditFlightDetails(contract_id) { + let obj = { id: contract_id }; + this.router.navigate(['/Services/FlightServices/Manage/EditFlight'], { queryParams: obj }); + } + + + + + + + + + + + + + + + + + + + + + + + displayModal: boolean; + showModalDialog() { + this.displayModal = true; + } + openDialog(Id) { + const dialogRef = this.dialog.open(EditContractDetailsComponents, { + width: '35rem', + restoreFocus: false, + data: { + contractId: Id, + } + }); + + // Manually restore focus to the menu trigger since the element that + // opens the dialog won't be in the DOM any more when the dialog closes. + dialogRef.afterClosed().subscribe(() => this.menuTrigger.focus()); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cities = [ + { id: 1, name: 'Vilnius' }, + { id: 2, name: 'Kaunas' }, + { id: 3, name: 'Pavilnys', disabled: true }, + { id: 4, name: 'Pabradė' }, + { id: 5, name: 'Klaipėda' }, + ]; + selectedCity = this.cities[0].name; + + + + rangeDates: Date[]; + + minDate: Date; + + maxDate: Date; + + es: any; + + invalidDates: Array; + // table + cols!: any[]; + + productDialog!: boolean; + + products!: Product[]; + + product!: Product; + + selectedProducts!: Product[]; + + submitted!: boolean; + + openNew() { + this.product = {}; + this.submitted = false; + this.productDialog = true; + } + + findIndexById(id: string): number { + let index = -1; + for (let i = 0; i < this.products.length; i++) { + if (this.products[i].id === id) { + index = i; + break; + } + } + return index; + } + createId(): string { + let id = ''; + var chars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (var i = 0; i < 5; i++) { + id += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return id; + } + exportExcel() { + import('xlsx').then((xlsx) => { + console.log(xlsx); + const worksheet = xlsx.utils.json_to_sheet(this.products); + const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }; + const excelBuffer: any = xlsx.write(workbook, { + bookType: 'xlsx', + type: 'array', + }); + this.saveAsExcelFile(excelBuffer, 'products'); + }); + } + + saveAsExcelFile(buffer: any, fileName: string): void { + import('file-saver').then((abc) => { + let EXCEL_TYPE = + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; + let EXCEL_EXTENSION = '.xlsx'; + const data: Blob = new Blob([buffer], { + type: EXCEL_TYPE, + }); + console.log(FileSaver); + FileSaver.saveAs( + data, + fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION + ); + }); + } +} diff --git a/src/app/modules/services/flight-services/flight-services.module.ts b/src/app/modules/services/flight-services/flight-services.module.ts new file mode 100644 index 0000000..b62f77e --- /dev/null +++ b/src/app/modules/services/flight-services/flight-services.module.ts @@ -0,0 +1,77 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FlightServicesSearchComponent } from './flight-services-search/flight-services-search.component'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { CheckboxModule } from 'primeng/checkbox'; +import { ProductService } from 'src/app/core/services/product.service'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TreeModule } from 'primeng/tree'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatButtonModule } from '@angular/material/button'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { FlightServicesAddComponent } from './flight-services-add/flight-services-add.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { CalendarModule } from 'primeng/calendar'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDialogModule } from '@angular/material/dialog'; +// import { FlightServicesManageComponent } from './flight-services-manage/flight-services-manage.component'; +import { MessageService } from 'primeng/api'; +import { ToastModule } from 'primeng/toast'; + +const routes: Routes = [ + { + path: 'Search', + component: FlightServicesSearchComponent, + }, + { + path: 'Add', + component: FlightServicesAddComponent, + }, + { + path: 'Manage', + loadChildren: () => + import('./flight-services-manage/flight-services-manage.module').then( + (m) => m.FlightServicesManageModule + ), + }, + + { + path: '', + pathMatch: 'full', + redirectTo: 'Search', + }, +]; + +@NgModule({ + declarations: [ + FlightServicesSearchComponent, + FlightServicesAddComponent, + ], + imports: [ + CommonModule, + ButtonModule, + NgSelectModule, + TreeModule, + ToolbarModule, + TableModule, + MatMenuModule, + MatButtonModule, + CheckboxModule, + InputTextModule, + InputNumberModule, + CalendarModule, + FormsModule, + ReactiveFormsModule, + MatDialogModule, + MatButtonModule, + MatCheckboxModule, + RouterModule.forChild(routes), + ToastModule + ], + providers: [ProductService, MessageService], +}) +export class FlightServicesModule { } diff --git a/src/app/modules/services/hotel/hotel-add/hotel-add.component.html b/src/app/modules/services/hotel/hotel-add/hotel-add.component.html new file mode 100644 index 0000000..6815c47 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-add/hotel-add.component.html @@ -0,0 +1,99 @@ + +
    +
    +
    +

    Add Hotel Form

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Hotel Name

    +
    + +
    +
    +
    + + {{item.hotelName }} {{item.cityName }}, {{item.countryName }} + +
    + Please + select hotel name +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Currency

    +
    + +
    +
    +
    + + {{item.currency_code }} + +
    + Please + select currency +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-add/hotel-add.component.ts b/src/app/modules/services/hotel/hotel-add/hotel-add.component.ts new file mode 100644 index 0000000..6903c82 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-add/hotel-add.component.ts @@ -0,0 +1,119 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-hotel-add', + templateUrl: './hotel-add.component.html', +}) +export class HotelAddComponent implements OnInit { + + constructor(private apiserv: API,public fb:FormBuilder, public validserv:ValidationService,public MsgService:MessageService, private router: Router) { } + HotelList; + CurrencyList; + timer; + selectedRow; + ddLoader = { + hotel_list:false, + currency_list:false + }; + HotelDetailForm:FormGroup; + + ngOnInit(): void { + this.HotelDetailForm = this.fb.group({ + hotel_code_mapping:this.validserv.required, + currency:this.validserv.required, + star_rating:'', + country_code:'', + city_code:'', + city_name:'', + country_name:'' + }) + } + + GetHotels(event){ + if (event.value.length >= 2) { + let obj ={ + languageCode:'en', + cityName:event.value, + lattitude:'0', + longitude:'0', + } + this.ddLoader['hotel_list'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost(`/Hotel/GetHotels`,obj).subscribe(res => { + if (res) { + this.HotelList = res.hotels; + this.ddLoader['hotel_list'] = false; + } + }); + }, 500); + } + } + GetCurrency(event){ + if (event.value.length >= 2) { + let obj ={ + langcode:'en', + query:event.value + } + this.ddLoader['currency_list'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost(`/MasterSearch/GetAllCurrency`,obj).subscribe(res => { + if (res) { + this.CurrencyList = res.Result; + this.ddLoader['currency_list'] = false; + } + }); + }, 500); + } + } + SetHotelDet(event){ + this.selectedRow = this.HotelList.find(row => row.hotelId === event); + if(this.selectedRow){ + this.HotelDetailForm.get('country_name').setValue(this.selectedRow.countryName); + this.HotelDetailForm.get('city_name').setValue(this.selectedRow.cityName); + this.HotelDetailForm.get('city_code').setValue(this.selectedRow.cityCode); + this.HotelDetailForm.get('country_code').setValue(this.selectedRow.countryCode); + this.HotelDetailForm.get('star_rating').setValue(this.selectedRow.Rating); + } + } + + Save(){ + if (this.HotelDetailForm.status == "INVALID") { + this.validserv.showValidationsMsg(this.HotelDetailForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.HotelDetailForm.getRawValue(); + let ReqObj={ + hotel_code_mapping:val.hotel_code_mapping, + currency:val.currency, + star_rating:val.star_rating ? parseInt(val.star_rating) : 0, + country_code:val.country_code ? val.country_code : '', + city_code:val.city_code ? val.city_code : '' + } + this.apiserv.Post('/ExtranetHotel/SaveExtranetHotel',ReqObj).subscribe(data=>{ + if(data){ + this.MsgService.add({ + severity: data.status ? "success" : "error", + detail: data.message, + }); + data.status ? this.backbutton() : ''; + } + }) + } + + backbutton(){ + this.router.navigateByUrl("Services/Hotel/HotelSearch"); + } + backClick() { + this.router.navigateByUrl("Services/Hotel/HotelSearch"); + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.html b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.html new file mode 100644 index 0000000..cd2c5ce --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.html @@ -0,0 +1,259 @@ + +
    +
    +
    +
    +

    Add Allocation

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + {{item}} + {{item}} + {{data.room_name + (data.room_view_name ? ', ' : '') + data.room_view_name}} +
    + Please + select room name +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    + +
    +
    +
    +
    + +
    +
    + + + Please select date greater than from previous range + + + Please select range to date + + + Please select date range + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + + info + + Please + select Season +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Allocation Days

    +
    + +
    +
    +
    + {{item}} + {{item}} +
    + Please + select allocation days +
    +
    +
    +
    + + + +
    +
    +
    +

    Allocation Type

    +
    + +
    +
    +
    + Select + Free Sale + Count Sale +
    + Please + select allocation type +
    +
    +
    +
    +
    +
    + + + Please + enter allocation +
    +
    +
    +
    + + + Please + enter release days +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    {{item.season_name}}
    +
    +

    {{date}}

    +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.ts b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.ts new file mode 100644 index 0000000..4bf6d9d --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-add/allocation-add.component.ts @@ -0,0 +1,322 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; + +@Component({ + selector: 'app-allocation-add', + templateUrl: './allocation-add.component.html', +}) +export class AllocationAddComponent implements OnInit { + Extranet_Hotel_Id; + Season_List = []; + AllSeason; + SelectAllRoom = []; + ClearAllRoom = []; + IsMobile; + AllRoomsData; + MinDate = new Date(); + position: string; + displayPosition: boolean; + Allocation_Form:FormGroup; + AllDaysArr = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + SelectAllVal = ["Select All"]; + DaysArrValue = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + SelectAll=["Select All"]; + constructor( + private router: Router, + public activateRoute:ActivatedRoute, + private hotelmanageserv:ManageHotelService, + public apiserv:API,public fb:FormBuilder,public validserv:ValidationService,public commonMasterSer:CommonFunctionService, + public brkpointsrv:BreakpointsService + ) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Allocation_Form = this.fb.group({ + extranet_room_id:this.validserv.required, + date_type:this.validserv.required, + AllocationDays:this.fb.array([ + this.fb.group({ + allocation_days:this.validserv.required, + allocation_type:this.validserv.required + }) + ]) + }); + this.getAllData(); + this.IsMobile = this.brkpointsrv.IsMobile.getValue(); + } + ShowDateTypeFields(event){ + this.Season_List = []; + if(event == 'SPECIFICDATES'){ + this.Allocation_Form.addControl('ContractDatesArr',new FormArray([this.fb.group({ + date:['', Validators.compose([Validators.required, this.dateValidation(new Date())])], + })])); + this.Allocation_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Allocation_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Allocation_Form.removeControl('ContractDatesArr'); + }else { + this.Allocation_Form.removeControl('Season_Id'); + this.Allocation_Form.removeControl('ContractDatesArr'); + } + } + addDate() { + let formArray = this.Allocation_Form.controls['ContractDatesArr'] as FormArray; + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if(formArray.length > 0){ + if (formArray.length > 0) { + let formdate = formArray.controls[formArray.length - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + formArray.push(this.fb.group({ + extranet_season_detail_id:'', + date: ['', Validators.compose([ + Validators.required, + this.dateValidation(currentDate) + ])] + })); + } + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (toDate && control.value.length <= 1 || control.value[0] <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.Allocation_Form.controls['ContractDatesArr'] as FormArray; + formArray.removeAt(index); + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if (formArray.length > 0) { + if(index > 0){ + let formdate = formArray.controls[index - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + if (formArray.controls.length >= (index + 1)) { + formArray.controls[index].get("date").clearValidators(); + formArray.controls[index].get("date").setErrors(null); + formArray.controls[index].get("date").addValidators([Validators.required,this.dateValidation(currentDate)]); + formArray.controls[index].get("date").markAsTouched(); + formArray.controls[index].get("date").updateValueAndValidity(); + formArray.controls[index].get("date").markAsTouched(); + } + } + } + showPositionDialog(position) { + this.position = position; + this.displayPosition = true; + }; + backClick(){ + this.hotelmanageserv.Active_tab = 'Allocation'; + this.router.navigateByUrl("Services/Hotel/HotelManage/"+ this.Extranet_Hotel_Id); + } + SeasonDataAddRemove(){ + this.Season_List = []; + let selected_season = this.Allocation_Form.controls['Season_Id'].value; + selected_season.forEach(data=>{ + let matched_season_by_id = this.AllSeason.find(e=>e.extranet_season_id == data); + if(matched_season_by_id){ + if(typeof(matched_season_by_id['date_range']) == 'string'){ + matched_season_by_id['date_range'] = matched_season_by_id.date_range.split(', '); + matched_season_by_id['date_range'].forEach((z,i)=>{ + matched_season_by_id['date_range'][i] = moment(z.split(' - ')[0]).format('DD MMM YYYY') + ' to ' + moment(z.split(' - ')[1]).format('DD MMM YYYY') + }) + } + this.Season_List.push(matched_season_by_id); + console.log(this.Season_List) + } + }) + } + getAllData() { + forkJoin( + this.GetAllRooms(), + this.GetAllSeason() + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllRoomsData = res[0] ? res[0].data : []; + if(res[0].data){ + this.SelectAllRoom = ['Select All']; + } + this.AllSeason = res[1].data ? res[1].data : []; + } + }); + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj) + } + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj) + } + CloseCalender(element, index) { + let formArray = this.Allocation_Form.controls['ContractDatesArr']['controls']; + if (element.value[0] && element.value[1]) { + element.overlayVisible = false; + element.datepickerClick = true; + if (formArray.length >= (index + 2)) { + formArray[index + 1].get("date").clearValidators(); + formArray[index + 1].get("date").setErrors(null); + formArray[index + 1].get("date").addValidators([Validators.required,this.dateValidation(element.value[1])]); + formArray[index + 1].get("date").markAsTouched(); + formArray[index + 1].get("date").updateValueAndValidity(); + formArray[index + 1].get("date").markAsTouched(); + } + } + } + AllocationTypeCheck(ind,event){ + let formgroup = this.Allocation_Form.controls['AllocationDays']['controls'][ind] as FormGroup; + if(event == 'COUNTSALE'){ + formgroup.addControl('allocation_limit',new FormControl('',Validators.required)); + formgroup.addControl('release_days',new FormControl('',Validators.required)); + }else { + formgroup.removeControl('allocation_limit'); + formgroup.removeControl('release_days'); + } + } + ChangeinWeekDays(i?,event?){ + let selected_days_by_room = []; + let formdata = this.Allocation_Form.controls['AllocationDays'].value; + if(event?.includes('Select All')){ + formdata[i].allocation_days.splice(formdata[i].allocation_days.indexOf('Select All'), 1); + this.DaysArrValue.forEach(days_val=>{ + formdata[i].allocation_days.push(days_val); + }) + this.Allocation_Form.controls['AllocationDays']['controls'][i]['controls']['allocation_days'].setValue(formdata[i].allocation_days); + } + formdata.forEach(e=>{ + if(e.allocation_days && e.allocation_days.length > 0){ + e.allocation_days.forEach(days=>{ + selected_days_by_room.push(days); + }) + } + }) + this.DaysArrValue = this.AllDaysArr.filter(item => !selected_days_by_room.includes(item)); + if(this.DaysArrValue.length == 0){ + this.SelectAllVal = [] + }else { + this.SelectAllVal = this.SelectAll; + } + } + AddAllocationDays(){ + let formArray = this.Allocation_Form.controls['AllocationDays'] as FormArray; + formArray.push(this.fb.group({ + allocation_days:this.validserv.required, + allocation_type:this.validserv.required + })); + } + RemoveAllocation(i){ + let formArray = this.Allocation_Form.controls['AllocationDays'] as FormArray; + formArray.removeAt(i); + this.ChangeinWeekDays(); + } + Save(){ + if (this.Allocation_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Allocation_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Allocation_Form.getRawValue(); + let postObjArr = []; + val.extranet_room_id.forEach(room_Id=>{ + let PostObj = { + extranet_room_id:room_Id, + extranet_hotel_id:this.Extranet_Hotel_Id, + date_range:'', + AllocationDays:[] + }; + if(val.date_type == 'SPECIFICDATES'){ + let date_Arr = []; + val.ContractDatesArr.forEach(data=>{ + date_Arr.push({ + date_from: moment(data.date[0]).format('YYYY-MM-DD'), + date_to: moment(data.date[1]).format('YYYY-MM-DD'), + }) + }); + PostObj['date_range'] = JSON.stringify(date_Arr); + } + if(val.date_type == 'SEASON'){ + let date_Arr = []; + this.Season_List.forEach(data=>{ + data.date_range.forEach(season_date=>{ + date_Arr.push({ + date_from: moment(season_date.split(' to ')[0]).format('YYYY-MM-DD'), + date_to: moment(season_date.split(' to ')[1]).format('YYYY-MM-DD'), + }) + }) + }); + PostObj['date_range'] = JSON.stringify(date_Arr); + } + val.AllocationDays.forEach(allocation_data=>{ + PostObj.AllocationDays.push({ + allocation_days:allocation_data.allocation_days ? allocation_data.allocation_days.join(',') : '', + allocation_type:allocation_data.allocation_type, + allocation_limit:allocation_data.allocation_limit ? parseInt(allocation_data.allocation_limit) : 0, + release_days:allocation_data.release_days ? parseInt(allocation_data.release_days) : 0 + }) + }); + postObjArr.push(PostObj); + }) + + this.apiserv.Post('/ExtranetAllocation/SaveExtranetAllocation',postObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.backClick() : ''; + } + }) + } + + SelectAndRemoveAllRoom(){ + const contract_id = this.Allocation_Form.get('extranet_room_id').value + if (contract_id && contract_id.length > 0 && (contract_id.includes('Select All') || contract_id.length == this.AllRoomsData.length) && !contract_id.includes('Clear All')) { + let room_id_List = [] + this.AllRoomsData.forEach(d=>{ + room_id_List.push(d.extranet_room_id) + }); + this.Allocation_Form.get('extranet_room_id').setValue(room_id_List); + this.SelectAllRoom = []; + this.ClearAllRoom = ['Clear All']; + } else if (contract_id && contract_id.length > 0 && (contract_id.includes('Clear All'))){ + this.Allocation_Form.get('extranet_room_id').setValue([]); + this.SelectAllRoom = ['Select All']; + this.ClearAllRoom = []; + } else { + this.SelectAllRoom = ['Select All']; + if(contract_id?.length > 0){ + this.ClearAllRoom = ['Clear All']; + } + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.html b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.html new file mode 100644 index 0000000..e90394e --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.html @@ -0,0 +1,153 @@ +
    +
    +
    +

    Allocation

    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + {{data.room_name + (data.room_view_name ? ', ' : '') + data.room_view_name}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Room ID + + + + Room Name + + + + Allocation Date Range + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + {{data.extranet_room_id}} + {{data.room_name}} + {{item}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + +
    + + +
    + + + No data found + + +
    +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.ts b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.ts new file mode 100644 index 0000000..3846bb0 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation-view/allocation-view.component.ts @@ -0,0 +1,104 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'allocation-view', + templateUrl: './allocation-view.component.html', +}) +export class AllocationViewComponent implements OnInit { + Extranet_Hotel_Id; + AllRoomsData; + Room_Id; + Result; + cols; + constructor( + public activateRoute:ActivatedRoute, + public apiserv:API, + public _commonService:CommonFunctionService, + public router:Router + ) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.GetAllRooms() + this.cols = [ + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'date_range_arr', header: 'Allocation Date Range' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj).subscribe(res=>{ + this.AllRoomsData = res ? res.data : []; + }) + } + // updateStatus(id, val) { + // let obj = { + // Id: id, + // status: val ? false : true, + // }; + // this.apiserv.Post('/ExtranetAllocation/UpdateExtranetAllocationStatus', obj).subscribe(res => { + // if (res) { + // this._commonService.showMessage(res['status'], res['message']); + // res['status'] ? this.Search() : ''; + // } + // }); + // } + + Search(){ + let ReqObj = { + extranet_room_id:this.Room_Id ? this.Room_Id : '', + extranet_hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetAllocation/GetAllExtranetAllocation',ReqObj).subscribe(res=>{ + if(res){ + this.Result = res.data ? res.data : []; + if(res.data){ + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['date_range_arr'] = e['date_ranges'] ? JSON.parse(e['date_ranges']) : []; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/UpdateAllocation/${this.Extranet_Hotel_Id}/${Id}`); + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.html b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.html new file mode 100644 index 0000000..150afcb --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.ts b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.ts new file mode 100644 index 0000000..1c25b46 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'allocation', + templateUrl: './allocation.component.html', +}) +export class AllocationComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/allocation/allocation.module.ts b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.module.ts new file mode 100644 index 0000000..0bbca9b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/allocation/allocation.module.ts @@ -0,0 +1,58 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { AllocationViewComponent } from './allocation-view/allocation-view.component'; +import { AllocationAddComponent } from './allocation-add/allocation-add.component'; +import { Routes, RouterModule } from '@angular/router'; +import { AllocationComponent } from './allocation.component'; +import { MatMenuModule } from '@angular/material/menu'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TableModule } from 'primeng/table'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { InputTextModule } from 'primeng/inputtext'; +import { CalendarModule } from 'primeng/calendar'; +import { DialogModule } from 'primeng/dialog'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { ToastModule } from 'primeng/toast'; +import { MatButtonModule } from '@angular/material/button'; + + +const routes: Routes = [ + { + path: 'AddAllocation/:Hotel_Eaxtranet_Id', + component: AllocationAddComponent, + }, + // { + // path: 'UpdateAllocation/:Hotel_Eaxtranet_Id/:RuleId', + // component: AllocationViewComponent, + // }, +] + + +@NgModule({ + declarations: [ + AllocationComponent, + AllocationViewComponent, + AllocationAddComponent + ], + imports: [ + TableModule, + DialogModule, + ButtonModule, + CommonModule, + ToolbarModule, + MatMenuModule, + ToastModule, + NgSelectModule, + CalendarModule, + FormsModule, + ReactiveFormsModule, + InputTextModule, + MatButtonModule, + RouterModule.forChild(routes), + ], + exports:[ + AllocationComponent + ] +}) +export class AllocationModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.html new file mode 100644 index 0000000..a2c30af --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.html @@ -0,0 +1,85 @@ + +
    +
    +
    +

    Add Block Dates

    +
    +
    +
    +
    +
    + + + Please + enter rule name +
    +
    + + + +
    +
    +
    +

    Block Date Type

    +
    + +
    +
    +
    + Select + Check-in Date + Check-out Date +
    + Please + select block date type +
    +
    +
    +
    +
    + + + + Please + select from date +
    +
    + + + + Please + select to date +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.ts new file mode 100644 index 0000000..c235bcb --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-add-block-date/hotel-add-block-date.component.ts @@ -0,0 +1,109 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import * as moment from 'moment'; + +@Component({ + selector: 'app-hotel-add-block-date', + templateUrl: './hotel-add-block-date.component.html', +}) +export class HotelAddBlockDateComponent implements OnInit { + + Extranet_Hotel_Id; + Edit_Id; + minDate = new Date(); + constructor(public activateRoute:ActivatedRoute,private apiserv: API,public fb:FormBuilder, public validserv:ValidationService,public MsgService:MessageService, private router: Router,private hotelmanageserv:ManageHotelService) { } + BlockSearchDaysForm; + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.BlockSearchDaysForm= this.fb.group({ + rule_name:this.validserv.required, + block_date_type:this.validserv.required, + extranet_block_date_rule_id:'', + DateRange:this.fb.array([ + this.fb.group({ + date_from:this.validserv.required, + date_to:this.validserv.required, + extranet_block_date_id:'', + }) + ]) + }); + if(this.Edit_Id){ + this.apiserv.Get('/ExtranetBlockDate/GetExtranetBlockDateById/'+this.Edit_Id).subscribe(res=>{ + if(res && res.status){ + this.setvalue(res.data) + } + }) + } + } + addDateArr(){ + this.BlockSearchDaysForm.controls['DateRange'].push( + this.fb.group({ + date_from:this.validserv.required, + date_to:this.validserv.required, + extranet_block_date_id:'', + }) + ) + } + removeDateArr(i){ + this.BlockSearchDaysForm.controls['DateRange'].removeAt(i) + } + setvalue(data){ + this.BlockSearchDaysForm.get('rule_name').setValue(data[0].rule_name); + this.BlockSearchDaysForm.get('extranet_block_date_rule_id').setValue(data[0].extranet_block_date_rule_id); + this.BlockSearchDaysForm.get('block_date_type').setValue(data[0].block_date_type); + data.forEach((date_arr,ind)=>{ + if(ind > 0)this.addDateArr() + this.BlockSearchDaysForm.controls['DateRange']['controls'][ind].get('extranet_block_date_id').setValue(date_arr.extranet_block_date_id); + console.log(new Date(date_arr.date_from)) + this.BlockSearchDaysForm.controls['DateRange']['controls'][ind].get('date_from').setValue(new Date(date_arr.date_from)); + this.BlockSearchDaysForm.controls['DateRange']['controls'][ind].get('date_to').setValue(new Date(date_arr.date_to)); + }) + } + + Save(){ + if (this.BlockSearchDaysForm.status == "INVALID") { + this.validserv.showValidationsMsg(this.BlockSearchDaysForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let Req_value = this.BlockSearchDaysForm.getRawValue(); + let ReqObj = [] + Req_value.DateRange.forEach(val=>{ + let from_date = new Date(Date.UTC(val.date_from.getFullYear(), val.date_from.getMonth(), val.date_from.getDate())) + let to_date = new Date(Date.UTC(val.date_to.getFullYear(), val.date_to.getMonth(), val.date_to.getDate())) + let Obj={ + extranet_block_date_id:val.extranet_block_date_id, + extranet_block_date_rule_id:Req_value.extranet_block_date_rule_id ? Req_value.extranet_block_date_rule_id :'', + extranet_hotel_id:this.Extranet_Hotel_Id ? this.Extranet_Hotel_Id : '', + rule_name:Req_value.rule_name ? Req_value.rule_name : '', + block_date_type:Req_value.block_date_type ? Req_value.block_date_type : '', + date_from:val.date_from ? moment(from_date).toISOString() : '', + date_to:val.date_to ? moment(to_date).toISOString() : '' + } + ReqObj.push(Obj) + }) + this.apiserv.Post('/ExtranetBlockDate/SaveExtranetBlockDate',ReqObj).subscribe(data=>{ + if(data){ + this.MsgService.add({ + severity: data.status ? "success" : "error", + detail: data.message, + }); + data.status ? this.backbutton() : ''; + } + }) + } + + backbutton(){ + this.hotelmanageserv.Active_tab = 'BlockDates'; + this.router.navigateByUrl("/Services/Hotel/HotelManage/"+this.Extranet_Hotel_Id); + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.html new file mode 100644 index 0000000..a6264a3 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.html @@ -0,0 +1,163 @@ +
    +
    +
    +

    Block Dates

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Block Date Type

    +
    + +
    +
    +
    + Select + Check-in Date + Check-out Date +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Rule Name + + + + Block Date Type + + + + Dates + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.rule_name}} + {{data.block_date_type}} + {{item}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.ts new file mode 100644 index 0000000..772451b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.component.ts @@ -0,0 +1,97 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'hotel-block-date', + templateUrl: './hotel-block-date.component.html', +}) +export class HotelBlockDateComponent implements OnInit { + + Extranet_Hotel_Id; + Result; + cols; + Rule_Name; + Date_Type; + constructor(public activateRoute:ActivatedRoute,private apiserv:API,public _commonService:CommonFunctionService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.cols = [ + { field: 'rule_name', header: 'Rule Name' }, + { field: 'block_date_type', header: 'Block Date Type' }, + { field: 'date_range_arr', header: 'Dates' }, + { field: 'status', header: 'status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + } + + Search(){ + let ReqObj = { + rule_name:this.Rule_Name ? this.Rule_Name : '', + block_date_type:this.Date_Type ? this.Date_Type : '', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetBlockDate/GetAllExtranetBlockDate',ReqObj).subscribe(res=>{ + if(res){ + this.Result = res.data ? res.data : []; + if(res.data){ + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + e['Custom_created_on'] = this._commonService.convertDateWithTimeToShow(e.created_on); + e['block_date_type'] = e.block_date_type == 'CHECKINDATE' ? 'Check-in Date' : 'Check-out Date'; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetBlockDate/UpdateExtranetBlockDateStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditBlockDate/${this.Extranet_Hotel_Id}/${Id}`); + } + Reset(){ + this.Rule_Name = undefined; + this.Date_Type = undefined; + } + btnClick() { + this.router.navigateByUrl("Services/FlightInventory/Add"); + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.module.ts new file mode 100644 index 0000000..afe57a7 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-block-date/hotel-block-date.module.ts @@ -0,0 +1,60 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelBlockDateComponent } from './hotel-block-date.component'; +import { HotelAddBlockDateComponent } from './hotel-add-block-date/hotel-add-block-date.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; + +const routes: Routes = [ + + { + path: 'HotelAddBlockDate/:Hotel_Eaxtranet_Id', + component:HotelAddBlockDateComponent, + }, + { + path: 'HotelEditBlockDate/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelAddBlockDateComponent, + } +] + +@NgModule({ + declarations: [ + HotelBlockDateComponent, + HotelAddBlockDateComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelBlockDateComponent + ] +}) +export class HotelBlockDateModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.html new file mode 100644 index 0000000..6c8d82f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.html @@ -0,0 +1,103 @@ +
    + + Back +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.ts new file mode 100644 index 0000000..a100c4f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-manage.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; + +@Component({ + selector: 'app-hotel-manage', + templateUrl: './hotel-manage.component.html', +}) +export class HotelManageComponent implements OnInit { + + constructor(public hotelmanageserv:ManageHotelService,private activateRoute:ActivatedRoute,public commonserv:CommonFunctionService) { } + + ngOnInit(): void { + this.hotelmanageserv.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + window.scrollTo(0, 0); + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-manage.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-manage.module.ts new file mode 100644 index 0000000..01d677c --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-manage.module.ts @@ -0,0 +1,173 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelManageComponent } from './hotel-manage.component'; +import { TabViewModule } from 'primeng/tabview'; +import { RouterModule, Routes } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { HotelRoomModule } from './hotel-room/hotel-room.module'; +import { HotelSeasonModule } from './hotel-season/hotel-season.module'; +import { RateSettingModule } from './rate-setting/rate-setting.module'; +import {MatMenuModule} from '@angular/material/menu'; +import { HotelMealModule } from './hotel-meal/hotel-meal.module'; +import { HotelBlockDateModule } from './hotel-block-date/hotel-block-date.module'; +import { HotelOffersModule } from './hotel-offers/hotel-offers.module'; +import { HotelSupplementsModule } from './hotel-supplements/hotel-supplements.module'; +import { AllocationModule } from './allocation/allocation.module'; +import { HotelUpdateAdultModule } from './hotel-update-adult/hotel-update-adult.module'; +import { HotelUpdateChildModule } from './hotel-update-child/hotel-update-child.module'; +import { HotelUpdateCancellationModule } from './hotel-update-cancellation/hotel-update-cancellation.module'; +import { HotelUpdateNationalityModule } from './hotel-update-nationality/hotel-update-nationality.module'; +import { HotelUpdateMealAddOnModule } from './hotel-update-meal-add-on/hotel-update-meal-add-on.module'; +import { HotelUpdateAllocationModule } from './hotel-update-allocation/hotel-update-allocation.module'; +import { OverviewModule } from './overview/overview.module'; +import { MinimumStayModule } from './minimum-stay/minimum-stay.module'; + +const routes: Routes = [ + { + path: ':Hotel_Eaxtranet_Id', + component:HotelManageComponent, + }, + { + path: 'RoomSearch', + loadChildren: () => + import('./hotel-room/hotel-room.module').then( + (m) => m.HotelRoomModule + ), + }, + { + path: 'SeasonSearch', + loadChildren: () => + import('./hotel-season/hotel-season.module').then( + (m) => m.HotelSeasonModule + ), + }, + { + path: 'RateSettingSearch', + loadChildren: () => + import('./rate-setting/rate-setting.module').then( + (m) => m.RateSettingModule ), + }, + // { + // path: 'Allocation', + // loadChildren: () => + // import('./allocation/allocation.module').then( + // (m) => m.AllocationModule + // ), + // }, + { + path: 'MealSearch', + loadChildren: () => + import('./hotel-meal/hotel-meal.module').then( + (m) => m.HotelMealModule + ), + }, + { + path: 'BlockDateSearch', + loadChildren: () => + import('./hotel-block-date/hotel-block-date.module').then( + (m) => m.HotelBlockDateModule + ), + }, + { + path: 'UpdateAdult', + loadChildren: () => + import('./hotel-update-adult/hotel-update-adult.module').then( + (m) => m.HotelUpdateAdultModule + ), + }, + { + path: 'UpdateChild', + loadChildren: () => + import('./hotel-update-child/hotel-update-child.module').then( + (m) => m.HotelUpdateChildModule + ), + }, + { + path: 'UpdateCancellation', + loadChildren: () => + import('./hotel-update-cancellation/hotel-update-cancellation.module').then( + (m) => m.HotelUpdateCancellationModule + ), + }, + { + path: 'UpdateNationality', + loadChildren: () => + import('./hotel-update-nationality/hotel-update-nationality.module').then( + (m) => m.HotelUpdateNationalityModule + ), + }, + { + path: 'UpdateMealAddOn', + loadChildren: () => + import('./hotel-update-meal-add-on/hotel-update-meal-add-on.module').then( + (m) => m.HotelUpdateMealAddOnModule + ), + }, + { + path: 'UpdateAllocation', + loadChildren: () => + import('./hotel-update-allocation/hotel-update-allocation.module').then( + (m) => m. HotelUpdateAllocationModule + ), + }, + { + path: 'Offers', + loadChildren: () => + import('./hotel-offers/hotel-offers.module').then( + (m) => m.HotelOffersModule + ), + }, + { + path: 'Supplements', + loadChildren: () => + import('./hotel-supplements/hotel-supplements.module').then( + (m) => m.HotelSupplementsModule + ), + }, + { + path: 'OverView', + loadChildren: () => + import('./overview/overview.module').then( + (m) => m.OverviewModule + ), + }, + { + path: 'MinimumStay', + loadChildren: () => + import('./minimum-stay/minimum-stay.module').then( + (m) => m.MinimumStayModule + ), + }, +] + + +@NgModule({ + declarations: [ + HotelManageComponent, + ], + imports: [ + CommonModule, + FormsModule, + MatMenuModule, + HotelRoomModule, + TabViewModule, + AllocationModule, + HotelSeasonModule, + RateSettingModule, + HotelUpdateAdultModule, + HotelUpdateChildModule, + HotelUpdateCancellationModule, + HotelUpdateNationalityModule, + HotelUpdateMealAddOnModule, + HotelUpdateAllocationModule, + HotelMealModule, + OverviewModule, + HotelBlockDateModule, + HotelOffersModule, + HotelSupplementsModule, + MinimumStayModule, + RouterModule.forChild(routes), + +] +}) +export class HotelManageModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.html new file mode 100644 index 0000000..f3425e9 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.html @@ -0,0 +1,236 @@ + +
    +
    +
    +

    Add Meal Add-On

    +
    +
    +
    +
    +
    +
    + + + Please + enter meal add-on name +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + Select + {{data.meal_plan_name}} +
    + Please + select meal plan +
    +
    +
    +
    + + + +
    +
    +
    +

    Currency

    +
    + +
    +
    +
    + + {{item.currency_code }} + +
    + Please + select currency +
    +
    +
    +
    + + + Please + enter adult rate +
    +
    +
    +
    +
    + Paid Child +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age From

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select paid child age from + Please + select age greater than previous age range +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age To

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select paid child age to + Please + select age to greater than age from +
    +
    +
    +
    + + + Please + enter paid child rate +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.ts new file mode 100644 index 0000000..b4d32d5 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal-add/hotel-meal-add.component.ts @@ -0,0 +1,188 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + + +@Component({ + selector: 'app-hotel-meal-add', + templateUrl: './hotel-meal-add.component.html', +}) +export class HotelMealAddComponent implements OnInit { + + Extranet_Hotel_Id; + constructor(public activateRoute:ActivatedRoute,private router:Router,private hotelmanageserv:ManageHotelService, + public apiserv:API,public fb:FormBuilder,public validserv:ValidationService,public commonMasterSer:CommonFunctionService) { } + ddLoader; + timer; + MealPlan; + CurrencyList; + Edit_Id; + occupancy_Limit_Child = [0,1,2,3,4,5,6,7,8,9,10,11]; + MealAddForm:FormGroup; + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.initForm(); + this.GetAllMeal(); + this.GetMealAddOnById(); + } + initForm(){ + this.MealAddForm = this.fb.group({ + extranet_meal_addon_id:'', + extranet_meal_plan_id:this.validserv.required, + addon_name:this.validserv.required, + currency:this.validserv.required, + adult_rate:this.validserv.required, + is_paid_child:false, + }) + } + SetMealAddOn(data){ + this.MealAddForm.get('extranet_meal_addon_id').setValue(data.extranet_meal_addon_id); + this.MealAddForm.get('extranet_meal_plan_id').setValue(data.extranet_meal_plan_id); + this.MealAddForm.get('addon_name').setValue(data.addon_name); + this.MealAddForm.get('currency').setValue(data.currency); + this.MealAddForm.get('adult_rate').setValue(data.adult_rate); + this.MealAddForm.get('is_paid_child').setValue(data.is_paid_child); + if(data.child_range_1_from || data.child_range_1_to || data.child_range_1_rate){ + this.PaidChildArr(true); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][0].get('from_age').setValue(data.child_range_1_from ? data.child_range_1_from : 0); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][0].get('to_age').setValue(data.child_range_1_to ? data.child_range_1_to : 0); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][0].get('child_rate').setValue(data.child_range_1_rate ? data.child_range_1_rate : 0); + if(data.child_range_2_from || data.child_range_2_to || data.child_range_2_rate){ + this.AddChildArr(); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][1].get('from_age').setValue(data.child_range_2_from ? data.child_range_2_from : 0); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][1].get('to_age').setValue(data.child_range_2_to ? data.child_range_2_to : 0); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][1].get('child_rate').setValue(data.child_range_2_rate ? data.child_range_2_rate : 0); + } + } + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'HotelMeal'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + GetAllMeal(){ + this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMeal/EN').subscribe(res=>{ + if(res){ + this.MealPlan = res.data; + } + }) + } + + GetCurrency(event){ + if (event.value.length >= 2) { + let obj ={ + langcode:'en', + query:event.value + } + this.ddLoader = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost(`/MasterSearch/GetAllCurrency`,obj).subscribe(res => { + if (res) { + this.CurrencyList = res.Result; + this.ddLoader = false; + } + }); + }, 500); + } +} +PaidChildArr(event){ + if(event){ + this.MealAddForm.addControl('ExtranetChildAgeRange',new FormArray([this.fb.group({ + from_age:this.validserv.required, + to_age:this.validserv.required, + child_rate:this.validserv.required, + })])); + }else { + this.MealAddForm.removeControl('ExtranetChildAgeRange'); + } +} +AddChildArr(){ + let formArray = this.MealAddForm.controls['ExtranetChildAgeRange'] as FormArray; + formArray.push( + this.fb.group({ + from_age:['', Validators.compose([Validators.required,this.AmountRangeValidation(formArray.controls[0].get('to_age') ? formArray.controls[0].get('to_age').value : '')])], + to_age:this.validserv.required, + child_rate:this.validserv.required, + }) + ) +} +RemoveChildArr(i){ + let formArray = this.MealAddForm.controls['ExtranetChildAgeRange'] as FormArray; + formArray.removeAt(i); +} +ChangeFeeMinValue(controlname,min,i?) { + let min_amt = min; + if (i == 0 || i) { + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).clearValidators(); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).markAsUntouched(); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).setErrors(null); + this.MealAddForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).updateValueAndValidity(); + }else { + this.MealAddForm.controls[controlname].clearValidators(); + this.MealAddForm.controls[controlname].addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.MealAddForm.controls[controlname].markAsUntouched(); + this.MealAddForm.controls[controlname].setErrors(null); + this.MealAddForm.controls[controlname].updateValueAndValidity(); + } +}; +private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value == 0) { + if (initialValue && parseInt(control.value) <= parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; +} +Save(){ + if (this.MealAddForm.status == "VALID") { + let val = this.MealAddForm.getRawValue(); + let reqObj={ + extranet_meal_addon_id: val.extranet_meal_addon_id ? val.extranet_meal_addon_id :'', + extranet_hotel_id: this.Extranet_Hotel_Id, + addon_name: val.addon_name, + currency: val.currency, + extranet_meal_plan_id: val.extranet_meal_plan_id, + adult_rate: parseFloat(val.adult_rate), + is_paid_child: val.is_paid_child, + } + if(val.ExtranetChildAgeRange && val.ExtranetChildAgeRange.length > 0){ + val.ExtranetChildAgeRange.forEach((child_obj,ind)=>{ + reqObj['child_range_'+(ind + 1)+'_from'] = child_obj.from_age; + reqObj['child_range_'+(ind + 1)+'_to'] = child_obj.to_age; + reqObj['child_range_'+(ind + 1)+'_rate'] = child_obj.child_rate ? parseFloat(child_obj.child_rate) : 0; + }) + } + this.apiserv.Post('/ExtranetMealAddon/SaveExtranetMealAddon',reqObj).subscribe(resp=>{ + if(resp){ + this.BackButton(); + } + this.commonMasterSer.showMessage(resp.status,resp.message) + }) + }else { + this.validserv.showValidationsMsg(this.MealAddForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } +} + GetMealAddOnById() { + if (this.Edit_Id) { + this.apiserv.Get("/ExtranetMealAddon/GetExtranetMealAddonById/" + this.Edit_Id).subscribe(res=>{ + if(res){ + this.SetMealAddOn(res.data) + } + }) + } + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.html new file mode 100644 index 0000000..d247f0e --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.html @@ -0,0 +1,197 @@ +
    +
    +
    +

    Meal Add-On

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Add-On Name

    +
    + +
    +
    +
    + Select + {{data.addon_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + Select + {{data.meal_plan_name}} +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Meal Add-On Name + + + + Meal Plan + + + + Currency + + + + Adult Rate + + + + Paid Child + + + + Meal Add-On Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.addon_name}} + {{data.meal_plan_name}} + {{data.currency}} + {{data.adult_rate}} + {{data.is_paid_child}} + {{data.extranet_meal_addon_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.ts new file mode 100644 index 0000000..58f9b27 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.component.ts @@ -0,0 +1,113 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { forkJoin } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'hotel-meal', + templateUrl: './hotel-meal.component.html', +}) +export class HotelMealComponent implements OnInit { + + Extranet_Hotel_Id; + Result; + AllMealPlan; + AllMealAddon; + MealPlan; + MealAddon; + cols; + constructor(public activateRoute:ActivatedRoute,private router:Router, public apiserv:API,public _commonService:CommonFunctionService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.cols = [ + { field: 'addon_name', header: 'Meal Add-On Name' }, + { field: 'meal_plan_name', header: 'Meal Plan' }, + { field: 'currency', header: 'Currency' }, + { field: 'adult_rate', header: 'Adult Rate' }, + { field: 'currency', header: 'Currency' }, + { field: 'is_paid_child', header: 'Paid Child' }, + { field: 'status', header: 'Status' }, + { field: 'extranet_meal_addon_id', header: 'Meal Add-On Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.getAllData(); + } + + Search(){ + let ReObj = { + addon_name:this.MealAddon ? this.MealAddon : '', + extranet_meal_plan_id:this.MealPlan ? this.MealPlan : '', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetMealAddon/GetAllExtranetMealAddon',ReObj).subscribe(res=>{ + if (res) { + this.Result = res.data ? res.data : []; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + getAllData() { + forkJoin( + this.GetAllMealPlan(), + this.GetAllMealAddon(), + ).subscribe(result => { + if (result && result.length > 0) { + this.AllMealPlan = result[0].data; + this.AllMealAddon = result[1].data; + } + }) + } + GetAllMealPlan(){ + return this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMeal/EN') + } + GetAllMealAddon(){ + return this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMealAddonByOrg/'+ this.Extranet_Hotel_Id) + } + updateStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetMealAddon/UpdateExtranetMealAddOnStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelMealEdit/${this.Extranet_Hotel_Id}/${Id}`); + } + Reset(){ + this.MealAddon = undefined; + this.MealPlan = undefined; + } + btnClick() { + this.router.navigateByUrl("Services/FlightInventory/Add"); + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.module.ts new file mode 100644 index 0000000..81e918b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-meal/hotel-meal.module.ts @@ -0,0 +1,61 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelMealComponent } from './hotel-meal.component'; +import { HotelMealAddComponent } from './hotel-meal-add/hotel-meal-add.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; + + +const routes: Routes = [ + + { + path: 'HotelMealAdd/:Hotel_Eaxtranet_Id', + component:HotelMealAddComponent, + }, { + path: 'HotelMealEdit/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelMealAddComponent, + }, +] + + +@NgModule({ + declarations: [ + HotelMealComponent, + HotelMealAddComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelMealComponent + ] +}) +export class HotelMealModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.html new file mode 100644 index 0000000..a93d1e5 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.html @@ -0,0 +1 @@ + diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.ts new file mode 100644 index 0000000..277d770 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'hotel-offers', + templateUrl: './hotel-offers.component.html', +}) +export class HotelOffersComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.module.ts new file mode 100644 index 0000000..ac14397 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/hotel-offers.module.ts @@ -0,0 +1,58 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { OffersAddComponent } from './offers-add/offers-add.component'; +import { OffersViewComponent } from './offers-view/offers-view.component'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { ButtonModule } from 'primeng/button'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MatMenuModule } from '@angular/material/menu'; +import { CalendarModule } from 'primeng/calendar'; +import { InputTextModule } from 'primeng/inputtext'; +import { HotelOffersComponent } from './hotel-offers.component'; +import { FormsModule,ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; + +const routes: Routes = [ + { + path: 'View', + component: OffersViewComponent, + }, + { + path: 'AddOffer/:Hotel_Eaxtranet_Id', + component: OffersAddComponent, + }, + { + path: 'EditOffer/:Hotel_Eaxtranet_Id/:RuleId', + component: OffersAddComponent, + }, +] + +@NgModule({ + declarations: [ + HotelOffersComponent, + OffersAddComponent, + OffersViewComponent + ], + imports: [ + CommonModule, + NgSelectModule, + MatCheckboxModule, + ButtonModule, + TableModule, + FormsModule, + ReactiveFormsModule, + ToolbarModule, + MatMenuModule, + MatButtonModule, + InputTextModule, + CalendarModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelOffersComponent + ] +}) +export class HotelOffersModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.html new file mode 100644 index 0000000..74cad33 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.html @@ -0,0 +1,961 @@ + +
    +
    +
    +

    Add Offers

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Contracts

    +
    + +
    +
    + +
    + {{item}} + {{item}} + {{data.room_name}} +
    + Please + select rooms +
    +
    +
    +
    + + +
    +
    +
    +
    + + + Please + enter offer name +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + Early Bird + Stay Pay + Long Stay + Discount + Contract Remark +
    + Please + select offer type +
    +
    +
    + Combinable Offer +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + {{item.offer_name}} +
    +
    +
    +
    +
    + + + Please + enter discount code +
    +
    +
    + Minimum + Stay +
    +
    +
    + + + Please + enter minimum stay value +
    +
    +
    + Maximum + Stay +
    +
    +
    + + + Please + enter maximum stay value +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + enter select nationality type +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select nationality applicability +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select nationality +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select residence type +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select residence applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select residence +
    +
    +
    +
    +
    +
    +
    + + + + Please select date greater than from previous range + + + Please select range to date + + + Please select date range + + + Please enter unique values for each row + +
    +
    +
    +
    + + + + Please select date greater than from previous range + + + Please select range greater than previous range + + + Please select date range + +
    +
    +
    +
    + + + Please + enter check in before days +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Offer Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    + Please + select offer days +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy

    +
    + +
    +
    +
    + Select + Original + Non Refundable + Custom Policy +
    + Please + select cancellation policy +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy

    +
    + +
    +
    +
    + Select + Day +
    + Please + select cancellation policy type +
    +
    +
    + +
    +
    +
    +
    + + + Please + enter from + Please + enter range greater than previous range +
    +
    + + + Please + enter to + Please + enter to value greater than from value +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Type

    +
    + +
    +
    +
    + Select + Full Charges + Night Count + Amount + Percentage +
    + Please + select cancellation type +
    +
    + + + +
    +
    +
    +

    Night Type

    +
    + +
    +
    +
    + Select + First + Last + Cheapest + Highest +
    + Please + select night type +
    +
    + + + Please + enter value +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Applicable Adult Occupancy

    +
    + +
    +
    + +
    + {{item}} + {{item}} Adult +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Applicable Child Occupancy

    +
    + +
    +
    + +
    + {{item}} + {{item}} Child +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Offer Applicable On

    +
    + +
    +
    +
    + Select + Room Rate Only + Total Room Rate including + Supplement +
    + Please + select offer applicable on +
    +
    +
    +
    + + + +
    +
    +
    +

    Stay Pay Applicable On

    +
    + +
    +
    +
    + Select + First Night + Last Night + Cheapest Night + Costliest Night +
    + Please + select stay pay applicable on +
    +
    +
    +
    + + + Please + enter stay night +
    +
    +
    +
    + + + Please + enter pay night +
    +
    +
    + Multiple Stay Pay Allowed + +
    +
    +
    + + +
    +
    +
    +
    + + + Please + enter long stay +
    +
    +
    +
    + + + +
    +
    +
    +

    Discount Type

    +
    + +
    +
    +
    + Select + Amount + Percentage +
    + Please + select discount type +
    +
    +
    +
    + + + Please + enter discount value +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + Please + enter contract remark +
    +
    +
    +
    +
    +
    + +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.ts new file mode 100644 index 0000000..f44d4a8 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-add/offers-add.component.ts @@ -0,0 +1,733 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-offers-add', + templateUrl: './offers-add.component.html', +}) +export class OffersAddComponent implements OnInit { + + Extranet_Hotel_Id; + AllContrtact; + combineOfferList; + timer; + Check_Same_Value_Arr = []; + MinDate = new Date(); + ddLoader = { + Country:false, + Residence:false, + }; + CountryList; + Adult_Occupancy_List; + Child_Occupancy_List; + selectAll = ['Select All']; + Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + selectAllAdult = []; + selectAllChild = []; + SelectAllRoom = []; + ClearAllRoom = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Offers_Form:FormGroup; + Edit_Id; + constructor( + private router: Router, + public activateRoute:ActivatedRoute, + private hotelmanageserv:ManageHotelService, + public apiserv:API,public fb:FormBuilder,public validserv:ValidationService,public commonMasterSer:CommonFunctionService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Initform(); + this.GetAllData(); + } + GetAllContract(){ + let obj = { + extranet_hotel_id:this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOfferAndSupplementContracts',obj) + } + GetHotelDetail(){ + return this.apiserv.Get('/ExtranetHotel/GetExtranetHotelById/' + this.Extranet_Hotel_Id) + } + GetAllData(){ + forkJoin( + this.GetAllContract(), + this.GetHotelDetail(), + this.GetOfferById(this.Edit_Id) + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllContrtact = res[0].data; + if(res[0].data){ + this.SelectAllRoom = ['Select All']; + } + if(res[1]?.data)this.Offers_Form.get('currency').setValue(res[1].data.currency); + this.SetOfferFormValue(res[2] ? res[2].data :'') + } + }) + } + GetOfferById(Editid) { + if (Editid) + return this.apiserv.Get('/ExtranetOffer/GetExtranetOfferById/' + Editid) + else + return of(null) + }; + Initform(){ + this.Offers_Form = this.fb.group({ + extranet_offer_id:'', + extranet_room_id:this.validserv.required, + offer_name:this.validserv.required, + currency:this.validserv.required, + offer_type:this.validserv.required, + is_combinable_offer:false, + combinable_offer_id:'', + offer_days:this.validserv.required, + is_min_stay:false, + is_max_stay:false, + is_stay_pay_multiple:false, + max_reoccurence:'', + residence_type:'', + residence_applicable_type:'', + offer_nationality_type:'', + nationality_applicable_type:'', + cancellation_policy_type:this.validserv.required, + type:this.validserv.required, + applicable_on:this.validserv.required, + applicable_adult_occupancy:'', + applicable_child_occupancy:'', + offer_description:'', + date_criteria:this.fb.array([]), + custom_cancellation_policy:this.fb.array([this.fb.group({ + from: [0,Validators.compose([Validators.required])], + to: ['',Validators.compose([Validators.required,this.AmountRangeValidation(0)])], + charge_type: this.validserv.required, + charge_value: this.validserv.required, + })]) + }); + this.addDate() + } + addDate() { + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.push(this.fb.group({ + booking_date_range: ['', Validators.compose([ + Validators.required, + this.dateValidation() + ])], + checkin_date_range: ['', Validators.compose([ + Validators.required, + this.dateValidation() + ])], + })); + if(this.Offers_Form.controls['offer_type'].value != 'CONTRACTREMARK'){ + let group = formArray.controls[formArray.controls.length - 1] as FormGroup; + group.addControl('checkin_before_days',new FormControl('',Validators.required)); + } + this.Check_Same_Value_Arr[formArray.controls.length - 1] = false; + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + this.Check_Same_Value_Arr[index] = false; + formArray.removeAt(index); + this.check_Unique_Values(); + } + Check_Offer_Type(event){ + if(event == 'STAYPAY'){ + this.Offers_Form.addControl('stay_pay_applicable_on',new FormControl('',Validators.required)); + this.Offers_Form.addControl('stay_night',new FormControl('',Validators.required)); + this.Offers_Form.addControl('pay_night',new FormControl('',Validators.required)); + if(!this.Offers_Form['discount_code']){ + this.Offers_Form.addControl('discount_code',new FormControl('',Validators.required)); + } + this.Offers_Form.removeControl('contract_remark'); + this.Offers_Form.removeControl('long_stay_night') + this.CheckAddremovecontrol('offer_days',this.Offers_Form,true); + this.CheckAddremovecontrol('cancellation_policy_type',this.Offers_Form,true); + this.CheckAddremovecontrol('type',this.Offers_Form,true); + this.CheckAddremovecontrol('applicable_on',this.Offers_Form,true); + this.Offers_Form.removeControl('discount_type'); + this.Offers_Form.removeControl('discount_value'); + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.controls.forEach((control:FormGroup)=>{ + this.CheckAddremovecontrol('checkin_before_days',control,true) + }); + this.Check_Cancel_Type(); + } + if(event != 'STAYPAY' && event!= 'CONTRACTREMARK'){ + if(!this.Offers_Form['discount_type']){ + this.Offers_Form.addControl('discount_type',new FormControl('',Validators.required)); + this.Offers_Form.addControl('discount_value',new FormControl('',Validators.required)); + } + if(!this.Offers_Form['discount_code']){ + this.Offers_Form.addControl('discount_code',new FormControl('',Validators.required)); + } + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.controls.forEach((control:FormGroup)=>{ + this.CheckAddremovecontrol('checkin_before_days',control,true) + }); + this.CheckAddremovecontrol('offer_days',this.Offers_Form,true); + this.CheckAddremovecontrol('cancellation_policy_type',this.Offers_Form,true); + this.CheckAddremovecontrol('type',this.Offers_Form,true); + this.CheckAddremovecontrol('applicable_on',this.Offers_Form,true); + this.Check_Cancel_Type(); + } + if(event == 'CONTRACTREMARK'){ + this.Offers_Form.addControl('contract_remark',new FormControl('',Validators.required)); + this.Offers_Form.removeControl('stay_pay_applicable_on'); + this.Offers_Form.removeControl('stay_night'); + this.Offers_Form.removeControl('pay_night'); + this.Offers_Form.removeControl('discount_code'); + this.Offers_Form.removeControl('long_stay_night'); + this.Offers_Form.removeControl('discount_type'); + this.Offers_Form.removeControl('discount_value'); + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.controls.forEach((control:FormGroup)=>{ + this.CheckAddremovecontrol('checkin_before_days',control,false) + }); + this.CheckAddremovecontrol('offer_days',this.Offers_Form,false); + this.CheckAddremovecontrol('cancellation_policy_type',this.Offers_Form,false); + this.CheckAddremovecontrol('type',this.Offers_Form,false); + this.CheckAddremovecontrol('custom_cancellation_policy',this.Offers_Form,false); + this.CheckAddremovecontrol('applicable_on',this.Offers_Form,false); + } + if(event == 'LONGSTAY'){ + this.Offers_Form.addControl('long_stay_night',new FormControl('',Validators.required)); + if(!this.Offers_Form['discount_code']){ + this.Offers_Form.addControl('discount_code',new FormControl('',Validators.required)); + } + this.Offers_Form.removeControl('stay_pay_applicable_on'); + this.Offers_Form.removeControl('stay_night'); + this.Offers_Form.removeControl('pay_night'); + this.Offers_Form.removeControl('contract_remark'); + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.controls.forEach((control:FormGroup)=>{ + this.CheckAddremovecontrol('checkin_before_days',control,true) + }); + this.CheckAddremovecontrol('offer_days',this.Offers_Form,true); + this.CheckAddremovecontrol('cancellation_policy_type',this.Offers_Form,true); + this.CheckAddremovecontrol('type',this.Offers_Form,true); + this.CheckAddremovecontrol('applicable_on',this.Offers_Form,true); + this.Check_Cancel_Type(); + }else if(event == 'EARLYBIRD'){ + if(!this.Offers_Form['discount_code']){ + this.Offers_Form.addControl('discount_code',new FormControl('',Validators.required)); + } + this.Offers_Form.removeControl('contract_remark'); + this.Offers_Form.removeControl('stay_pay_applicable_on'); + this.Offers_Form.removeControl('stay_night'); + this.Offers_Form.removeControl('pay_night'); + this.Offers_Form.removeControl('long_stay_night'); + let formArray = this.Offers_Form.controls['date_criteria'] as FormArray; + formArray.controls.forEach((control:FormGroup)=>{ + this.CheckAddremovecontrol('checkin_before_days',control,true) + }); + this.CheckAddremovecontrol('offer_days',this.Offers_Form,true); + this.CheckAddremovecontrol('cancellation_policy_type',this.Offers_Form,true); + this.CheckAddremovecontrol('type',this.Offers_Form,true); + this.CheckAddremovecontrol('applicable_on',this.Offers_Form,true); + this.Check_Cancel_Type(); + } + } + CheckAddremovecontrol(controlname,formgroup,check){ + if(check){ + if(!formgroup.get(controlname)){ + formgroup.addControl(controlname,new FormControl('',Validators.required)); + } + }else { + formgroup.removeControl(controlname); + } + } + ChangeFeeMinValue(controlname,min,i?) { + let min_amt = min; + if(this.Offers_Form.controls['custom_cancellation_policy']['controls'][i] && controlname != 'from'){ + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).clearValidators(); + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).markAsUntouched(); + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).setErrors(null); + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).updateValueAndValidity(); + } + if(controlname == 'from' && this.Offers_Form.controls['custom_cancellation_policy']['controls'][i]){ + this.Offers_Form.controls['custom_cancellation_policy']['controls'][i].get(controlname).setValue(min_amt ? (parseInt(min_amt) + 1) : 0) + this.ChangeFeeMinValue('to',min_amt ? (parseInt(min_amt) + 1) : 0 ,i); + } + } + private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value == 0) { + if (initialValue && parseInt(control.value) <= parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; + } + AddCancelArr(ind){ + let formArray = this.Offers_Form.controls['custom_cancellation_policy'] as FormArray; + let cancel_arr = this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind]; + let min_amnt = cancel_arr.get('to').value; + formArray.push( + this.fb.group({ + from: [min_amnt ? (parseInt(min_amnt) + 1) : '',Validators.compose([Validators.required])], + to: this.validserv.required, + charge_type: this.validserv.required, + charge_value: this.validserv.required, + }) + ) + if(min_amnt){ + formArray.controls[formArray['controls'].length -1].get('from').setValue(min_amnt ? parseInt(min_amnt) : '') + this.ChangeFeeMinValue('to',min_amnt ? parseInt(min_amnt) : min_amnt ,ind+1); + } + } + removeCancelArr(room_ind){ + let formArray = this.Offers_Form.controls['custom_cancellation_policy'] as FormArray; + formArray.removeAt(room_ind); + if(formArray.controls[room_ind]){ + let amount = room_ind == 0 ? '' : formArray.controls[room_ind-1].get('to').value; + this.ChangeFeeMinValue('from',amount,room_ind); + } + } + Checkcanceltype(event,room_ind){ + let formcontrol = this.Offers_Form.controls['custom_cancellation_policy']['controls'][room_ind] as FormGroup; + if(event == 'NIGHTCOUNT'){ + formcontrol.addControl('night_type',new FormControl('',Validators.required)); + if(!formcontrol.controls['charge_value']){ + formcontrol.addControl('charge_value',new FormControl('',Validators.required)); + } + } else if(event == 'FULLCHARGES'){ + formcontrol.removeControl('night_type'); + formcontrol.removeControl('charge_value'); + } else { + if(!formcontrol.controls['charge_value']){ + formcontrol.addControl('charge_value',new FormControl('',Validators.required)); + } + formcontrol.removeControl('night_type'); + } + } + MinStay(event){ + if(event){ + this.Offers_Form.addControl('min_stay_value',new FormControl('',Validators.required)); + }else { + this.Offers_Form.removeControl('min_stay_value') + } + } + MaxStay(event){ + if(event){ + this.Offers_Form.addControl('max_stay_value',new FormControl('',Validators.required)); + }else { + this.Offers_Form.removeControl('max_stay_value') + } + } + CheckcontractType(){ + let val = this.Offers_Form.get('extranet_room_id').value; + this.Adult_Occupancy_List = []; + this.Child_Occupancy_List = []; + let child_occ = 0; + let adult_occ = 0; + if (val && val.length > 0 && (val.includes('Select All') || val.length == this.AllContrtact.length) && !val.includes('Clear All')) { + let room_id_List = [] + this.AllContrtact.forEach(d=>{ + room_id_List.push(d.extranet_room_id) + }); + this.Offers_Form.get('extranet_room_id').setValue(room_id_List); + this.SelectAllRoom = []; + this.ClearAllRoom = ['Clear All']; + } else if (val && val.length > 0 && (val.includes('Clear All'))){ + this.Offers_Form.get('extranet_room_id').setValue([]); + this.SelectAllRoom = ['Select All']; + this.ClearAllRoom = []; + } else { + this.SelectAllRoom = ['Select All']; + if(val?.length > 0){ + this.ClearAllRoom = ['Clear All']; + } + } + if(val && val.length > 0){ + let arr = []; + val.forEach(item=>{ + let contract_det = this.AllContrtact.find(e=>item == e.extranet_room_id); + arr.push(contract_det.extranet_room_id); + if(contract_det.max_child_occupancy > child_occ){ + child_occ = contract_det.max_child_occupancy; + this.Child_Occupancy_List = []; + let selected_val = this.Offers_Form.get('applicable_child_occupancy').value + if(selected_val){ + for(let i=selected_val.length;i>0;i--){ + if(selected_val[i] > child_occ){ + selected_val.splice(i,1) + } + } + this.Offers_Form.get('applicable_child_occupancy').setValue(selected_val); + } + for(let i=0;i adult_occ){ + adult_occ = contract_det.max_adult_occupancy; + this.Adult_Occupancy_List = []; + let selected_val = this.Offers_Form.get('applicable_adult_occupancy').value + if(selected_val){ + for(let i=selected_val.length;i>0;i--){ + if(selected_val[i] > adult_occ){ + selected_val.splice(i,1) + } + } + this.Offers_Form.get('applicable_adult_occupancy').setValue(selected_val); + } + for(let i=0;i{ + if(res?.data){ + let filter_array = res.data.filter(elm=>elm.extranet_offer_id != this.Edit_Id); + this.combineOfferList = filter_array.length > 0 ? filter_array : undefined; + }else { + this.combineOfferList = undefined; + this.Offers_Form.get('combinable_offer_id').setValue('') + } + }) + }else { + this.Offers_Form.get('applicable_child_occupancy').setValue(null); + this.Offers_Form.get('applicable_adult_occupancy').setValue(null); + + } + this.CheckAdultSelection(); + this.CheckChildSelection(); + } + NationalityShowhide(event){ + if(event == 'SPECIFIC'){ + this.Offers_Form.addControl('nationality',new FormControl('',Validators.required)) + }else{ + this.Offers_Form.removeControl('nationality'); + } + } + NationalityTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Nationality_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.Offers_Form.controls['nationality_applicable_type'].value == 'ALL'){ + this.Offers_Form.get('nationality_applicable_type').setValue(''); + } + } + } + getCountryList(event,name) { + if (event.value.length >= 2) { + this.ddLoader[name] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader[name] = false; + } + }); + }, 500); + } + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Offers_Form.get('offer_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Offers_Form.get('offer_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + CheckAdultSelection() { + if (this.Offers_Form.controls['applicable_adult_occupancy']) { + let value = this.Offers_Form.get('applicable_adult_occupancy').value; + if (value && value.length > 0 && (value.includes('Select All') || value.length == this.Adult_Occupancy_List.length)) { + this.Offers_Form.get('applicable_adult_occupancy').setValue(this.Adult_Occupancy_List); + this.selectAllAdult = [] + } else { + this.selectAllAdult = this.Adult_Occupancy_List && this.Adult_Occupancy_List.length > 0 ? ['Select All'] : []; + } + }else { + this.selectAllAdult = [] + } + } + CheckChildSelection() { + if (this.Offers_Form.controls['applicable_child_occupancy']) { + let value = this.Offers_Form.get('applicable_child_occupancy').value; + if (value && value.length > 0 && (value.includes('Select All') || value.length == this.Child_Occupancy_List.length)) { + this.Offers_Form.get('applicable_child_occupancy').setValue(this.Child_Occupancy_List); + this.selectAllChild = [] + } else { + this.selectAllChild = this.Child_Occupancy_List && this.Child_Occupancy_List.length > 0 ? ['Select All'] : []; + } + }else { + this.selectAllChild = [] + } + } + check_Unique_Values(){ + let val = this.Offers_Form.getRawValue(); + if(val.date_criteria.length > 0){ + val.date_criteria.forEach((obj, index) => { + if((obj.checkin_before_days || val.offer_type != 'CONTRACTREMARK') && obj.booking_date_range && obj.checkin_date_range){ + //finding the duplicate first remove the current array to check the current from the others + const isDuplicate = val.date_criteria.filter((e,i)=>i != index).some(item => JSON.stringify(item) === JSON.stringify(obj)); + + if (isDuplicate) { + this.Check_Same_Value_Arr[index] = true; + }else { + this.Check_Same_Value_Arr[index] = false; + } + } + else { + this.Check_Same_Value_Arr[index] = false; + + } + }); + // if(!duplicates){ + // this.commonMasterSer.showMessage(false,'two or more booking date range rows has same values'); + // } + // return duplicates; + } + } + Save(){ + let val = this.Offers_Form.getRawValue(); + if (this.Offers_Form.status == "VALID" && this.Check_Same_Value_Arr.every(value => !value)) { + let PostObj={ + extranet_offer_id:val.extranet_offer_id, + extranet_room_id:val.extranet_room_id ? val.extranet_room_id.join(',') : '', + offer_name:val.offer_name, + is_combinable_offer:val.is_combinable_offer && val.offer_type != 'CONTRACTREMARK', + combinable_offer_id:val.combinable_offer_id && val.offer_type != 'CONTRACTREMARK' ? val.combinable_offer_id.join(',') : '', + offer_type:val.offer_type ? val.offer_type : '', + discount_code:val.discount_code ? val.discount_code : '', + offer_nationality_type:val.offer_nationality_type ? val.offer_nationality_type : '', + nationality_applicable_type:val.nationality_applicable_type ? val.nationality_applicable_type : '', + nationality:val.nationality ? val.nationality.join(',') : '', + is_min_stay:val.is_min_stay && val.offer_type != 'CONTRACTREMARK', + min_stay_value:val.min_stay_value && val.offer_type != 'CONTRACTREMARK' ? parseInt(val.min_stay_value) : 0, + is_max_stay:val.is_max_stay && val.offer_type != 'CONTRACTREMARK' , + max_stay_value:val.max_stay_value && val.offer_type != 'CONTRACTREMARK' ? parseInt(val.max_stay_value) : 0, + date_criteria:'', + offer_days:val.offer_days && val.offer_type != 'CONTRACTREMARK' ? val.offer_days.join(',') : '', + applicable_adult_occupancy:val.applicable_adult_occupancy && val.offer_type != 'CONTRACTREMARK' ? val.applicable_adult_occupancy.join(',') : '', + applicable_child_occupancy:val.applicable_child_occupancy && val.offer_type != 'CONTRACTREMARK' ? val.applicable_child_occupancy.join(',') : '', + cancellation_policy_type: val.offer_type != 'CONTRACTREMARK' ? val.cancellation_policy_type : '', + offer_residence_type:val.residence_type, + residence_applicable_type:val.residence_applicable_type, + residence:val.residence_applicable_type == 'SPECIFIC' ? val.residence.join(',') : '', + custom_cancellation_policy:'[]', + applicable_on:val.applicable_on && val.offer_type != 'CONTRACTREMARK' ? val.applicable_on : '', + stay_pay_applicable_on:val.stay_pay_applicable_on ? val.stay_pay_applicable_on : '', + stay_night:val.stay_night ? parseInt(val.stay_night) : 0, + pay_night:val.pay_night ? parseInt(val.pay_night) : 0, + is_stay_pay_multiple:val.offer_type == 'STAYPAY' ? val.is_stay_pay_multiple :false, + max_reoccurence:val.offer_type == 'STAYPAY' && val.is_stay_pay_multiple ? parseInt(val.max_reoccurence) : 0, + long_stay_night:val.long_stay_night ? parseInt(val.long_stay_night) : 0, + discount_type:val.discount_type ? val.discount_type:'', + discount_value:val.discount_value ? parseFloat(val.discount_value) : 0, + offer_description:val.offer_description && val.offer_type != 'CONTRACTREMARK' ? val.offer_description:'', + contract_remark:val.contract_remark?val.contract_remark:'', + } + if(val.custom_cancellation_policy){ + val.custom_cancellation_policy.map(item=>{ + item['type']=val.type; + item['charge_value'] = item['charge_value'] ? item['charge_value'] : 0; + }); + PostObj.custom_cancellation_policy = JSON.stringify(val.custom_cancellation_policy); + } + if(val.date_criteria){ + val.date_criteria.map(e=>{ + e['booking_date_range'] = [moment(e['booking_date_range'][0]).format('YYYY-MM-DD'),moment(e['booking_date_range'][1]).format('YYYY-MM-DD')] + e['checkin_date_range'] = [moment(e['checkin_date_range'][0]).format('YYYY-MM-DD'),moment(e['checkin_date_range'][1]).format('YYYY-MM-DD')] + }); + PostObj.date_criteria = val.date_criteria ? JSON.stringify(val.date_criteria) : ''; + } + // console.log(PostObj); + this.apiserv.Post('/ExtranetOffer/SaveExtranetOffer',PostObj).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + }else { + this.validserv.showValidationsMsg(this.Offers_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } + } + Check_Cancel_Type(){ + let rate_plan_id = this.Offers_Form.get('cancellation_policy_type')?.value; + if(rate_plan_id != 'CUSTOMPOLICY'){ + // this.Offers_Form.controls['RoomPricingDetail']['controls'].forEach(formgroup=>{ + this.Offers_Form.removeControl('custom_cancellation_policy'); + this.Offers_Form.removeControl('type'); + // }) + }else{ + // this.Offers_Form.controls['RoomPricingDetail']['controls'].forEach(formgroup=>{ + // formgroup.removeControl('cancel_policy'); + // formgroup.removeControl('type'); + if(!this.Offers_Form.contains('custom_cancellation_policy')){ + this.Offers_Form.addControl(`type`,new FormControl([],Validators.required)) + this.Offers_Form.addControl(`custom_cancellation_policy`,new FormArray([this.fb.group({ + from: [0,Validators.compose([Validators.required])], + to: ['',Validators.compose([Validators.required,this.AmountRangeValidation(0)])], + charge_type: this.validserv.required, + charge_value: this.validserv.required, + })])) + } + // }) + } + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'Offers'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + SetOfferFormValue(data){ + if(data){ + this.Offers_Form.get('extranet_offer_id').setValue(data.extranet_offer_id); + this.Offers_Form.get('extranet_room_id').setValue(data.extranet_room_id ? data.extranet_room_id.split(','):[]); + this.Offers_Form.get('extranet_room_id').disable(); + if(data.extranet_room_id){ + this.CheckcontractType(); + } + this.Offers_Form.get('offer_name').setValue(data.offer_name); + this.Offers_Form.get('offer_type').setValue(data.offer_type); + this.Check_Offer_Type(data.offer_type); + this.Offers_Form.get('is_combinable_offer').setValue(data.is_combinable_offer); + this.Offers_Form.get('is_stay_pay_multiple').setValue(data.is_stay_pay_multiple); + this.Offers_Form.get('max_reoccurence').setValue(data.max_reoccurence != 0 ? data.max_reoccurence : ''); + this.Offers_Form.get('offer_nationality_type').setValue(data.offer_nationality_type); + this.Offers_Form.get('cancellation_policy_type')?.setValue(data.cancellation_policy_type); + this.Offers_Form.get('nationality_applicable_type').setValue(data.nationality_applicable_type); + this.Offers_Form.get('offer_description').setValue(data.offer_description); + this.Offers_Form.get('applicable_on')?.setValue(data.applicable_on); + this.Offers_Form.get('combinable_offer_id').setValue(data.combinable_offer_id ? data.combinable_offer_id.split(','):[]); + this.Offers_Form.get('applicable_adult_occupancy').setValue(data.applicable_adult_occupancy ? data.applicable_adult_occupancy.split(','):[]); + this.Offers_Form.get('applicable_child_occupancy').setValue(data.applicable_child_occupancy ? data.applicable_child_occupancy.split(','):[]); + this.Offers_Form.get('offer_days')?.setValue(data.offer_days ? data.offer_days.split(','):[]); + this.Offers_Form.get('residence_type').setValue(data.offer_residence_type); + this.Offers_Form.get('residence_applicable_type').setValue(data.residence_applicable_type); + if(data.residence_applicable_type == 'SPECIFIC'){ + this.ResidenceShowhide(data.residence_applicable_type); + this.Offers_Form.get('residence').setValue((data.residence.split(','))); + this.CountryList = data.country ? JSON.parse(data.country) : []; + } + if(data.offer_days){ + this.Check_day_type(); + } + this.Offers_Form.get('is_min_stay').setValue(data.is_min_stay); + if(data.is_min_stay){ + this.MinStay(true); + this.Offers_Form.get('min_stay_value').setValue(data.min_stay_value); + } + this.Offers_Form.get('is_max_stay').setValue(data.is_max_stay); + if(data.is_max_stay){ + this.MaxStay(true); + this.Offers_Form.get('max_stay_value').setValue(data.max_stay_value); + } + if(data.nationality_applicable_type == 'SPECIFIC'){ + this.NationalityShowhide('SPECIFIC'); + this.Offers_Form.get('nationality').setValue(data.nationality.split(',')); + this.CountryList = data.country ? JSON.parse(data.country) : []; + } + if(data.offer_type == 'STAYPAY'){ + this.Offers_Form.get('stay_pay_applicable_on').setValue(data.stay_pay_applicable_on); + this.Offers_Form.get('stay_night').setValue(data.stay_night); + this.Offers_Form.get('pay_night').setValue(data.pay_night); + this.Offers_Form.get('discount_code').setValue(data.discount_code); + } + if(data.offer_type != 'STAYPAY' && data.offer_type != 'CONTRACTREMARK'){ + this.Offers_Form.get('discount_type').setValue(data.discount_type); + this.Offers_Form.get('discount_value').setValue(data.discount_value); + this.Offers_Form.get('discount_code').setValue(data.discount_code); + } + if(data.offer_type == 'CONTRACTREMARK'){ + this.Offers_Form.get('contract_remark').setValue(data.contract_remark); + } + if(data.offer_type == 'LONGSTAY'){ + this.Offers_Form.get('long_stay_night').setValue(data.long_stay_night); + this.Offers_Form.get('discount_code').setValue(data.discount_code); + } + if(data.offer_type == 'EARLYBIRD'){ + this.Offers_Form.get('discount_code').setValue(data.discount_code); + } + if(data.date_criteria){ + let Date_Arr = JSON.parse(data.date_criteria); + Date_Arr.forEach((date_data,ind)=>{ + if(ind > 0)this.addDate(); + this.Offers_Form.controls['date_criteria']['controls'][ind].get('booking_date_range').setValue([new Date(date_data.booking_date_range[0]),new Date(date_data.booking_date_range[1])]) + this.Offers_Form.controls['date_criteria']['controls'][ind].get('checkin_date_range').setValue([new Date(date_data.checkin_date_range[0]),new Date(date_data.checkin_date_range[1])]) + this.Offers_Form.controls['date_criteria']['controls'][ind].get('checkin_before_days')?.setValue(date_data.checkin_before_days) + }) + } + if( data.cancellation_policy_type == 'CUSTOMPOLICY'){ + let Cancel_Arr = JSON.parse(data.custom_cancellation_policy); + this.Offers_Form.get('type').setValue(Cancel_Arr[0].type) + Cancel_Arr.forEach((cancel_data,ind)=>{ + if(ind > 0)this.AddCancelArr(ind -1); + this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind].get('from').setValue(cancel_data.from) + this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind].get('to').setValue(cancel_data.to) + this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind].get('charge_type').setValue(cancel_data.charge_type) + this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind].get('charge_value').setValue(cancel_data.charge_value) + this.Checkcanceltype(cancel_data.charge_type,ind); + if(this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind]['controls']['night_type']){ + this.Offers_Form.controls['custom_cancellation_policy']['controls'][ind].get('night_type').setValue(cancel_data.night_type) + } + }) + }else { + this.Check_Cancel_Type() + } + } + } + ResidenceTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Residence_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.Offers_Form.controls['residence_applicable_type'].value == 'ALL'){ + this.Offers_Form.get('residence_applicable_type').setValue(''); + } + } + } + ResidenceShowhide(event){ + if(event == 'SPECIFIC'){ + this.Offers_Form.addControl('residence',new FormControl('',Validators.required)) + }else{ + this.Offers_Form.removeControl('residence'); + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.html new file mode 100644 index 0000000..44a4458 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.html @@ -0,0 +1,253 @@ +
    +
    +
    +

    Offers

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + Select + {{data.room_name + (data.room_view_name ? ', ' : '') + + data.room_view_name}} +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Offer Type

    +
    + +
    +
    +
    + Select + Early Bird + Stay Pay + Long Stay + Discount + Contract Remark +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Combinable Offer

    +
    + +
    +
    +
    + Select + Yes + No +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Offer Name + + + + Offer Type + + + + Room Name + + + + Combinable Offer + + + + Discount Code + + + + Offer days + + + + Offer Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.offer_name}} + {{data.offer_type}} + {{data.room_name}} + {{data.is_combinable_offer}} + {{data.discount_code}} + {{data.offer_days}} + {{data.extranet_offer_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.ts new file mode 100644 index 0000000..4e59cef --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-offers/offers-view/offers-view.component.ts @@ -0,0 +1,143 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; +@Component({ + selector: 'offers-view', + templateUrl: './offers-view.component.html', +}) +export class OffersViewComponent implements OnInit { + + AllRoomsData; + Result; + cols; + OfferSearchForm:FormGroup + constructor( + public activateRoute:ActivatedRoute, + public apiserv:API, + public _commonService:CommonFunctionService, + public router:Router, + private fb:FormBuilder + ) { } + Extranet_Hotel_Id; + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.GetAllRooms(); + this.OfferSearchForm = this.fb.group({ + extranet_hotel_id:this.Extranet_Hotel_Id, + extranet_room_id:'', + contract_name:'', + offer_name:'', + offer_type:'', + discount_code:'', + is_combinable_offer:'' + }); + this.cols = [ + { field: 'offer_name', header: 'Offer Name' }, + { field: 'offer_type', header: 'Offer Type' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'is_combinable_offer', header: 'Combinable Offer' }, + { field: 'discount_code', header: 'Discount Code' }, + { field: 'offer_days', header: 'Offer days' }, + { field: 'status', header: 'Status' }, + { field: 'extranet_offer_id', header: 'Offer Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + } + + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj).subscribe(res=>{ + if(res && res.data){ + this.AllRoomsData = res.data; + } + }) + } + Search(){ + let val = this.OfferSearchForm.getRawValue(); + let obj = { + extranet_hotel_id:val.extranet_hotel_id, + extranet_room_id:val.extranet_room_id, + contract_name:val.contract_name, + offer_name:val.offer_name, + offer_type:val.offer_type, + discount_code:val.discount_code, + is_combinable_offer:val.is_combinable_offer, + } + this.apiserv.Post('/ExtranetOffer/GetAllExtranetOffer',obj).subscribe(res=>{ + if (res) { + this.Result = res.data ? res.data : []; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['offer_type'] = this.getOfferType(e['offer_type']); + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetOffer/UpdateExtranetOfferStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + getOfferType(value){ + if(value == 'EARLYBIRD'){ + return 'Early Bird' + }else if(value == 'STAYPAY'){ + return 'Stay Pay' + }else if(value == 'LONGSTAY'){ + return 'Long Stay' + }else if(value == 'DISCOUNT'){ + return 'Discount' + }else if(value == 'CONTRACTREMARK'){ + return 'Contract Remark' + } + return '' + } + + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditOffer/${this.Extranet_Hotel_Id}/${Id}`); + } + Reset(){ + this.OfferSearchForm.get('extranet_room_id').setValue(''); + this.OfferSearchForm.get('contract_name').setValue(''); + this.OfferSearchForm.get('offer_name').setValue(''); + this.OfferSearchForm.get('offer_type').setValue(''); + this.OfferSearchForm.get('discount_code').setValue(''); + this.OfferSearchForm.get('is_combinable_offer').setValue(''); + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.html new file mode 100644 index 0000000..62b6332 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.html @@ -0,0 +1,976 @@ + + +
    +
    +
    +

    Add Room Form

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Default Language

    +
    + +
    +
    +
    + {{lang.LanguageName}} +
    + Please + select default language +
    +
    +
    +
    + + + Please + enter room name +
    +
    +
    +
    + + + +
    +
    +
    +

    Room View

    +
    + +
    +
    +
    + Select + {{data.room_view_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Adult Occupancy

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max adult occupancy +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Occupancy

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child occupancy +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Occupancy Type

    +
    + +
    +
    +
    + Max Total Occupancy + Max Occupancy Combinations +
    + Please + select max occupancy type +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Total Occupancy

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max total occupancy +
    +
    +
    +
    +
    +
    +
    + +
    +
    Option {{i + 1}}
    +
    +
    +
    + + + +
    +
    +
    +

    Max Adult

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max adult +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    + + + +
    +
    +
    +

    Max Child Age

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max child age +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Free + Child Allowed +
    + Please + select free child +
    +
    +
    + + + +
    +
    +
    +

    Max Free Child

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select max free child +
    +
    +
    +
    + + + +
    +
    +
    +

    Free Child Age From

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select free child age from +
    +
    +
    +
    + + + +
    +
    +
    +

    Free Child Age To

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select free child age to + Please + select age to greater than age from +
    +
    +
    +
    +
    +
    + Paid + Child +
    + Please + select paid child +
    + + +
    +
    + + + +
    +
    +
    +

    Paid Child Age From

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select paid child age from + Please + select age greater than previous age range +
    +
    +
    +
    + + + +
    +
    +
    +

    Paid Child Age To

    +
    + +
    +
    +
    + Select + {{item}} +
    + Please + select paid child age to + Please + select age to greater than age from +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + Child Extrabed Supported +
    +
    +
    +
    + + + Please + enter extrabed details +
    +
    +
    +
    + Child ExtraBed Detail +
    +
    + Child Age Range + ({{HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][0].get('from_age').value}} to + {{HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][0].get('to_age').value}}) +
    +
    +
    +
    + Child 1 +
    +
    +
    +
    + Child 2 +
    +
    +
    +
    + Child 3 +
    +
    +
    +
    + Child 4 +
    +
    +
    +
    + Child 5 +
    +
    +
    +
    + Child 6 +
    +
    +
    +
    + Child Age Range + ({{HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][1].get('from_age').value}} to + {{HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][1].get('to_age').value}}) +
    +
    +
    +
    + Child 1 +
    +
    +
    +
    + Child 2 +
    +
    +
    +
    + Child 3 +
    +
    +
    +
    + Child 4 +
    +
    +
    +
    + Child 5 +
    +
    +
    +
    + Child 6 +
    +
    +
    +
    +
    +
    + Adult Extrabed Supported +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + {{item}} Adult +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    Room Images

    +
    +
    +
    +
    +
    + Thumbnail Image + + +
    + Note: Upload jpeg/png with max file size upto + 500kb. Height + 200px and Width 800px. +
    +
    +
    +
    +
    +
    +
    +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    + Room Images + + +
    + Note: Upload jpeg/png with max file size upto + 500kb. Height + 200px and Width 800px. +
    +
    +
    +
    +
    +
    +
    +
    +
    date.PNG
    +
    490 B
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Room Amenities

    +
    +
    +
    +
    +
    +
    + {{!isCollapsed[i] ? + 'expand_less' : 'expand_more'}} + {{amenity.amenities}} +
    +
    +
    + {{sub_amanity}} +
    +
    +
    + +
    + +
    + +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.ts new file mode 100644 index 0000000..1ba0908 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room-add/hotel-room-add.component.ts @@ -0,0 +1,764 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-hotel-room-add', + templateUrl: './hotel-room-add.component.html', +}) +export class HotelRoomAddComponent implements OnInit { + + Extranet_Hotel_Id; + AllLang; + AllRoomView; + max_Child_Occ = 7; + max_Adult_Occ = 10; + max_Total_Occ = 16; + max_child_age = 12; + Clone_Rule; + showPaidchild = true; + Edit_Id; + ShowChildEditDet = true; + ShoeHideChildFields = false; + fileInfo = []; + fileArr = []; + public isCollapsed: boolean[]; + Sub_Ameneties_checked_Obj={}; + Amenities; + Age_Limit_Child = [0,1,2,3,4,5,6,7,8,9,10,11]; + occupancy_Limit_Child = [0,1,2,3,4,5,6,7,8,9,10,11]; + Max_occupancy_Limit_Child = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; + HotelRoomForm:FormGroup; + constructor(public activateRoute:ActivatedRoute,private router:Router,private hotelmanageserv:ManageHotelService, + public apiserv:API,public fb:FormBuilder,public validserv:ValidationService,public commonMasterSer:CommonFunctionService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Clone_Rule = this.activateRoute.snapshot['_routerState'].url.includes('CloneRoom') || !this.Edit_Id ? true :false; + this.initForm() + this.GetAllLAng(); + if(this.Edit_Id){ + this.GetById() + } + } + initForm(){ + this.HotelRoomForm = this.fb.group({ + extranet_room_id:'', + extranet_room_view_id:'', + default_lang_code:this.validserv.required, + room_name:this.validserv.required, + max_adult_occupancy:this.validserv.required, + max_child_occupancy:this.validserv.required, + max_occupancy_type:this.validserv.required, + is_extra_bed_supported:false, + is_free_child:false, + is_paid_child:false, + is_adult_extra_bed_supported:false, + room_size:'', + bed_details:'', + room_description:'', + extranet_room_details_id:'', + room_images:this.fb.control([]), + room_images_url:this.fb.control([]), + max_occupancy_options:this.fb.array([]), + room_thumbnail_url:[''], + room_thumbnail_url_display:[''], + age_range1_child1:false, + age_range1_child2:false, + age_range1_child3:false, + age_range1_child4:false, + age_range1_child5:false, + age_range1_child6:false, + age_range2_child1:false, + age_range2_child2:false, + age_range2_child3:false, + age_range2_child4:false, + age_range2_child5:false, + age_range2_child6:false, + }) + } + getAllData(Edit_Data?) { + this.Sub_Ameneties_checked_Obj = {}; + this.Amenities = undefined; + forkJoin( + this.GetAllRoomView(), + this.GetAllAmenities(), + ).subscribe(result => { + if (result && result.length > 0) { + this.AllRoomView = result[0] ? result[0].data : result[0]; + let amenity_json = result[1] ? result[1].data :''; + this.Amenities = amenity_json && amenity_json['extranet_hotel_room_amenity_json'] ? JSON.parse(amenity_json.extranet_hotel_room_amenity_json) : []; + this.Amenities.forEach(data=>{ + this.Sub_Ameneties_checked_Obj[data.parent_amenity_id] = []; + }); + if(this.Amenities && this.Amenities.length > 0){ + this.isCollapsed = new Array(this.Amenities.length).fill(true); + } + if(Edit_Data && Edit_Data.length > 0){ + Edit_Data.forEach(data=>{ + this.Sub_Ameneties_checked_Obj[data.parent_amenity_id] = data.sub_amenities && data.sub_amenities.length > 0 ? data.sub_amenities : []; + }) + } + } + }) + } + GetAllLAng(){ + this.apiserv.AdminGet('/LanguageMapping/GetLanguagesByOrgId').subscribe(data=>{ + if(data){ + this.AllLang = data; + } + }) + } + GetById(){ + this.apiserv.Get('/ExtranetHotelRoom/GetExtranetHotelRoomById/'+ this.Edit_Id).subscribe(res=>{ + if(res){ + this.SetRoomdata(res.data); + } + }) + } + GetAllRoomView(){ + return this.apiserv.Get('/ExtranetHotelRoom/GetAllExtranetHotelRoomView?lang_code='+this.HotelRoomForm.get('default_lang_code').value) + } + GetAllAmenities(){ + return this.apiserv.Get('/ExtranetHotelRoom/GetAllExtranetHotelRoomAmenities/'+this.HotelRoomForm.get('default_lang_code').value) + } + + BackButton(){ + this.hotelmanageserv.Active_tab = 'Room'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + CheckOccpancyType(val){ + if(val == 'MAXTOTALOCCUPANCY'){ + this.HotelRoomForm.addControl('max_total_occupancy',new FormControl('',Validators.required)); + let formarray = this.HotelRoomForm.controls['max_occupancy_options'] as FormArray; + formarray.clear(); + }else if(val == 'MAXOCCUPANCYCOMBINATIONS'){ + this.AddMaxOccupancyCombination(); + this.HotelRoomForm.removeControl('max_total_occupancy'); + } + } + GetAdultOcuupancy(val){ + if(val){ + this.max_Adult_Occ = val+1; + this.max_Total_Occ = val + this.max_Child_Occ; + let max_occ_val = this.HotelRoomForm.controls['max_total_occupancy'] ? this.HotelRoomForm.controls['max_total_occupancy'].value : 0; + if(max_occ_val > this.max_Total_Occ){ + this.HotelRoomForm.get('max_total_occupancy').setValue(''); + } + let formarray = this.HotelRoomForm.controls['max_occupancy_options'] as FormArray; + formarray.controls.forEach(control=>{ + if(control.get('max_adult').value > val){ + control.get('max_adult').setValue(''); + } + }) + }else { + this.max_Adult_Occ = 10; + } + this.AdultBedSupport(); + } + SetRoomdata(Resp){ + if(!this.Clone_Rule){ + this.HotelRoomForm.get('extranet_room_id').setValue(Resp.extranet_room_id); + this.HotelRoomForm.get('extranet_room_view_id').setValue(Resp.extranet_room_view_id); + this.HotelRoomForm.get('max_adult_occupancy').disable(); + this.HotelRoomForm.get('max_occupancy_type').disable(); + this.HotelRoomForm.get('max_child_occupancy').disable(); + } + this.HotelRoomForm.get('default_lang_code').setValue(Resp.default_lang_code); + this.HotelRoomForm.get('max_adult_occupancy').setValue(Resp.max_adult_occupancy); + this.HotelRoomForm.get('max_occupancy_type').setValue(Resp.max_occupancy_type); + this.HotelRoomForm.get('max_child_occupancy').setValue(Resp.max_child_occupancy); + this.HotelRoomForm.get('room_size').setValue(Resp.room_size); + this.HotelRoomForm.get('bed_details').setValue(Resp.bed_details); + this.HotelRoomForm.get('room_description').setValue(Resp.room_description); + this.HotelRoomForm.get('is_free_child').setValue(Resp.is_free_child); + this.HotelRoomForm.get('is_extra_bed_supported').setValue(Resp.is_extra_bed_supported); + this.HotelRoomForm.get('is_paid_child').setValue(Resp.is_paid_child); + this.HotelRoomForm.get('is_adult_extra_bed_supported').setValue(Resp.is_adult_extra_bed_supported); + this.CheckOccpancyType(Resp.max_occupancy_type) + if(Resp.max_occupancy_type == 'MAXTOTALOCCUPANCY'){ + this.HotelRoomForm.get('max_total_occupancy').setValue(Resp.max_total_occupancy); + if(!this.Clone_Rule)this.HotelRoomForm.get('max_total_occupancy').disable(); + }else if(Resp.max_occupancy_type == 'MAXOCCUPANCYCOMBINATIONS'){ + let val = Resp.max_occupancy_options ? JSON.parse(Resp.max_occupancy_options) : []; + val.forEach((data,i)=>{ + if(i > 0) this.AddMaxOccupancyCombination(); + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].get('max_adult').setValue(data.max_adult); + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].get('max_child')?.setValue(data.max_child); + data.child_age.forEach((child_age,child_ind)=>{ + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].addControl('child_age_'+(child_ind+1),new FormControl(child_age,Validators.required)) + }) + if(!this.Clone_Rule){ + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].get('max_adult').disable(); + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].get('max_child')?.disable(); + for(let ind=1 ; ind<=6 ; ind++){ + this.HotelRoomForm.controls['max_occupancy_options']['controls'][i].get('child_age_'+ ind)?.disable(); + } + } + }) + } + + if(Resp.max_child_occupancy){ + this.ShowHideChildAgeFields(Resp.max_child_occupancy) + this.ShowChildEditDet = this.Clone_Rule ? true : false; + // this.ShoeHideChildFields = this.Clone_Rule ? true : false; + this.HotelRoomForm.get('max_child_age').setValue(Resp.max_child_age); + if(!this.Clone_Rule){ + this.HotelRoomForm.get('max_child_age').disable(); + } + } + if(Resp.is_extra_bed_supported){ + this.ExtraBedControls(true); + this.HotelRoomForm.get('extra_bed_details').setValue(Resp.extra_bed_details); + } + if(Resp.is_free_child){ + this.FreeChildControls(true); + this.HotelRoomForm.get('max_free_child').setValue(Resp.max_free_child); + this.HotelRoomForm.get('free_child_age_from').setValue(Resp.free_child_age_from); + this.HotelRoomForm.get('free_child_age_to').setValue(Resp.free_child_age_to); + } + if(Resp.ExtranetChildAgeRange && Resp.ExtranetChildAgeRange.length > 0){ + Resp.ExtranetChildAgeRange.forEach((Paid_child_Obj,ind)=>{ + ind == 0 ? this.PaidChildArr(true) : this.AddChildArr(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][ind].get('from_age').setValue(Paid_child_Obj.from_age); + this.ChangeFeeMinValue('to_age',Paid_child_Obj.from_age,ind); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][ind].get('to_age').setValue(Paid_child_Obj.to_age); + if(!this.Clone_Rule)this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][ind].get('extranet_child_age_range_id').setValue(Paid_child_Obj.extranet_child_age_range_id); + }) + } + if(Resp.ExtranetHotelRoomDetails){ + if(!this.Clone_Rule)this.HotelRoomForm.get('room_name').setValue(Resp.ExtranetHotelRoomDetails.room_name); + this.HotelRoomForm.get('room_description').setValue(Resp.ExtranetHotelRoomDetails.room_description); + if(!this.Clone_Rule)this.HotelRoomForm.get('extranet_room_details_id').setValue(Resp.ExtranetHotelRoomDetails.extranet_room_details_id); + } + if(Resp.room_amenities){ + let amenity_data = JSON.parse(Resp.room_amenities); + this.getAllData(amenity_data) + } + if(Resp.paid_child_extrabed_details){ + let extrabed_details = JSON.parse(Resp.paid_child_extrabed_details); + extrabed_details.forEach((range_data,range_ind)=>{ + range_data.Child_Extra_bed_detail.forEach((is_extraned,child_ind)=>{ + this.HotelRoomForm.get(`age_range${range_ind+1}_child${child_ind+1}`).setValue(is_extraned); + }) + }) + } + if(Resp.room_images){ + let Images_Arr = Resp.room_images.split(','); + Images_Arr.forEach(data=>{ + this.HotelRoomForm.get('room_images').value.push(data); + this.HotelRoomForm.get('room_images_url').value.push(data); + }) + } + if(Resp.room_thumbnail_url){ + this.HotelRoomForm.get('room_thumbnail_url').setValue(Resp.room_thumbnail_url); + this.HotelRoomForm.get('room_thumbnail_url_display').setValue(Resp.room_thumbnail_url); + } + if(Resp.is_adult_extra_bed_supported){ + let adult_bed_obj = Resp.adult_extrabed_details_json ? JSON.parse(Resp.adult_extrabed_details_json) : ''; + this.AdultBedSupport(adult_bed_obj); + this.HotelRoomForm.get('adult_extrabed_details').setValue(Resp.adult_extrabed_details); + } + } + ExtraBedControls(event){ + if(event){ + this.HotelRoomForm.addControl('extra_bed_details',new FormControl('',Validators.required)); + }else { + this.HotelRoomForm.removeControl('extra_bed_details'); + } + } + FreeChildControls(event){ + if(event){ + this.HotelRoomForm.addControl('max_free_child',new FormControl('',Validators.required)); + this.HotelRoomForm.addControl('free_child_age_from',new FormControl('',Validators.required)); + this.HotelRoomForm.addControl('free_child_age_to',new FormControl('',Validators.required)); + }else { + this.HotelRoomForm.removeControl('max_free_child'); + this.HotelRoomForm.removeControl('free_child_age_from'); + this.HotelRoomForm.removeControl('free_child_age_to'); + this.addRemoveValidation('is_paid_child',true); + this.ChangeFeeMinValue('from_age','',0) + } + } + PaidChildArr(event){ + if(event){ + this.addRemoveValidation('is_free_child',false); + this.HotelRoomForm.addControl('ExtranetChildAgeRange',new FormArray([this.fb.group({ + from_age:['', Validators.compose([Validators.required,this.AmountRangeValidation(this.HotelRoomForm.get('free_child_age_to') ? this.HotelRoomForm.get('free_child_age_to').value : '')])], + to_age:this.validserv.required, + extranet_child_age_range_id:'' + })])); + }else { + this.addRemoveValidation('is_free_child',true); + if(this.HotelRoomForm.get('is_free_child').value == false){ + this.addRemoveValidation('is_paid_child',true); + } + this.HotelRoomForm.removeControl('ExtranetChildAgeRange'); + } + this.CheckMaxChildCriteria(); + } + CheckMaxChildCriteria(){ + let max_child_occupancy = this.HotelRoomForm.get('max_child_occupancy').value; + let max_free_child_occ = this.HotelRoomForm.get('max_free_child') ? this.HotelRoomForm.get('max_free_child').value : 0; + if(max_child_occupancy == max_free_child_occ && max_child_occupancy !== 0){ + this.addRemoveValidation('is_paid_child',false); + let min_amt = this.HotelRoomForm.get('free_child_age_to').value ? this.HotelRoomForm.get('free_child_age_to').value : ''; + this.AddValidationPaidAgeFields(0,min_amt,'from_age') + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('from_age').enable(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('to_age').enable(); + }else if(max_free_child_occ && this.HotelRoomForm.get('is_free_child').value && max_child_occupancy !== 0){ + this.addRemoveValidation('is_paid_child',true); + this.addRemoveValidation('is_free_child',false); + if(max_free_child_occ){ + this.AddValidationPaidAgeFields(0,'','from_age'); + this.AddValidationPaidAgeFields(0,'','to_age'); + let from_age = this.HotelRoomForm.get('free_child_age_from').value; + let to_age = this.HotelRoomForm.get('free_child_age_to').value; + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('from_age').setValue( from_age || from_age === 0 ? this.HotelRoomForm.get('free_child_age_from').value : ''); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('from_age').disable(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('to_age').setValue(to_age || to_age === 0 ? this.HotelRoomForm.get('free_child_age_to').value : ''); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][0].get('to_age').disable(); + let min_amt = this.HotelRoomForm.get('free_child_age_to').value ? this.HotelRoomForm.get('free_child_age_to').value : ''; + this.AddValidationPaidAgeFields(1,min_amt,'from_age'); + } + }else { + this.addRemoveValidation('is_paid_child',false); + this.addRemoveValidation('is_free_child',false); + } + } + AddValidationPaidAgeFields(i,min_amt,control){ + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][i]?.get(control).clearValidators(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][i]?.get(control).addValidators([Validators.required, this.AmountRangeValidation(min_amt ? min_amt : '')]); + this.HotelRoomForm.controls['ExtranetChildAgeRange']?.['controls'][i]?.get(control).updateValueAndValidity(); + } + AddChildArr(){ + let formArray = this.HotelRoomForm.controls['ExtranetChildAgeRange'] as FormArray; + formArray.push( + this.fb.group({ + from_age:['', Validators.compose([Validators.required,this.AmountRangeValidation(formArray.controls[0].get('to_age') ? formArray.controls[0].get('to_age').value : '')])], + to_age:this.validserv.required, + extranet_child_age_range_id:'', + }) + ) + } + RemoveChildArr(i){ + let formArray = this.HotelRoomForm.controls['ExtranetChildAgeRange'] as FormArray; + formArray.removeAt(i); + this.ChangeFeeMinValue('from_age',(this.HotelRoomForm.get('free_child_age_to') ? this.HotelRoomForm.get('free_child_age_to').value : ''),0) + } + AddMaxOccupancyCombination(){ + let formArray = this.HotelRoomForm.controls['max_occupancy_options'] as FormArray; + let group_obj = { + max_adult:this.validserv.required + } + if(this.HotelRoomForm.get('max_child_occupancy').value > 0){ + group_obj['max_child'] = this.validserv.required; + } + formArray.push( + this.fb.group(group_obj) + ) + } + RemoveMaxOccupancyCombination(i){ + let formArray = this.HotelRoomForm.controls['max_occupancy_options'] as FormArray; + formArray.removeAt(i); + } + SelectParent(event,parent_Id){ + if(event.checked){ + let filter_selectced_parent = this.Amenities.find(e=> e.parent_amenity_id == parent_Id); + this.Sub_Ameneties_checked_Obj[parent_Id] = filter_selectced_parent.sub_amenities; + }else { + this.Sub_Ameneties_checked_Obj[parent_Id] = []; + } + } + Select_Sub_Amenity(event,parent_Id,sub_amenity){ + if(event.checked){ + this.Sub_Ameneties_checked_Obj[parent_Id].push(sub_amenity); + }else { + this.Sub_Ameneties_checked_Obj[parent_Id] = this.Sub_Ameneties_checked_Obj[parent_Id].filter(e=>e !== sub_amenity) + } + } + + SelectImage(e, filedata,contol) { + if (e.currentFiles.length != 0) { + for (let i = 0; i < e.files.length; i++) { + let file = e.files[i]; + if (file.size < 1048576 && (file.type == 'image/png' || file.type == 'image/jpeg')) { + const reader = new FileReader(); + console.log(file) + reader.readAsText(file); // Read as binary data + reader.onload = (res) => { + const binaryString = res.target.result as string; + const hasScriptTag = this.commonMasterSer.hasScriptTagInBinary(binaryString); + if (hasScriptTag) { + filedata.clear(); + this.commonMasterSer.showMessage(false, 'Invalid file (contains script tag)'); + } else { + //base 64 + if(contol == 'room_thumbnail_url'){ + this.HotelRoomForm.get(contol).setValue(file); + }else { + this.HotelRoomForm.get(contol).value.push(file); + } + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + if(contol == 'room_thumbnail_url'){ + this.HotelRoomForm.get('room_thumbnail_url_display').setValue(reader.result.toString()); + }else { + this.HotelRoomForm.get('room_images_url').value.push(reader.result.toString()); + } + } + }; + } + } + } + } + + } + RemoveImage(ind,contol) { + if(contol == 'room_thumbnail_url'){ + this.HotelRoomForm.get(contol).setValue(''); + this.HotelRoomForm.get('room_thumbnail_url_display').setValue(''); + }else { + let image_url_list = this.HotelRoomForm.get(contol).value; + image_url_list.splice(ind, 1); + let image_display_url_list = this.HotelRoomForm.get('room_images_url').value; + image_display_url_list.splice(ind, 1); + } + } + + saveImg(fileInfo, fileArr,edit_id) { + if (fileInfo && fileInfo.length > 0 && fileArr && fileArr.length > 0) { + var formdata = new FormData(); + fileArr.forEach((x) => { + formdata.append("files", x); + }); + let file_info_list = JSON.stringify(fileInfo).replaceAll('ExtranetRoomId', edit_id); + formdata.append("fileInfo", file_info_list); + return this.apiserv.PostFile("/FileUpload/SaveFile", formdata); + } else { + return of({ + resp: true, + respMsg: "No images to save" + }); + } + } + ChangeFeeMinValue(controlname,min,i?) { + let min_amt = min; + if ((i == 0 || i) && (this.HotelRoomForm.controls['ExtranetChildAgeRange'] && this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i])) { + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).clearValidators(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).markAsUntouched(); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).setErrors(null); + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'][i].get(controlname).updateValueAndValidity(); + }else if(i == null || i == undefined){ + this.HotelRoomForm.controls[controlname].clearValidators(); + this.HotelRoomForm.controls[controlname].addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.HotelRoomForm.controls[controlname].markAsUntouched(); + this.HotelRoomForm.controls[controlname].setErrors(null); + this.HotelRoomForm.controls[controlname].updateValueAndValidity(); + } + this.CheckMaxChildCriteria() + }; + private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value === 0) { + if ((initialValue || initialValue === 0)&& parseInt(control.value) <= parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; + } + Save(){ + if (this.HotelRoomForm.status == "VALID") { + let val = this.HotelRoomForm.getRawValue(); + let Amenities_Obj = []; + if(this.Amenities && this.Amenities.length > 0){ + this.Amenities.forEach(data=>{ + if(this.Sub_Ameneties_checked_Obj[data.parent_amenity_id] && this.Sub_Ameneties_checked_Obj[data.parent_amenity_id].length > 0){ + data['sub_amenities'] = this.Sub_Ameneties_checked_Obj[data.parent_amenity_id]; + Amenities_Obj.push(data); + } + }) + } + let PostData = { + extranet_room_id:val.extranet_room_id ? val.extranet_room_id : '', + extranet_hotel_id: this.Extranet_Hotel_Id, + extranet_room_view_id:val.extranet_room_view_id ? val.extranet_room_view_id : '', + default_lang_code : val.default_lang_code, + max_adult_occupancy : val.max_adult_occupancy, + max_child_occupancy : val.max_child_occupancy, + max_child_age : val.max_child_age, + max_total_occupancy : val.max_total_occupancy ? val.max_total_occupancy : 0, + max_occupancy_type : val.max_occupancy_type ? val.max_occupancy_type : '', + max_occupancy_options : '', + adult_extrabed_details_json : '', + adult_extrabed_details:val.adult_extrabed_details ? val.adult_extrabed_details : '', + is_extra_bed_supported : val.is_extra_bed_supported, + extra_bed_details : val.is_extra_bed_supported ? val.extra_bed_details : '', + is_adult_extra_bed_supported : val.is_adult_extra_bed_supported, + is_free_child : val.is_free_child, + max_free_child : val.max_free_child ? val.max_free_child : 0, + free_child_age_from : val.free_child_age_from ? val.free_child_age_from : 0, + free_child_age_to : val.free_child_age_to ? val.free_child_age_to : 0, + is_paid_child : val.is_paid_child, + room_size : val.room_size ? val.room_size : '', + bed_details : val.bed_details ? val.bed_details : '', + paid_child_extrabed_details:'', + room_amenities:JSON.stringify(Amenities_Obj), + ExtranetHotelRoomDetails:{ + extranet_hotel_id:this.Extranet_Hotel_Id, + extranet_room_details_id:val.extranet_room_details_id ? val.extranet_room_details_id : '', + lang_code:val.default_lang_code ? val.default_lang_code : '', + room_name : val.room_name, + room_description : val.room_description ? val.room_description :'', + }, + ExtranetChildAgeRange:[] + } + let paid_child_extrabed_obj = []; + if(val.ExtranetChildAgeRange && val.ExtranetChildAgeRange.length > 0){ + val.ExtranetChildAgeRange.forEach((child_age_arr,i)=>{ + PostData.ExtranetChildAgeRange.push({ + from_age:child_age_arr.from_age, + to_age:child_age_arr.to_age, + extranet_child_age_range_id:child_age_arr.extranet_child_age_range_id, + range_sequence:i, + }); + if(val.is_extra_bed_supported){ + let age_range_obj = {paid_child_extrabed_obj:`${child_age_arr.from_age} to ${child_age_arr.to_age}`,Child_Extra_bed_detail:[]} + for(let ind=1;ind<=val.max_child_occupancy;ind++){ + age_range_obj.Child_Extra_bed_detail.push(val[`age_range${i+1}_child${ind}`]) + } + paid_child_extrabed_obj.push(age_range_obj); + } + }) + } + PostData['paid_child_extrabed_details'] = JSON.stringify(paid_child_extrabed_obj); + if(val.is_adult_extra_bed_supported){ + let adult_bed_obj = {} + for(let i=1;i<=9;i++){ + adult_bed_obj['adult_'+i] = val['adult_'+i] ? val['adult_'+i] : false; + } + PostData.adult_extrabed_details_json = JSON.stringify(adult_bed_obj); + } + let room_images_arr = [] + val.room_images.forEach((img_data,img_Ind)=>{ + if (typeof(img_data) == 'object' && img_data) { + let image_type = img_data.name.split('.'); + this.fileArr.push(img_data); + this.fileInfo.push({ 'fileName': "Extranet/Hotel/Rooms/ExtranetRoomId/Room_Images_"+ img_Ind + '.' + image_type[image_type.length - 1], 'pathToSave': 'OrganizationData/ORGID' }); + let image_url = `${environment.cdnFileUrl}OrganizationData/ORGID/Extranet/Hotel/Rooms/ExtranetRoomId/Room_Images_${img_Ind}.${image_type[image_type.length - 1]}?t=${moment(new Date()).format("yyMMddHHmmssfffffff")}`; + room_images_arr.push(image_url) + }else { + room_images_arr.push(img_data); + } + }) + let thumbnail_image_url = ''; + if (typeof(val.room_thumbnail_url) == 'object' && val.room_thumbnail_url) { + let image_type = val.room_thumbnail_url.name.split('.'); + this.fileArr.push(val.room_thumbnail_url); + this.fileInfo.push({ 'fileName': "Extranet/Hotel/Rooms/ExtranetRoomId/Thumbnail_Img" + '.' + image_type[image_type.length - 1], 'pathToSave': 'OrganizationData/ORGID' }); + thumbnail_image_url = `${environment.cdnFileUrl}OrganizationData/ORGID/Extranet/Hotel/Rooms/ExtranetRoomId/Thumbnail_Img.${image_type[image_type.length - 1]}?t=${moment(new Date()).format("yyMMddHHmmssfffffff")}`; + }else { + thumbnail_image_url = val.room_thumbnail_url; + } + PostData['room_images'] = room_images_arr.length > 0 ? room_images_arr.join(',') : ''; + PostData['room_thumbnail_url'] = thumbnail_image_url; + if(val.max_occupancy_options) { + let max_occupancy_arr = []; + val.max_occupancy_options.forEach(occupancy_arr=>{ + let child_age_arr = []; + for(let i=1 ; i <= 6 ; i++){ + if(occupancy_arr[`child_age_${i}`]){ + child_age_arr.push(occupancy_arr[`child_age_${i}`]) + } + } + max_occupancy_arr.push({ + max_adult:occupancy_arr.max_adult, + max_child:occupancy_arr.max_child, + child_age:child_age_arr, + }) + }); + PostData['max_occupancy_options'] = JSON.stringify(max_occupancy_arr) + } + this.apiserv.Post('/ExtranetHotelRoom/SaveExtranetHotelRoom',PostData).subscribe(resp=>{ + if(resp){ + if(this.fileInfo.length > 0 && resp.status){ + this.saveImg(this.fileInfo, this.fileArr,resp.data.extranet_room_id).subscribe(res=>{ + if(res && res.resp){ + this.BackButton(); + } + this.commonMasterSer.showMessage(resp.status,resp.message) + }) + }else if(resp.status){ + this.BackButton(); + } + this.commonMasterSer.showMessage(resp.status,resp.message); + + } + }) + }else{ + this.validserv.showValidationsMsg(this.HotelRoomForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } + } + ShowHideChildAgeFields(event){ + if(event){ + this.HotelRoomForm.addControl('max_child_age',new FormControl('',Validators.required)); + this.ShoeHideChildFields = true; + if(this.HotelRoomForm.controls['max_free_child']?.value > event){ + this.HotelRoomForm.get('max_free_child').setValue(''); + }; + this.CheckMaxChildCriteria(); + if(!this.HotelRoomForm.get('is_paid_child').value){ + this.addRemoveValidation('is_free_child',true); + } + this.addRemoveValidation('is_paid_child',true); + }else { + this.ShoeHideChildFields = false; + this.HotelRoomForm.removeControl('max_child_age'); + this.HotelRoomForm.get('is_extra_bed_supported').setValue(false); + this.HotelRoomForm.get('is_free_child').setValue(false); + this.HotelRoomForm.get('is_paid_child').setValue(false); + this.addRemoveValidation('is_free_child',false); + this.addRemoveValidation('is_paid_child',false); + this.PaidChildArr(false); + this.FreeChildControls(false); + this.ExtraBedControls(false); + } + this.max_Child_Occ = event+1; + this.max_Total_Occ = event + this.max_Adult_Occ; + let max_occ_val = this.HotelRoomForm.controls['max_total_occupancy'] ? this.HotelRoomForm.controls['max_total_occupancy'].value : 0; + if(max_occ_val > this.max_Total_Occ){ + this.HotelRoomForm.get('max_total_occupancy').setValue(''); + } + this.Paid_Child_Show_Hide(); + this.maxOccupancyCombination(event); + } + GetMaxChildAge(event){ + if(event || event===0){ + this.max_child_age = event + 1; + this.SetFieldsValueEmpty(this.HotelRoomForm,'free_child_age_from',event); + this.SetFieldsValueEmpty(this.HotelRoomForm,'free_child_age_to',event); + if(this.HotelRoomForm.controls['ExtranetChildAgeRange']){ + this.HotelRoomForm.controls['ExtranetChildAgeRange']['controls'].forEach(formgroup=>{ + this.SetFieldsValueEmpty(formgroup,'from_age',event); + this.SetFieldsValueEmpty(formgroup,'to_age',event); + }) + } + }else { + this.max_child_age = 12; + } + this.Paid_Child_Show_Hide(); + this.maxAgeCombination(event); + } + SetFieldsValueEmpty(group,control,val?){ + if(group.controls[control]?.value > val){ + group.get(control).setValue(''); + } + } + // common function + addRemoveValidation(name, check) { + if (check) { + this.HotelRoomForm.get(name).addValidators([Validators.requiredTrue]); + } else { + this.HotelRoomForm.get(name).clearValidators(); + } + this.HotelRoomForm.get(name).updateValueAndValidity(); + }; + Paid_Child_Show_Hide(){ + let child_occ = this.HotelRoomForm.controls['max_child_occupancy'].value ? this.HotelRoomForm.controls['max_child_occupancy'].value : undefined; + let free_child_occ = this.HotelRoomForm.controls['free_child_age_from']?.value ? this.HotelRoomForm.controls['max_child_occupancy'].value : ''; + if((free_child_occ == child_occ) && this.HotelRoomForm.controls['free_child_age_to'].value == this.max_child_age -1){ + this.showPaidchild = false; + this.addRemoveValidation('is_paid_child',false); + this.PaidChildArr(false); + }else { + this.showPaidchild = true; + this.CheckMaxChildCriteria(); + } + } + + maxChildAge(child_occ,ind){ + for(let i=1;i<=6;i++){ + let group = this.HotelRoomForm.controls['max_occupancy_options']['controls'][ind] as FormGroup; + if(!group?.get('child_age_'+i) && i <= child_occ){ + this.HotelRoomForm.controls['max_occupancy_options']['controls'][ind].addControl('child_age_'+i,new FormControl('',Validators.required)) + }else if(group?.get('child_age_'+i) && i > child_occ){ + this.HotelRoomForm.controls['max_occupancy_options']['controls'][ind].removeControl('child_age_'+i); + } + } + } + + maxOccupancyCombination(child_Occ){ + if(child_Occ > 0){ + this.HotelRoomForm.controls['max_occupancy_options']?.['controls'].forEach(occ_Combination_grp=>{ + let child_occ_Cobination_val = occ_Combination_grp.get('max_child')?.value; + if(child_occ_Cobination_val > child_Occ){ + occ_Combination_grp.get('max_child').setValue(''); + }else if(!occ_Combination_grp.get('max_child')){ + occ_Combination_grp.addControl('max_child', new FormControl('',Validators.required)) + } + }) + }else { + this.HotelRoomForm.controls['max_occupancy_options']?.['controls'].forEach((occ_Combination_grp,ind)=>{ + occ_Combination_grp.removeControl('max_child'); + this.maxChildAge(0,ind); + }) + } + } + maxAgeCombination(child_Occ){ + if(child_Occ > 0){ + this.HotelRoomForm.controls['max_occupancy_options']?.['controls'].forEach(occ_Combination_grp=>{ + for(let i=1 ; i<=6 ; i++){ + let child_occ_Cobination_val = occ_Combination_grp.get('child_age_'+i)?.value; + if(child_occ_Cobination_val > child_Occ){ + occ_Combination_grp.get('child_age_'+i)?.setValue(''); + } + } + }) + }else if(child_Occ == 0){ + this.HotelRoomForm.controls['max_occupancy_options']?.['controls'].forEach((occ_Combination_grp,ind)=>{ + for(let i=1 ; i<=6 ; i++){ + occ_Combination_grp.get('child_age_'+i)?.setValue(0); + } + }) + } + } + + AdultBedSupport(value_Obj?){ + let value = this.HotelRoomForm.get('is_adult_extra_bed_supported').value; + let adult_occ = this.HotelRoomForm.get('max_adult_occupancy').value; + if(value && adult_occ){ + this.HotelRoomForm.addControl('adult_extrabed_details',new FormControl('',this.validserv.required)); + for(let i = 1; i <= adult_occ; i++){ + if(!this.HotelRoomForm.get('adult_'+i)){ + this.HotelRoomForm.addControl('adult_' + i,new FormControl(value_Obj ? value_Obj['adult_'+ i] : false)); + } + } + for(let i = 9; i > adult_occ; i--){ + if(this.HotelRoomForm.get('adult_'+i)){ + this.HotelRoomForm.removeControl('adult_'+i); + } + } + }else { + this.HotelRoomForm.removeControl('adult_extrabed_details'); + for(let i = 9; i > 0; i--){ + if(this.HotelRoomForm.get('adult_'+i)){ + this.HotelRoomForm.removeControl('adult_'+i); + } + } + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.html new file mode 100644 index 0000000..d7a97b7 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.html @@ -0,0 +1,257 @@ +
    +
    +
    +

    Room

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Room View

    +
    + +
    +
    +
    + Select + {{data.room_view_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Extrabed Supported

    +
    + +
    +
    +
    + Select + Yes + No +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Free Child Allowed

    +
    + +
    +
    +
    + Select + Yes + No +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Room Name + + + + Room View + + + + Max Occupancy Type + + + + Max Adult Occupancy + + + + Max Child Occupancy + + + + Max Child Age + + + + Max Total Occupancy + + + + Extrabed Supported + + + + Free Child Allowed + + + + Room Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.room_name}} + {{data.room_view}} + {{data.max_occupancy_type}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.ts new file mode 100644 index 0000000..c1d3864 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.component.ts @@ -0,0 +1,120 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'hotel-room', + templateUrl: './hotel-room.component.html', +}) +export class HotelRoomComponent implements OnInit { + displayPosition; + Extranet_Hotel_Id; + Result; + cols; + Room_Name; + AllRoomView; + Clone_Room_data; + Clone_Room_view; + Room_View; + Extra_bed; + Free_Child; + constructor(public activateRoute:ActivatedRoute,private router:Router, public apiserv:API,public _commonService:CommonFunctionService, + public validserv:ValidationService, public fb:FormBuilder) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.cols = [ + { field: 'room_name', header: 'Room Name' }, + { field: 'room_view', header: 'Room View' }, + { field: 'max_occupancy_type', header: 'max Occupancy Type' }, + { field: "max_adult_occupancy", header: 'Max Adult Occupancy' }, + { field: 'max_child_occupancy', header: 'Max Child Occupancy' }, + { field: 'max_child_age', header: 'Max Child Age' }, + { field: 'max_total_occupancy', header: 'Max Total Occupancy' }, + { field: 'is_extra_bed_supported', header: 'Extrabed Supported' }, + { field: 'is_free_child', header: 'Free Child Allowed' }, + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.GetAllRoomView() + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditRoom/${this.Extranet_Hotel_Id}/${Id}`); + } + + Search(){ + let ReObj = { + is_free_child:this.Free_Child ? this.Free_Child : '' , + is_extra_bed_supported:this.Extra_bed ? this.Extra_bed : '', + extranet_room_view_id:this.Room_View ? this.Room_View : '', + room_name:this.Room_Name ? this.Room_Name : '', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetHotelRoom/GetAllExtranetHotelRoom',ReObj).subscribe(res=>{ + if (res) { + this.Result = res.data ? res.data : []; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['is_extra_bed_supported'] = e.is_extra_bed_supported ? 'Yes' : 'No'; + e['is_free_child'] = e.is_free_child ? 'Yes' : 'No'; + if(e.max_occupancy_type){ + e['max_occupancy_type'] = e.max_occupancy_type == 'MAXOCCUPANCYCOMBINATIONS' ? 'Max Occupancy Combinations' : 'Max Total Occupancy'; + } + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + Clone(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/CloneRoom/${this.Extranet_Hotel_Id}/${Id}`); + } + updateStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetHotelRoom/UpdateExtranetHotelRoomStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + GetAllRoomView(){ + this.apiserv.Get('/ExtranetHotelRoom/GetAllExtranetHotelRoomView').subscribe(res=>{ + if(res && res.data){ + this.AllRoomView = res.data ? res.data : undefined; + } + }) + } + Reset(){ + this.Room_Name = undefined; + this.Room_View = undefined; + this.Extra_bed = undefined; + this.Free_Child = undefined; + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.module.ts new file mode 100644 index 0000000..47aa046 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-room/hotel-room.module.ts @@ -0,0 +1,67 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { HotelManageComponent } from '../hotel-manage.component'; +import { HotelRoomAddComponent } from './hotel-room-add/hotel-room-add.component'; +import { HotelRoomComponent } from './hotel-room.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { FileUploadModule } from 'primeng/fileupload'; + + + +const routes: Routes = [ + + { + path: 'HotelAddRoom/:Hotel_Eaxtranet_Id', + component:HotelRoomAddComponent, + }, + { + path: 'HotelEditRoom/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelRoomAddComponent, + }, + { + path: 'CloneRoom/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelRoomAddComponent, + }, +] + + +@NgModule({ + declarations: [ + HotelRoomComponent, + HotelRoomAddComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelRoomComponent + ] +}) +export class HotelRoomModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.html new file mode 100644 index 0000000..5751a0a --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.html @@ -0,0 +1,72 @@ + +
    +
    +
    +

    Add Season Form

    +
    +
    +
    +
    +
    +
    + + + Please + enter season name +
    +
    +
    +
    + +
    +
    +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.ts new file mode 100644 index 0000000..ace16ac --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season-add/hotel-season-add.component.ts @@ -0,0 +1,173 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { MessageService } from 'primeng/api'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-hotel-season-add', + templateUrl: './hotel-season-add.component.html', +}) +export class HotelSeasonAddComponent implements OnInit { + + constructor(public activateRoute:ActivatedRoute,public fb:FormBuilder,public validserv:ValidationService,public apiserv:API,public MsgService:MessageService,private router: Router , + private hotelmanageserv:ManageHotelService) { } + Hotel_Season_Form:FormGroup; + MinDate = new Date(); + Extranet_Hotel_Id; + Edit_Id; + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Hotel_Season_Form = this.fb.group({ + extranet_season_id:'', + extranet_hotel_id:this.Extranet_Hotel_Id, + season_name:this.validserv.required, + ExtranetSeasonDetail:this.fb.array([ + this.fb.group({ + extranet_season_detail_id:'', + date:['', Validators.compose([ + Validators.required, + this.dateValidation(new Date(new Date().setDate(new Date().getDate() - 1))) + ])] + }) + ]) + }) + if(this.Edit_Id){ + this.apiserv.Get('/ExtranetSeason/GetExtranetSeasonById/'+this.Edit_Id).subscribe(res=>{ + if(res && res.status){ + this.setvalue(res.data) + } + }) + } + } + CloseCalender(element, index) { + let formArray = this.Hotel_Season_Form.controls['ExtranetSeasonDetail']['controls']; + if (element.value[0] && element.value[1]) { + element.overlayVisible = false; + element.datepickerClick = true; + if (formArray.length >= (index + 2)) { + formArray[index + 1].get("date").clearValidators(); + formArray[index + 1].get("date").setErrors(null); + formArray[index + 1].get("date").addValidators([this.dateValidation(element.value[1])]); + formArray[index + 1].get("date").markAsTouched(); + formArray[index + 1].get("date").updateValueAndValidity(); + formArray[index + 1].get("date").markAsTouched(); + } + } + } + addDate() { + let formArray = this.Hotel_Season_Form.controls['ExtranetSeasonDetail'] as FormArray; + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if(formArray.length > 0){ + if (formArray.length > 0) { + let formdate = formArray.controls[formArray.length - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + formArray.push(this.fb.group({ + extranet_season_detail_id:'', + date: ['', Validators.compose([ + Validators.required, + this.dateValidation(currentDate) + ])] + })); + } + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (toDate && control.value.length <= 1 || control.value[0] <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.Hotel_Season_Form.controls['ExtranetSeasonDetail'] as FormArray; + formArray.removeAt(index); + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if (formArray.length > 0) { + if(index > 0){ + let formdate = formArray.controls[index - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + if (formArray.controls.length >= (index + 1)) { + formArray.controls[index].get("date").clearValidators(); + formArray.controls[index].get("date").setErrors(null); + formArray.controls[index].get("date").addValidators([this.dateValidation(currentDate)]); + formArray.controls[index].get("date").markAsTouched(); + formArray.controls[index].get("date").updateValueAndValidity(); + } + } + } + Save(){ + if (this.Hotel_Season_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Hotel_Season_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Hotel_Season_Form.getRawValue(); + let ExtranetSeasonDetailArr = []; + val.ExtranetSeasonDetail.forEach(data=>{ + let from_date = new Date(Date.UTC(data.date[0].getFullYear(), data.date[0].getMonth(), data.date[0].getDate())) + let to_date = new Date(Date.UTC(data.date[1].getFullYear(), data.date[1].getMonth(), data.date[1].getDate())) + let dateObj={ + extranet_season_detail_id:data.extranet_season_detail_id ? data.extranet_season_detail_id : '', + from_date: moment(from_date).toISOString(), + to_date: moment(to_date).toISOString() + } + ExtranetSeasonDetailArr.push(dateObj) + }) + + let reqObj = { + extranet_season_id:val.extranet_season_id, + extranet_hotel_id:this.Extranet_Hotel_Id, + season_name:val.season_name, + ExtranetSeasonDetail:ExtranetSeasonDetailArr + } + this.apiserv.Post('/ExtranetSeason/SaveExtranetSeason',reqObj).subscribe(data=>{ + if(data){ + this.MsgService.add({ + severity: data.status ? "success" : "error", + detail: data.message, + }); + data.status ? this.backbutton() : ''; + } + }) + } + backbutton(){ + this.hotelmanageserv.Active_tab = 'Season'; + this.router.navigateByUrl("Services/Hotel/HotelManage/"+ this.Extranet_Hotel_Id); + } + setvalue(Resp){ + this.Hotel_Season_Form.get('season_name').setValue(Resp?.ExtranetSeason.season_name); + this.Hotel_Season_Form.get('extranet_season_id').setValue(Resp?.ExtranetSeason.extranet_season_id); + if(Resp.ExtranetSeasonDetail && Resp.ExtranetSeasonDetail.length > 0){ + Resp.ExtranetSeasonDetail.forEach((Season_detail,dateIndex)=>{ + dateIndex > 0 ? this.addDate() : ""; + let firstdate = new Date(Season_detail.from_date); + let lastdate = new Date(Season_detail.to_date ); + this.Hotel_Season_Form.controls['ExtranetSeasonDetail']['controls'][dateIndex].get("date").setValue([firstdate, lastdate]); + this.Hotel_Season_Form.controls['ExtranetSeasonDetail']['controls'][dateIndex].get("extranet_season_detail_id").setValue(Season_detail.extranet_season_detail_id); + }) + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.html new file mode 100644 index 0000000..4aa41dd --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.html @@ -0,0 +1,138 @@ +
    +
    +
    +

    Season

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Season Name + + + + Date Range + + + + Season Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.season_name}} + {{item}} + {{data.extranet_season_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.ts new file mode 100644 index 0000000..34dd731 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.component.ts @@ -0,0 +1,89 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'hotel-season', + templateUrl: './hotel-season.component.html', +}) +export class HotelSeasonComponent implements OnInit { + + Extranet_Hotel_Id; + Season_Name; + Result; + cols; + constructor(public activateRoute:ActivatedRoute,private apiserv:API,public _commonService:CommonFunctionService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.cols = [ + { field: 'season_name', header: 'Season Name' }, + { field: 'date_range', header: 'Date Range' }, + { field: 'extranet_season_id', header: 'Season Id' }, + { field: 'updated_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + { field: 'status', header: 'Status' }, + ]; + } + + Search(){ + let ReqObj = { + season_name:this.Season_Name ? this.Season_Name : '', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.Result = res.data ? res.data : []; + if(res.data){ + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetSeason/UpdateExtranetSeasonStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSeason/${this.Extranet_Hotel_Id}/${Id}`); + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.module.ts new file mode 100644 index 0000000..ddc8285 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-season/hotel-season.module.ts @@ -0,0 +1,62 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { HotelSeasonAddComponent } from './hotel-season-add/hotel-season-add.component'; +import { HotelSeasonComponent } from './hotel-season.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; + + +const routes: Routes = [ + + { + path: 'AddSeason/:Hotel_Eaxtranet_Id', + component:HotelSeasonAddComponent, + }, + { + path: 'EditSeason/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelSeasonAddComponent, + }, +] + + +@NgModule({ + declarations: [ + HotelSeasonComponent, + HotelSeasonAddComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelSeasonComponent + ] +}) +export class HotelSeasonModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.html new file mode 100644 index 0000000..62e77c8 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.html @@ -0,0 +1 @@ + diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.ts new file mode 100644 index 0000000..8d56189 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'hotel-supplements', + templateUrl: './hotel-supplements.component.html', +}) +export class HotelSupplementsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.module.ts new file mode 100644 index 0000000..4c2b2ec --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/hotel-supplements.module.ts @@ -0,0 +1,67 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SupplementsAddComponent } from './supplements-add/supplements-add.component'; +import { SupplementsViewComponent } from './supplements-view/supplements-view.component'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { ButtonModule } from 'primeng/button'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MatMenuModule } from '@angular/material/menu'; +import { CalendarModule } from 'primeng/calendar'; +import { InputTextModule } from 'primeng/inputtext'; +import { TabViewModule } from 'primeng/tabview'; +import { Tab1Component } from './supplements-add/tab1/tab1.component'; +import { Tab2Component } from './supplements-add/tab2/tab2.component'; +import { HotelSupplementsComponent } from './hotel-supplements.component'; +import { ReactiveFormsModule,FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'AddSuppliment/:Hotel_Eaxtranet_Id', + component: SupplementsAddComponent, + }, + { + path: 'EditSuppliment/:Hotel_Eaxtranet_Id/:RuleId', + component: SupplementsAddComponent, + }, + { + path: 'View', + component: SupplementsViewComponent, + }, +] + +@NgModule({ + declarations: [ + HotelSupplementsComponent, + SupplementsAddComponent, + SupplementsViewComponent, + Tab1Component, + Tab2Component + ], + imports: [ + CommonModule, + RouterModule, + NgSelectModule, + MatCheckboxModule, + ButtonModule, + TableModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + ReactiveFormsModule, + FormsModule, + TooltipModule, + InputTextModule, + TabViewModule, + MatButtonModule, + RouterModule.forChild(routes), + ], + exports:[ + HotelSupplementsComponent + ] +}) +export class HotelSupplementsModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.html new file mode 100644 index 0000000..918d5df --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.html @@ -0,0 +1,1139 @@ + +
    +
    +
    +
    +

    Add Supplements

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Contracts

    +
    + +
    +
    + +
    + {{item}} + {{item}} + {{data.room_name}} +
    + Please + select rooms +
    +
    +
    +
    + + +
    +
    +
    +
    + + + Please + enter supplement name +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Type

    +
    + +
    +
    +
    + select + Include + Exclude +
    + Please + select nationality type +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select nationality applicability +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select nationality +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select residence type +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select residence applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select residence +
    +
    +
    +
    + + + +
    +
    +
    +

    Supplement Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    + Please + select supplement days +
    +
    +
    +
    + Dinner Supplement +
    +
    +
    +
    + + + +
    +
    +
    +

    Supplement Rate Type

    +
    + +
    +
    +
    + Select + Per Room Per Night + Per Pax Per Night + Per Pax Per Stay +
    + Please + select supplement rate type +
    +
    +
    +
    + + + +
    +
    +
    +

    Supplement Type

    +
    + +
    +
    +
    + Select + Add-On Rate + New Rate +
    + Please + select supplement type +
    +
    +
    +
    + + + Please + enter supplement rate +
    +
    +
    +
    + +
    +
    +
    + + + + Please select date greater than from previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Supplement Pricing

    +
    +
    + +
    + + + +
    + {{Room_data.get('extranet_room_name').value}} +
    +
    +
    +
    Add-On Rate Details
    +
    +
    +
    + + + + Please enter adult rate + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + Please enter child age range 1 rate + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + Please enter child age range 2 rate + +
    +
    +
    +
    + Adult New Rate
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + 1 Adult + +
    +
    +
    + 2 Adult + +
    +
    +
    + 3 Adult + +
    +
    +
    + 4 Adult + +
    +
    +
    + 5 Adult + +
    +
    +
    + 6 Adult + +
    +
    +
    + 7 Adult + +
    +
    +
    + 8 Adult + +
    +
    +
    + 9 Adult + +
    +
    + {{date_wise_control.get('date').value ? + date_wise_control.get('date').value : '' }} + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + Child New Rate
    +
    + + + +
    + {{Room_data.controls['Child_range1'].value}} +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + 1 Child + +
    +
    +
    + 2 Child + +
    +
    +
    + 3 Child + +
    +
    +
    + 4 Child + +
    +
    +
    + 5 Child + +
    +
    +
    + 6 Child + +
    +
    + {{date_wise_control.get('date').value ? + date_wise_control.get('date').value : '' }} + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + + +
    + {{Room_data.controls['Child_range2'].value}} +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + 1 Child + +
    +
    +
    + 2 Child + +
    +
    +
    + 3 Child + +
    +
    +
    + 4 Child + +
    +
    +
    + 5 Child + +
    +
    +
    + 6 Child + +
    +
    + {{date_wise_control.get('date').value ? + date_wise_control.get('date').value : '' }} + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.ts new file mode 100644 index 0000000..c17d514 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/supplements-add.component.ts @@ -0,0 +1,701 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { isSameDay, addDays, parseISO } from 'date-fns'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'supplements-add', + templateUrl: './supplements-add.component.html', +}) +export class SupplementsAddComponent implements OnInit { + + Edit_Id; + CountryList; + timer; + Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + MinDate = new Date(); + ActiveTab = 0; + MainActiveTab = 0; + selectAll = ['Select All']; + SelectAllRoom = []; + ClearAllRoom = []; + AllDaysArr = [ + { Key: 'Mon', Value: 'Monday' }, + { Key: 'Tue', Value: 'Tuesday' }, + { Key: 'Wed', Value: 'Wednesday' }, + { Key: 'Thu', Value: 'Thursday' }, + { Key: 'Fri', Value: 'Friday' }, + { Key: 'Sat', Value: 'Saturday' }, + { Key: 'Sun', Value: 'Sunday' } + ]; + ddLoader = { + Country:false, + Residence:false, + }; Extranet_Hotel_Id; + AllContrtact; + enabledDates: Date[] = []; + Supplement_Form: FormGroup; + constructor(private router: Router, + public activateRoute: ActivatedRoute, + private hotelmanageserv: ManageHotelService, + public apiserv: API, public fb: FormBuilder, public validserv: ValidationService, public commonMasterSer: CommonFunctionService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.InitForm(); + this.GetAllData(); + } + + BackButton() { + this.hotelmanageserv.Active_tab = 'Supplements'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + GetAllData() { + forkJoin( + this.GetAllContract(), + this.GetHotelDetail(), + this.GetSupplementById(this.Edit_Id) + ).subscribe(res => { + if (res && res.length > 0) { + this.AllContrtact = res[0].data; + if(res[0].data){ + this.SelectAllRoom = ['Select All']; + } + if (res[1] && res[1].data) this.Supplement_Form.get('currency').setValue(res[1].data.currency); + this.SetSupplementFormValue(res[2] ? res[2].data :'') + } + }) + } + GetAllContract() { + let obj = { + extranet_hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOfferAndSupplementContracts', obj) + } + GetHotelDetail() { + return this.apiserv.Get('/ExtranetHotel/GetExtranetHotelById/' + this.Extranet_Hotel_Id) + } + GetSupplementById(Editid) { + if (Editid) + return this.apiserv.Get('/ExtranetSupplement/GetExtranetSupplementById/' + Editid) + else + return of(null) + }; + InitForm() { + this.Supplement_Form = this.fb.group({ + extranet_room_id: this.validserv.required, + currency: '', + extranet_supplement_id: '', + supplement_name: this.validserv.required, + supplement_nationality_type: '', + nationality_applicable_type: '', + supplement_days: this.validserv.required, + supplement_rate_type: this.validserv.required, + residence_type:'', + dinner_supplement:false, + residence_applicable_type:'', + supplement_type: this.validserv.required, + supplement_dates: this.fb.array([]), + ExtranetSupplementNewRate:this.fb.array([]), + // AdultNewRates: this.fb.group({ + // Adult_Contract_Arr: this.fb.array([]), + // Copy_Group: this.fb.group({}) + // }), + // ChildNewRates1: this.fb.group({ + // Child_Contract_Arr: this.fb.array([]), + // Copy_Group: this.fb.group({}) + // }), + // ChildNewRates2: this.fb.group({ + // Child_Contract_Arr: this.fb.array([]), + // Copy_Group: this.fb.group({}) + // }), + }); + this.addDate() + } + getCountryList(event,name) { + if (event.value.length >= 2) { + this.ddLoader[name] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader[name] = false; + } + }); + }, 500); + } + } + NationalityShowhide(event) { + if (event == 'SPECIFIC') { + this.Supplement_Form.addControl('nationality', new FormControl('', Validators.required)) + } else { + this.Supplement_Form.removeControl('nationality'); + } + } + NationalityTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Nationality_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.Supplement_Form.controls['nationality_applicable_type'].value == 'ALL'){ + this.Supplement_Form.get('nationality_applicable_type').setValue(''); + } + } + } + Check_day_type() { + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Supplement_Form.get('supplement_days').value; + if (value && value.length > 0 && (value.includes('Select All') || value.length == 7)) { + this.Supplement_Form.get('supplement_days').setValue(daysArr); + this.selectAll = []; + } else { + this.selectAll = ['Select All']; + } + this.CheckRateCriteria(); + } + + Check_Supplement_Rate_Type(value) { + if (value == 'PERROOMPERNIGHT') { + this.Supplement_Form.addControl('per_room_per_night_supplement_rate', new FormControl('', Validators.required)); + this.Supplement_Form.removeControl('supplement_type'); + } else { + this.Supplement_Form.removeControl('per_room_per_night_supplement_rate'); + this.Supplement_Form.addControl('supplement_type', new FormControl('', Validators.required)); + + } + this.CheckRateCriteria(); + } + addDate() { + let formArray = this.Supplement_Form.controls['supplement_dates'] as FormArray; + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + // if(formArray.length > 0){ + if (formArray.length > 0) { + let formdate = formArray.controls[formArray.length - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + formArray.push(this.fb.group({ + date: ['', Validators.compose([ + Validators.required, + this.dateValidation(currentDate) + ])] + })); + // } + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (toDate && control.value.length <= 1 || control.value[0] <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.Supplement_Form.controls['supplement_dates'] as FormArray; + formArray.removeAt(index); + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if (formArray.length > 0) { + if (index > 0) { + let formdate = formArray.controls[index - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + if (formArray.controls.length >= (index + 1)) { + formArray.controls[index].get("date").clearValidators(); + formArray.controls[index].get("date").setErrors(null); + formArray.controls[index].get("date").addValidators([Validators.required, this.dateValidation(currentDate)]); + // formArray.controls[index].get("date").markAsTouched(); + formArray.controls[index].get("date").updateValueAndValidity(); + // formArray.controls[index].get("date").markAsTouched(); + } + } + this.CheckRateCriteria(); + } + CloseCalender(element, index) { + let formArray = this.Supplement_Form.controls['supplement_dates']['controls']; + if (element.value[0] && element.value[1]) { + element.overlayVisible = false; + element.datepickerClick = true; + if (formArray.length >= (index + 2)) { + formArray[index + 1].get("date").clearValidators(); + formArray[index + 1].get("date").setErrors(null); + formArray[index + 1].get("date").addValidators([Validators.required, this.dateValidation(element.value[1])]); + formArray[index + 1].get("date").markAsTouched(); + formArray[index + 1].get("date").updateValueAndValidity(); + formArray[index + 1].get("date").markAsTouched(); + } + this.CheckRateCriteria(); + } + } + CheckRateCriteria(adultarr?,child1arr?,child2arr?) { + let rate_type = this.Supplement_Form.controls['supplement_rate_type'] ? this.Supplement_Form.get('supplement_rate_type').value : ''; + let supplement_type = this.Supplement_Form.controls['supplement_type'] ? this.Supplement_Form.get('supplement_type').value : ''; + let contract_id = this.Supplement_Form.get('extranet_room_id').value; + if (contract_id && contract_id.length > 0 && (contract_id.includes('Select All') || contract_id.length == this.AllContrtact.length) && !contract_id.includes('Clear All')) { + let room_id_List = [] + this.AllContrtact.forEach(d=>{ + room_id_List.push(d.extranet_room_id) + }); + this.Supplement_Form.get('extranet_room_id').setValue(room_id_List); + this.SelectAllRoom = []; + this.ClearAllRoom = ['Clear All']; + } else if (contract_id && contract_id.length > 0 && (contract_id.includes('Clear All'))){ + this.Supplement_Form.get('extranet_room_id').setValue([]); + this.SelectAllRoom = ['Select All']; + this.ClearAllRoom = []; + } else { + this.SelectAllRoom = ['Select All']; + if(contract_id?.length > 0){ + this.ClearAllRoom = ['Clear All']; + } + } + if(rate_type == 'PERPAXPERSTAY' && supplement_type == 'NEWRATE'){ + this.Supplement_Form.get('supplement_type').setValue(''); + } + contract_id = this.Supplement_Form.get('extranet_room_id').value; + let contract_filter_data = this.AllContrtact.filter(e => contract_id.includes(e.extranet_room_id)); + if(contract_id?.length != this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'].length){ + for(let i = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'].length -1; i >= 0 ;i--){ + let new_rate_contract_id = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][i].get('extranet_room_id').value + if(!contract_id.includes(new_rate_contract_id)){ + let formArray = this.Supplement_Form.get('ExtranetSupplementNewRate') as FormArray; + formArray.removeAt(i); + } + } + } + contract_filter_data.forEach((contract_data,contract_ind)=>{ + let selected_rooms_arr = []; + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'].forEach(control=>{ + selected_rooms_arr.push(control.get('extranet_room_id').value) + }) + if(!selected_rooms_arr.includes(contract_data.extranet_room_id)){ + let formArray = this.Supplement_Form.get('ExtranetSupplementNewRate') as FormArray; + formArray.push(this.fb.group({ + extranet_room_name:contract_data.room_name, + extranet_room_id:contract_data.extranet_room_id, + Child_range1: '', + Child_range2: '', + AdultNewRates: this.fb.group({ + Adult_Contract_Arr: this.fb.array([]), + Copy_Group: this.fb.group({}) + }), + ChildNewRates1: this.fb.group({ + Child_Contract_Arr: this.fb.array([]), + Copy_Group: this.fb.group({}) + }), + ChildNewRates2: this.fb.group({ + Child_Contract_Arr: this.fb.array([]), + Copy_Group: this.fb.group({}) + }), + })); + } + contract_data = contract_filter_data.find(e=> e.extranet_room_id == this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('extranet_room_id').value) + // this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('extranet_room_name').setValue(contract_data.room_name); + let range = contract_data ? JSON.parse(contract_data.age_range) : []; + range.forEach((data, ind) => { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('Child_range' + (ind + 1)).setValue(data.from + ' to ' + data.to); + }) + if ((rate_type == 'PERPAXPERSTAY' || rate_type == 'PERPAXPERNIGHT') && supplement_type == 'ADDONRATE') { + if (!this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].contains('addon_adult_rate')) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].addControl(`addon_adult_rate`, this.validserv.required); + } + if (contract_data) { + range.forEach((data, ind) => { + if (!this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]?.contains(`addon_child_age_range${ind + 1}_rate`)) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].addControl(`addon_child_age_range${ind + 1}_rate`, this.validserv.required); + } + }); + if (range.length <= 1) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range2_rate`); + if (range.length == 0) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range1_rate`); + } + } + } + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates'],'Adult_Contract_Arr'); + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['ChildNewRates1'],'Child_Contract_Arr'); + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['ChildNewRates2'],'Child_Contract_Arr'); + } + else if (rate_type == 'PERPAXPERNIGHT' && supplement_type == 'NEWRATE' && this.Supplement_Form.get('supplement_days').value && contract_data) { + // let dates = []; + if(!this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]?.get('ChildNewRates1')){ + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].addControl('ChildNewRates1',new FormGroup({})) + } + if(!this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]?.get('ChildNewRates2')){ + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].addControl('ChildNewRates2',new FormGroup({})) + } + if(!this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]?.get('AdultNewRates')){ + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].addControl('AdultNewRates',new FormGroup({})) + } + this.enabledDates = []; + let date_range_arr = this.Supplement_Form.get('supplement_dates').value; + let weekDays = this.Supplement_Form.get('supplement_days').value; + let ChildArr1 = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('ChildNewRates1') as FormGroup; + let ChildArr2 = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('ChildNewRates2') as FormGroup; + let AdultArr = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].get('AdultNewRates') as FormGroup; + let ChildArrValue1 = ChildArr1.contains('Child_Contract_Arr') ? ChildArr1.get('Child_Contract_Arr').value : []; + let ChildArrValue2 = ChildArr2.contains('Child_Contract_Arr') ? ChildArr2.get('Child_Contract_Arr').value : []; + let AdultArrValue = AdultArr.contains('Adult_Contract_Arr') ? AdultArr.get('Adult_Contract_Arr').value : []; + let CopyAdultArrValue = AdultArr.contains('Copy_Group') ? AdultArr.get('Copy_Group').value : []; + let CopyChild1ArrValue = ChildArr1.contains('Copy_Group') ? ChildArr1.get('Copy_Group').value : []; + let CopyChild2ArrValue = ChildArr2.contains('Copy_Group') ? ChildArr2.get('Copy_Group').value : []; + + if(adultarr)AdultArrValue = adultarr; + if(child1arr)ChildArrValue1 = child1arr; + if(child2arr)ChildArrValue2 = child2arr; + + date_range_arr.forEach(date_range => { + if (date_range && date_range.date[0] && date_range.date[1]) { + const startDate = new Date(date_range.date[0]); + const endDate = date_range.date[1]; + startDate.setHours(0, 0, 0, 0); + endDate.setHours(0, 0, 0, 0); + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + const dayName = moment(d).format('dddd'); // Get the day name (e.g., 'Monday') + if (weekDays.includes(dayName)) { + this.enabledDates.push(d); + } + } + } + }) + //Adult Occupancy data + // this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]['controls']['AdultNewRates'],'Adult_Contract_Arr') + let adult_copy_group = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]['controls']['AdultNewRates']['controls']['Copy_Group'] as FormGroup; + for (let i = 1; i <= contract_data['max_adult_occupancy']; i++) { + if(!adult_copy_group.get(`adult_${i}`)){ + adult_copy_group.addControl(`adult_${i}`, new FormControl(CopyAdultArrValue ? CopyAdultArrValue[`adult_${i}`] : '')); + } + } + + //Child range 1 occupancy data + // this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind]['controls']['ChildNewRates1'],'Child_Contract_Arr') + let child_copy_group1 = ChildArr1['controls']['Copy_Group'] as FormGroup; + for (let i = 1; i <= contract_data['max_child_occupancy']; i++) { + if(!child_copy_group1.get(`child_${i}`)){ + child_copy_group1.addControl(`child_${i}`, new FormControl(CopyChild1ArrValue ? CopyChild1ArrValue[`child_${i}`] : '')) + } + } + + //child range 2 occupancy data + // this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['ChildNewRates2'],'Child_Contract_Arr') + let child_copy_group2 = ChildArr2['controls']['Copy_Group'] as FormGroup; + for (let i = 1; i <= contract_data['max_child_occupancy']; i++) { + if(!child_copy_group2.get(`child_${i}`)){ + child_copy_group2.addControl(`child_${i}`, new FormControl(CopyChild2ArrValue ? CopyChild2ArrValue[`child_${i}`] : '')) + } + } + if (this.enabledDates.length > 0) { + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + let selected_date_arr = []; + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr']['controls'].forEach(adult_group=>{ + selected_date_arr.push(adult_group.get('date').value) + }) + this.enabledDates.forEach(dates_data => { + // Adult Table data + if(!selected_date_arr.includes(moment(dates_data).format('DD MMM YYYY'))){ + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr'].push(this.fb.group({ + date: moment(dates_data).format('DD MMM YYYY') + })) + let adultformgroup = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr']['controls'][this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr']['controls'].length - 1] as FormGroup; + let setvalue_data; + if (AdultArrValue && AdultArrValue.length > 0) { + setvalue_data = AdultArrValue.find(e => moment(dates_data).format('DD MMM YYYY') == e.date); + } + // adultformgroup.addControl('date',new FormControl(moment(dates_data).format('DD MMM YYYY'))); + for (let i = 1; i <= contract_data['max_adult_occupancy']; i++) { + if(!adultformgroup.get(`adult_${i}`)){ + adultformgroup.addControl(`adult_${i}`, new FormControl((setvalue_data && setvalue_data[`adult_${i}`] ? setvalue_data[`adult_${i}`] : 0), Validators.required)); + } + } + + //child Table data + for (let i = 1; i <= range.length; i++) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls[`ChildNewRates${i}`]['controls']['Child_Contract_Arr'].push(this.fb.group({ + date: moment(dates_data).format('DD MMM YYYY') + })) + let childformgroup = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls[`ChildNewRates${i}`]['controls']['Child_Contract_Arr']['controls'][this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls[`ChildNewRates${i}`]['controls']['Child_Contract_Arr']['controls'].length - 1] as FormGroup; + let setvalue_data; + if (ChildArrValue1 && ChildArrValue1.length > 0 && i == 1) { + setvalue_data = ChildArrValue1.find(e => moment(dates_data).format('DD MMM YYYY') == e.date); + } + if (ChildArrValue2 && ChildArrValue2.length > 0 && i == 2) { + setvalue_data = ChildArrValue2.find(e => moment(dates_data).format('DD MMM YYYY') == e.date); + } + for (let i = 1; i <= contract_data['max_child_occupancy']; i++) { + if(!childformgroup.get(`child_${i}`)){ + childformgroup.addControl(`child_${i}`, new FormControl((setvalue_data && setvalue_data[`child_${i}`] ? setvalue_data[`child_${i}`] : 0), Validators.required)); + } + } + } + } + }) + } + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range2_rate`); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range1_rate`); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_adult_rate`); + } else { + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['AdultNewRates'],'Adult_Contract_Arr'); + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['ChildNewRates1'],'Child_Contract_Arr'); + this.RemovePaxControls(this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].controls['ChildNewRates2'],'Child_Contract_Arr'); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range2_rate`); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_child_age_range1_rate`); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].removeControl(`addon_adult_rate`); + } + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][contract_ind].updateValueAndValidity(); + }) + } + RemovePaxControls(formarray,formGroup){ + if(formarray){ + let Pax_Value_Group = formarray['controls'][formGroup] as FormArray; + for (let i = Pax_Value_Group.controls.length - 1; i >= 0; i--) { + Pax_Value_Group.removeAt(i); + } + let copy_group = formarray['controls']['Copy_Group'] as FormGroup; + Object.keys(copy_group.controls).forEach(key => { + copy_group.removeControl(key); + }); + } + } + Adultcopycolumn(colname, ind, controlval?) { + let value = controlval ? controlval : this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr']['controls'][0].get(colname).value; + if (this.enabledDates && this.enabledDates.length > 0) { + for (let i = 0; i < this.enabledDates.length; i++) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls['AdultNewRates']['controls']['Adult_Contract_Arr']['controls'][i].get(colname).setValue(value); + } + } + } + AdultCopyOnUi(ind) { + let val = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls['AdultNewRates']['controls']['Copy_Group'].getRawValue(); + let contract_id = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].get('extranet_room_id').value + let contract_data = this.AllContrtact.find(e => contract_id.includes(e.extranet_room_id)); + for (let i = 1; i <= contract_data['max_adult_occupancy']; i++) { + if (val[`adult_${i}`]) { + this.Adultcopycolumn(`adult_${i}`,ind, val[`adult_${i}`]); + } + } + } + CheckTabInd(event){ + this.ActiveTab = event.index; + } + Childcopycolumn(colname, formgroup, ind, controlval?) { + let value = controlval ? controlval : this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls[formgroup]['controls']['Child_Contract_Arr']['controls'][0].get(colname).value; + if (this.enabledDates && this.enabledDates.length > 0) { + for (let i = 0; i < this.enabledDates.length; i++) { + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls[formgroup]['controls']['Child_Contract_Arr']['controls'][i].get(colname).setValue(value); + } + } + } + ChildCopyOnUi(formgroup,ind) { + let val = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].controls[formgroup]['controls']['Copy_Group'].getRawValue(); + let contract_id = this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][ind].get('extranet_room_id').value; + let contract_data = this.AllContrtact.find(e => contract_id.includes(e.extranet_room_id)); + for (let i = 1; i <= contract_data['max_child_occupancy']; i++) { + if (val[`child_${i}`]) { + this.Childcopycolumn(`child_${i}`, formgroup, ind, val[`child_${i}`]); + } + } + } + Save(){ + this.Supplement_Form.updateValueAndValidity(); + if (this.Supplement_Form.status == "VALID") { + let val = this.Supplement_Form.getRawValue(); + let mainObj = []; + val.ExtranetSupplementNewRate.forEach((new_rate_det,room_ind)=>{ + let PostObj={ + extranet_supplement_id:val.extranet_supplement_id, + extranet_room_id:val.extranet_room_id[room_ind], + supplement_name:val.supplement_name, + dinner_supplement:val.supplement_rate_type == 'PERPAXPERNIGHT'? val.dinner_supplement : false, + supplement_nationality_type:val.supplement_nationality_type ? val.supplement_nationality_type : '', + nationality_applicable_type:val.nationality_applicable_type ? val.nationality_applicable_type : '', + nationality:val.nationality ? val.nationality.join(',') : '', + residence_type:val.residence_type, + residence_applicable_type:val.residence_applicable_type, + residence:val.residence_applicable_type == 'SPECIFIC' ? val.residence.join(',') : '', + supplement_dates:'', + supplement_days:val.supplement_days ? val.supplement_days.join(',') : '', + supplement_rate_type:val.supplement_rate_type, + supplement_type:val.supplement_type, + per_room_per_night_supplement_rate:val.per_room_per_night_supplement_rate ? parseFloat(val.per_room_per_night_supplement_rate) : 0, + addon_adult_rate:new_rate_det.addon_adult_rate ? parseFloat(new_rate_det.addon_adult_rate) : 0, + addon_child_age_range1_rate:new_rate_det.addon_child_age_range1_rate ? parseFloat(new_rate_det.addon_child_age_range1_rate) : 0, + addon_child_age_range2_rate:new_rate_det.addon_child_age_range2_rate ? parseFloat(new_rate_det.addon_child_age_range2_rate) : 0, + ExtranetSupplementNewRate:[] + } + let date_Arr = []; + val.supplement_dates.forEach(season_date=>{ + date_Arr.push({ + from: moment(season_date.date[0]).format('YYYY-MM-DD'), + to: moment(season_date.date[1]).format('YYYY-MM-DD'), + }) + }); + PostObj.supplement_dates = JSON.stringify(date_Arr); + if((val.supplement_rate_type == 'PERPAXPERNIGHT' || val.supplement_rate_type == 'PERPAXPERSTAY') && val.supplement_type == 'NEWRATE'){ + this.enabledDates.forEach((date,ind)=>{ + let array_obj = { + date : moment(date).format('YYYY-MM-DD') + } + let contract_data = this.AllContrtact.find(e => val.extranet_room_id.includes(e.extranet_room_id)); + let range = contract_data ? JSON.parse(contract_data.age_range) : []; + if(new_rate_det.AdultNewRates.Adult_Contract_Arr && new_rate_det.AdultNewRates.Adult_Contract_Arr.length > 0){ + for (let i = 1; i <= contract_data['max_adult_occupancy']; i++) { + array_obj[`adult_${i}`] = parseFloat(new_rate_det.AdultNewRates.Adult_Contract_Arr[ind][`adult_${i}`]) + } + } + range.forEach((data, index) => { + if(new_rate_det[`ChildNewRates${index+1}`].Child_Contract_Arr && new_rate_det[`ChildNewRates${index+1}`].Child_Contract_Arr.length > 0){ + for (let i = 1; i <= contract_data['max_child_occupancy']; i++) { + array_obj[`age_range${index+1}_child_${i}`] = parseFloat(new_rate_det[`ChildNewRates${index+1}`].Child_Contract_Arr[ind][`child_${i}`]) + } + } + }) + PostObj.ExtranetSupplementNewRate.push(array_obj); + }) + } + mainObj.push(PostObj); + }) + + + // console.log(PostObj); + this.apiserv.Post('/ExtranetSupplement/SaveExtranetSupplement',mainObj).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + }else { + this.validserv.showValidationsMsg(this.Supplement_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } + } + SetSupplementFormValue(data){ + if(data){ + this.Supplement_Form.get('extranet_room_id').setValue(data.extranet_room_id ? data.extranet_room_id.split(',') : []); + this.Supplement_Form.get('extranet_room_id').disable(); + this.Supplement_Form.get('extranet_supplement_id').setValue(data.extranet_supplement_id); + this.Supplement_Form.get('supplement_name').setValue(data.supplement_name); + this.Supplement_Form.get('supplement_nationality_type').setValue(data.supplement_nationality_type); + this.Supplement_Form.get('nationality_applicable_type').setValue(data.nationality_applicable_type); + this.Supplement_Form.get('supplement_days').setValue(data.supplement_days ? data.supplement_days.split(','):''); + this.Supplement_Form.get('supplement_rate_type').setValue(data.supplement_rate_type); + this.Supplement_Form.get('supplement_type').setValue(data.supplement_type); + this.Supplement_Form.get('dinner_supplement').setValue(data.dinner_supplement); + this.Supplement_Form.get('supplement_rate_type').disable() + this.Supplement_Form.get('supplement_type').disable(); + this.Check_Supplement_Rate_Type(data.supplement_rate_type); + this.Supplement_Form.get('residence_type').setValue(data.residence_type); + this.Supplement_Form.get('residence_applicable_type').setValue(data.residence_applicable_type); + if(data.residence_applicable_type == 'SPECIFIC'){ + this.ResidenceShowhide(data.residence_applicable_type); + this.Supplement_Form.get('residence').setValue((data.residence.split(','))); + this.CountryList = data.country ? JSON.parse(data.country) : []; + } + if(data.supplement_rate_type == 'PERROOMPERNIGHT'){ + this.Supplement_Form.get('per_room_per_night_supplement_rate').setValue(data.per_room_per_night_supplement_rate); + } + if(data.nationality_applicable_type == 'SPECIFIC'){ + this.NationalityShowhide('SPECIFIC'); + this.Supplement_Form.get('nationality').setValue(data.nationality.split(',')); + this.CountryList = data.country ? JSON.parse(data.country) : []; + } + if(data.supplement_dates){ + let dates_arr = JSON.parse(data.supplement_dates); + dates_arr.forEach((dates,ind)=>{ + if(ind > 0)this.addDate(); + this.Supplement_Form.controls['supplement_dates']['controls'][ind]['controls']['date'].setValue([new Date(dates.from),new Date(dates.to)]) + }) + } + if((data.supplement_rate_type == 'PERPAXPERSTAY' ||data.supplement_rate_type == 'PERPAXPERNIGHT') && data.supplement_type == 'ADDONRATE'){ + this.CheckRateCriteria(); + this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][0].get('addon_adult_rate').setValue(data.addon_adult_rate); + if(data.addon_child_age_range1_rate)this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][0].get('addon_child_age_range1_rate').setValue(data.addon_child_age_range1_rate); + if(data.addon_child_age_range2_rate)this.Supplement_Form.controls['ExtranetSupplementNewRate']['controls'][0].get('addon_child_age_range2_rate').setValue(data.addon_child_age_range2_rate); + } + if((data.supplement_rate_type == 'PERPAXPERSTAY' ||data.supplement_rate_type == 'PERPAXPERNIGHT') && data.supplement_type == 'NEWRATE'){ + let Child1arr = []; + let Child2arr = []; + let adultarr = []; + data.ExtranetSupplementNewRate.forEach(data_on_date=>{ + Child1arr.push({ + date:moment(data_on_date.date).format('DD MMM YYYY'), + child_1:data_on_date.age_range1_child_1, + child_2:data_on_date.age_range1_child_2, + child_3:data_on_date.age_range1_child_3, + child_4:data_on_date.age_range1_child_4, + child_5:data_on_date.age_range1_child_5, + child_6:data_on_date.age_range1_child_6, + }) + Child2arr.push({ + date:moment(data_on_date.date).format('DD MMM YYYY'), + child_1:data_on_date.age_range2_child_1, + child_2:data_on_date.age_range2_child_2, + child_3:data_on_date.age_range2_child_3, + child_4:data_on_date.age_range2_child_4, + child_5:data_on_date.age_range2_child_5, + child_6:data_on_date.age_range2_child_6, + }) + adultarr.push({ + date:moment(data_on_date.date).format('DD MMM YYYY'), + adult_1:data_on_date.adult_1, + adult_2:data_on_date.adult_2, + adult_3:data_on_date.adult_3, + adult_4:data_on_date.adult_4, + adult_5:data_on_date.adult_5, + adult_6:data_on_date.adult_6 + }) + }) + this.CheckRateCriteria(adultarr,Child1arr,Child2arr); + } + } + } + ResidenceTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Residence_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.Supplement_Form.controls['residence_applicable_type'].value == 'ALL'){ + this.Supplement_Form.get('residence_applicable_type').setValue(''); + } + } + } + ResidenceShowhide(event){ + if(event == 'SPECIFIC'){ + this.Supplement_Form.addControl('residence',new FormControl('',Validators.required)) + }else{ + this.Supplement_Form.removeControl('residence'); + } + } + CheckTabMainInd(event){ + this.MainActiveTab = event.index; +} +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.html new file mode 100644 index 0000000..72679f9 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.html @@ -0,0 +1,121 @@ +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + 1 Child + +
    +
    +
    + 2 Child + +
    +
    +
    + 3 Child + +
    +
    +
    + 4 Child + +
    +
    + 12 Mar 2021 + + 120 + + 120 + + 120 + + 120 +
    + 13 Mar 2021 + + 120 + + 120 + + 120 + + 120 +
    + 14 Mar 2021 + + 120 + + 120 + + 120 + + 120 +
    +
    +
    +
    diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.ts new file mode 100644 index 0000000..b4c97dd --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab1/tab1.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-tab1', + templateUrl: './tab1.component.html', +}) +export class Tab1Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.html new file mode 100644 index 0000000..8303a31 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.html @@ -0,0 +1,121 @@ +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    + 1 Child + +
    +
    +
    + 2 Child + +
    +
    +
    + 3 Child + +
    +
    +
    + 4 Child + +
    +
    + 12 Mar 2021 + + 125 + + 125 + + 125 + + 130 +
    + 13 Mar 2021 + + 120 + + 120 + + 120 + + 120 +
    + 14 Mar 2021 + + 120 + + 120 + + 120 + + 120 +
    +
    +
    +
    diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.ts new file mode 100644 index 0000000..1d733da --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-add/tab2/tab2.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-tab2', + templateUrl: './tab2.component.html', +}) +export class Tab2Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.html new file mode 100644 index 0000000..dc81f31 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.html @@ -0,0 +1,234 @@ +
    +
    +
    +

    Supplements

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + Select + {{data.room_name + (data.room_view_name ? ', ' : '') + + data.room_view_name}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Supplement Rate Type

    +
    + +
    +
    +
    + Select + Per Room Per Night + Per Pax Per Night + Per Pax Per Stay +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Supplement Type

    +
    + +
    +
    +
    + Select + Add-On Rate + New Rate +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Supplement Name + + + + Supplement Rate Type + + + + Room Name + + + + Supplement Type + + + + Supplement Dates + + + + Supplement Days + + + + Supplement Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.supplement_name}} + {{data.supplement_rate_type}} + {{data.room_name}} + {{data.supplement_type}} + {{item}} + {{data.supplement_days}} + {{data.extranet_supplement_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.ts new file mode 100644 index 0000000..69c993c --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-supplements/supplements-view/supplements-view.component.ts @@ -0,0 +1,153 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'supplements-view', + templateUrl: './supplements-view.component.html', +}) +export class SupplementsViewComponent implements OnInit { + + AllRoomsData; + Result; + cols; + SupplementSearchForm:FormGroup + constructor( + public activateRoute:ActivatedRoute, + public apiserv:API, + public _commonService:CommonFunctionService, + public router:Router, + private fb:FormBuilder + ) { } + Extranet_Hotel_Id; + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.GetAllRooms(); + this.SupplementSearchForm = this.fb.group({ + extranet_hotel_id:this.Extranet_Hotel_Id, + extranet_room_id:'', + contract_name:'', + supplement_name:'', + supplement_rate_type:'', + supplement_type:'' + }); + this.cols = [ + { field: 'supplement_name', header: 'Supplement Name' }, + { field: 'supplement_rate_type', header: 'Supplement Rate Type' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'supplement_type', header: 'Supplement Type' }, + { field: 'date_range_arr', header: 'supplement_dates' }, + { field: 'custom_days', header: 'Supplement days' }, + { field: 'extranet_supplement_id', header: 'Supplement Id' }, + { field: 'status', header: 'Status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' } + ]; + } + + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj).subscribe(res=>{ + if(res && res.data){ + this.AllRoomsData = res.data; + } + }) + } + Search(){ + let val = this.SupplementSearchForm.getRawValue(); + let obj = { + extranet_hotel_id:val.extranet_hotel_id, + extranet_room_id:val.extranet_room_id, + contract_name:val.contract_name, + supplement_name:val.supplement_name, + supplement_rate_type:val.supplement_rate_type, + supplement_type:val.supplement_type, + } + this.apiserv.Post('/ExtranetSupplement/GetAllExtranetSupplement',obj).subscribe(res=>{ + if (res) { + this.Result = res.data ? res.data : []; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['supplement_rate_type'] = this.getSupplementRateType(e.supplement_rate_type); + e['supplement_type'] = this.getSupplementType(e.supplement_type); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['supplement_dates'] ? JSON.parse(e['supplement_dates']) : e['supplement_dates']; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.from).format('DD MMM YYYY') + ' - ' + moment(data.to).format('DD MMM YYYY'); + }) + } + e['custom_days'] = e['supplement_days'] ? e['supplement_days'].split(',') : '' + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetSupplement/UpdateExtranetSupplementStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + getSupplementType(value){ + if(value == 'ADDONRATE'){ + return 'Add-On Rate' + }else if(value == 'NEWRATE'){ + return 'New Rate' + } + return '' + } + getSupplementRateType(value){ + if(value == 'PERROOMPERNIGHT'){ + return 'Per Room Per Night' + }else if(value == 'PERPAXPERNIGHT'){ + return 'Per Pax Per Night' + }else if(value == 'PERPAXPERSTAY'){ + return 'Per Pax Per Stay' + } + return '' + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSuppliment/${this.Extranet_Hotel_Id}/${Id}`); + } + Reset(){ + this.SupplementSearchForm.get('extranet_room_id').setValue(''); + this.SupplementSearchForm.get('contract_name').setValue(''); + this.SupplementSearchForm.get('supplement_name').setValue(''); + this.SupplementSearchForm.get('supplement_rate_type').setValue(''); + this.SupplementSearchForm.get('supplement_type').setValue(''); + } +} \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.html new file mode 100644 index 0000000..cfb56bf --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.html @@ -0,0 +1,370 @@ + +
    +
    +
    +

    Update Adult Rate

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    +
    +
    + +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + Please + select Season +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Adult Pricing

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + 1 Adult + +
    +
    +
    + 2 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 3 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 4 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 5 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 6 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 7 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 8 Adult + +
    + ExtraBed Included +
    +
    +
    +
    + 9 Adult + +
    + ExtraBed Included +
    +
    +
    + {{date_wise_control.get('contract_date').value ? (date_wise_control.get('contract_date').value | date: "dd MMM YYYY") : '' }} + + {{date_wise_control.get('contract_day').value}} + + + + + + + + + + + + + + + + + + +
    No data found
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.ts new file mode 100644 index 0000000..876f394 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.component.ts @@ -0,0 +1,307 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'hotel-update-adult', + templateUrl: './hotel-update-adult.component.html', +}) +export class HotelUpdateAdultComponent implements OnInit { + Extranet_Hotel_Id; + Edit_Id; + GetAllContractResp; + GetAllData; + AllSeason; + Defaultdate = new Date(); + selectedDate: Date | null = null; + DisableDate; + selectAll = ['Select All']; + hasResult = false; + enabledDates: Date[] = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Adult_contract_Search_Form:FormGroup; + Adult_contract_Save_Form:FormGroup; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Adult_contract_Search_Form = this.fb.group({ + room_Name:'', + rate_Plan:'', + meal_Plan:'', + currency:'', + contract_days:'', + date_type:this.validserv.required, + }) + this.GetAllSeason(); + this.GetById(); + // this.disabledDates(); + } + + GetById(){ + this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + // this.SetRoomdata(res.data); + let dates_range_arr = res.data['contract_dates'] ? JSON.parse(res.data.contract_dates) : []; + this.Adult_contract_Search_Form.get('room_Name').setValue(res.data.room_name); + this.Adult_contract_Search_Form.get('rate_Plan').setValue(res.data.rate_plan_name); + this.Adult_contract_Search_Form.get('meal_Plan').setValue(res.data.meal_plan_name); + this.Adult_contract_Search_Form.get('currency').setValue(res.data.currency_code); + this.GetAllData = res.data; + // this.GetAllData['max_adult_occupancy'] = 3; + dates_range_arr.forEach(date_range=>{ + const startDate = parseISO(date_range.date_from); + const endDate = parseISO(date_range.date_to); + + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + this.enabledDates.push(d); + } + }); + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + for(let i=0;i= new Date().getTime()){ + this.Defaultdate = new Date(this.enabledDates[i]); + break; + } + if(this.enabledDates.length -1 == i){ + this.Defaultdate = new Date(this.enabledDates[i]); + } + } + let to_date = new Date(this.enabledDates[0]); + to_date.setMonth(to_date.getMonth()-12) + let from_date = new Date(this.enabledDates[0]); + from_date.setMonth(from_date.getMonth() + 18) + this.DisableDate = this.disabledDates(to_date,from_date) + } + }) + } + disabledDates(to_date,From_date): Date[] { + const start = startOfYear(new Date(to_date)); + const end = endOfYear(new Date(From_date)); + const disabledDates: Date[] = []; + + for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { + if (!this.isDateEnabled(new Date(d))) { + disabledDates.push(new Date(d)); + } + } + + return disabledDates; + } + + isDateEnabled(date: Date): boolean { + return this.enabledDates.some(enabledDate => + isSameDay(date, enabledDate) + ); + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + SearchAdultcontract(){ + if (this.Adult_contract_Search_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Adult_contract_Search_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let date_arr = []; + let val = this.Adult_contract_Search_Form.getRawValue(); + if(val.date_type == 'SPECIFICDATES'){ + const selectedFromDate = new Date(val.date[0]); + const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset); + const selectedToDate = new Date(val.date[1]); + const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset); + date_arr.push({ + date_from:fromDate, + date_to:toDate, + }); + }else if(val.date_type == 'SEASON'){ + let season_id = val.Season_Id + season_id.forEach(data => { + let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data); + if (matched_season_by_id) { + if (typeof (matched_season_by_id['date_range']) == 'string') { + let splited_date = matched_season_by_id.date_range.split(', '); + splited_date.forEach((z) => { + date_arr.push({ + date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`), + date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`), + }); + }) + } + } + }) + } + let ReqObj = { + extranet_contract_id:this.Edit_Id, + date_range:date_arr, + contract_days:val.contract_days ? val.contract_days.join(','):'', + } + + this.apiserv.Post('/ExtranetRoomContract/GetAllAdultRateContract',ReqObj).subscribe(resp=>{ + this.hasResult = true; + if(resp){ + this.GetAllContractResp = resp.data; + this.Adult_contract_Save_Form = this.fb.group({ + Copy_Group:this.fb.group({}), + Adult_Contract_Arr:this.fb.array([]) + }); + let contract_group = this.Adult_contract_Save_Form.controls['Copy_Group'] as FormGroup; + let adult_extrabed_details = this.GetAllData['adult_extrabed_details_json'] ? JSON.parse(this.GetAllData['adult_extrabed_details_json']) : ''; + for(let i=1;i<=this.GetAllData['max_adult_occupancy'];i++){ + contract_group.addControl(`adult_${i}`,new FormControl('')); + contract_group.addControl(`supplement_${i}`,new FormControl({value : adult_extrabed_details ? adult_extrabed_details[`adult_${i}`] : false, disabled : true})); + } + if(resp.data){ + resp.data.sort((a,b)=>{ + let from_date = new Date(a.contract_date); + let to_date = new Date(b.contract_date) + return from_date.getTime() - to_date.getTime() + }) + resp.data.forEach((contractc_data,ind)=>{ + let formArray = this.Adult_contract_Save_Form.controls['Adult_Contract_Arr'] as FormArray; + let day = this.AllDaysArr.find(e=>e.Value == contractc_data.contract_day) + formArray.push(this.fb.group({ + contract_date:contractc_data.contract_date, + contract_day:day ? day.Key : '', + extranet_contract_rate_id:contractc_data.extranet_contract_rate_id, + })); + for(let i=1;i<=this.GetAllData['max_adult_occupancy'];i++){ + let formgroup = formArray.controls[ind] as FormGroup; + formgroup.addControl(`adult_${i}`,new FormControl(contractc_data[`adult_${i}`])); + } + }) + }else { + this.commonMasterSer.showMessage(resp.status,resp.message); + } + } + }) + } + copycolumn(colname,controlval?){ + let value = controlval ? controlval : this.Adult_contract_Save_Form.controls['Adult_Contract_Arr']['controls'][0].get(colname).value; + if(this.GetAllContractResp && this.GetAllContractResp.length > 0){ + for(let i = 0;i { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Adult_contract_Save_Form.controls['Adult_Contract_Arr'].getRawValue(); + let reqObjArr = []; + val.forEach(adultcontract=>{ + reqObjArr.push({ + extranet_contract_rate_id : adultcontract.extranet_contract_rate_id, + extranet_contract_id : this.Edit_Id, + contract_date : adultcontract.contract_date, + contract_day : adultcontract.contract_day, + adult_1 : adultcontract.adult_1 ? parseFloat(adultcontract.adult_1) : 0, + adult_2 : adultcontract.adult_2 ? parseFloat(adultcontract.adult_2) : 0, + adult_3 : adultcontract.adult_3 ? parseFloat(adultcontract.adult_3) : 0, + adult_4 : adultcontract.adult_4 ? parseFloat(adultcontract.adult_4) : 0, + adult_5 : adultcontract.adult_5 ? parseFloat(adultcontract.adult_5) : 0, + adult_6 : adultcontract.adult_6 ? parseFloat(adultcontract.adult_6) : 0, + adult_7 : adultcontract.adult_7 ? parseFloat(adultcontract.adult_7) : 0, + adult_8 : adultcontract.adult_8 ? parseFloat(adultcontract.adult_8) : 0, + adult_9 : adultcontract.adult_9 ? parseFloat(adultcontract.adult_9) : 0, + }) + }); + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetAdultRate',reqObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + Reset(){ + this.Adult_contract_Search_Form.reset(); + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Adult_contract_Search_Form.get('contract_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Adult_contract_Search_Form.get('contract_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + + ShowDateTypeFields(event){ + if(event == 'SPECIFICDATES'){ + this.Adult_contract_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()]))); + this.Adult_contract_Search_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Adult_contract_Search_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Adult_contract_Search_Form.removeControl('date'); + }else { + this.Adult_contract_Search_Form.removeControl('Season_Id'); + this.Adult_contract_Search_Form.removeControl('date'); + } + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.AllSeason = res.data; + } + }) + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.module.ts new file mode 100644 index 0000000..862d84b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-adult/hotel-update-adult.module.ts @@ -0,0 +1,57 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateAdultComponent } from './hotel-update-adult.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'UpdateAdultRate/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelUpdateAdultComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateAdultComponent, + + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + TooltipModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + ], + + exports:[ + HotelUpdateAdultComponent + ] +}) +export class HotelUpdateAdultModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.html new file mode 100644 index 0000000..2b879ee --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.html @@ -0,0 +1,338 @@ + +
    +
    +
    +

    Update Allocation

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    +
    +
    + +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + Please + select Season +
    +
    +
    +
    + + + +
    +
    +
    +

    Allocation Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    + Please + select contract days +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Allocation

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + Select + Count Sale + Free Sale + Stop Sale +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    Date
    +
    +
    Day
    +
    +
    + Allocation Type + +
    +
    +
    + Allocation + +
    +
    +
    + Release Days + +
    +
    +
    + Booked Count +
    +
    +
    + Remaining Count +
    +
    + {{date_wise_control.get('allocation_date').value ? + (date_wise_control.get('allocation_date').value | date: "dd MMM YYYY") : '' }} + + {{date_wise_control.get('allocation_day').value}} + +
    + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + Select + Count Sale + Free Sale + Stop Sale +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    No data found
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.ts new file mode 100644 index 0000000..55b06de --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.component.ts @@ -0,0 +1,449 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { MessageService } from 'primeng/api'; + +@Component({ + selector: 'hotel-update-allocation', + templateUrl: './hotel-update-allocation.component.html', +}) +export class HotelUpdateAllocationComponent implements OnInit { + Extranet_Hotel_Id; + Edit_Id; + Defaultdate = new Date(); + GetAllContractResp; + GetAllData; + AllSeason; + DisableDate; + selectAll = ['Select All']; + hasResult = false; + enabledDates: Date[] = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Allocation_Search_Form:FormGroup; + Allocation_Save_Form:FormGroup; + IsMobile; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router,public messageService:MessageService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Allocation_Search_Form = this.fb.group({ + room_Name:'', + room_Id:'', + date_type:this.validserv.required, + allocation_days:[] + }) + this.GetAllSeason(); + this.GetById(); + // this.disabledDates(); + } + + GetById(){ + this.apiserv.Get('/ExtranetAllocation/GetExtranetAllocationById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + // this.SetRoomdata(res.data); + let dates_range_arr = res.data['date_ranges'] ? JSON.parse(res.data.date_ranges) : []; + this.Allocation_Search_Form.get('room_Name').setValue(res.data.room_name); + this.Allocation_Search_Form.get('room_Id').setValue(res.data.extranet_room_id); + this.GetAllData = res.data; + this.GetAllData['max_adult_occupancy'] = 3; + dates_range_arr.forEach(date_range=>{ + const startDate = parseISO(date_range.date_from); + const endDate = parseISO(date_range.date_to); + + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + this.enabledDates.push(d); + } + }); + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + for(let i=0;i= new Date().getTime()){ + this.Defaultdate = new Date(this.enabledDates[i]); + break; + } + if(this.enabledDates.length -1 == i){ + this.Defaultdate = new Date(this.enabledDates[i]); + } + } + let to_date = new Date(this.enabledDates[0]); + to_date.setMonth(to_date.getMonth()-12) + let from_date = new Date(this.enabledDates[0]); + from_date.setMonth(from_date.getMonth() + 18) + this.DisableDate = this.disabledDates(to_date,from_date) + } + }) + } + disabledDates(to_date,From_date): Date[] { + const start = startOfYear(new Date(to_date)); + const end = endOfYear(new Date(From_date)); + const disabledDates: Date[] = []; + + for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { + if (!this.isDateEnabled(new Date(d))) { + disabledDates.push(new Date(d)); + } + } + + return disabledDates; + } + + isDateEnabled(date: Date): boolean { + return this.enabledDates.some(enabledDate => + isSameDay(date, enabledDate) + ); + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'Allocation'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + SearchAllocation(){ + if (this.Allocation_Search_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Allocation_Search_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Allocation_Search_Form.getRawValue(); + let ReqObj = { + extranet_room_id:val.room_Id ? val.room_Id:'', + extranet_hotel_id:this.Extranet_Hotel_Id, + date_range:[], + allocation_days:val.allocation_days ? val.allocation_days.join(','):'', + } + if(val.date_type == 'SPECIFICDATES'){ + const selectedFromDate = new Date(val.date[0]); + const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset); + const selectedToDate = new Date(val.date[1]); + const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset); + ReqObj.date_range.push({ + date_from:fromDate, + date_to:toDate, + }); + }else if(val.date_type == 'SEASON'){ + val.Season_Id.forEach(data => { + let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data); + if (matched_season_by_id) { + if (typeof (matched_season_by_id['date_range']) == 'string') { + let splited_date = matched_season_by_id.date_range.split(', '); + splited_date.forEach((z) => { + ReqObj.date_range.push({ + date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`), + date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`), + }); + }) + } + } + }) + } + this.apiserv.Post('/ExtranetAllocation/GetUpdateallocation',ReqObj).subscribe(resp=>{ + this.hasResult = true; + if(resp){ + this.GetAllContractResp = resp.data && resp.data.length > 0 ? resp.data : undefined; + this.Allocation_Save_Form = this.fb.group({ + Copy_Group:this.fb.group({ + allocation_type:'', + allocation_limit:'', + release_days:'', + }), + Allocation_Arr:this.fb.array([]) + }); + if(resp.data){ + resp.data.sort((a,b)=>{ + let from_date = new Date(a.allocation_date); + let to_date = new Date(b.allocation_date) + return from_date.getTime() - to_date.getTime() + }) + resp.data.forEach((contract_data,ind)=>{ + let formArray = this.Allocation_Save_Form.controls['Allocation_Arr'] as FormArray; + let day = this.AllDaysArr.find(e=>e.Value == contract_data.contract_day) + formArray.push(this.fb.group({ + allocation_type:contract_data.allocation_type, + allocation_limit:contract_data.allocation_limit, + release_days:contract_data.release_days, + allocation_date:contract_data.allocation_date, + allocation_day:contract_data.allocation_day, + booking_count:contract_data.booking_count, + remaining_count:contract_data.remaining_count, + contract_day:day ? day.Key : '', + extranet_allocation_id:contract_data.extranet_allocation_id, + extranet_room_id:contract_data.extranet_room_id, + Is_Required:false + })); + + let formgroup = formArray.controls[ind] as FormGroup; + if(contract_data.booking_count || contract_data.allocation_limit || contract_data.release_days || contract_data.remaining_count){ + if(contract_data.allocation_type=='FREESALE' || contract_data.allocation_type=='STOPSALE'){ + formgroup.get('allocation_limit').disable(); + formgroup.get('release_days').disable(); + }else { + formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(contract_data.booking_count )]); + formgroup.get('release_days').addValidators([Validators.required]); + } + formgroup.get('allocation_type').addValidators([Validators.required]); + formgroup.get('Is_Required').setValue(true); + } + }) + }else { + this.commonMasterSer.showMessage(resp.status,resp.message); + } + } + }) + }; + get copyForm(){ + return this.Allocation_Save_Form.get('Copy_Group') as FormGroup + } + copycolumn(colname,controlval?){ + let value = controlval ? controlval : this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][0].get(colname).value; + if(this.GetAllContractResp && this.GetAllContractResp.length > 0){ + for(let i = 0;i { + this.validserv.scrollToError(); + }, 50); + for(let i = 0;i{ + reqObjArr.push({ + extranet_allocation_id : Allocationdata.extranet_allocation_id, + extranet_room_id : Allocationdata.extranet_room_id, + extranet_hotel_id : this.Extranet_Hotel_Id, + allocation_date : Allocationdata.allocation_date, + allocation_day : Allocationdata.allocation_day, + allocation_type : Allocationdata.allocation_type, + booking_count : Allocationdata.booking_count ? parseInt(Allocationdata.booking_count) :0, + remaining_count : Allocationdata.remaining_count ? parseInt(Allocationdata.remaining_count) : 0, + release_days : Allocationdata.release_days ? Allocationdata.release_days : '', + allocation_limit : Allocationdata.allocation_limit ? Allocationdata.allocation_limit : '' + }) + }); + this.apiserv.Post('/ExtranetAllocation/UpdateExtranetAllocation',reqObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + Reset(){ + this.Allocation_Search_Form.reset(); + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Allocation_Search_Form.get('allocation_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Allocation_Search_Form.get('allocation_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value == 0) { + if (initialValue && parseInt(control.value) < parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; + } + AllocationType_Check(i){ + let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup; + let val = formgroup.get('allocation_type').value; + if(val == 'FREESALE'){ + formgroup.get('allocation_limit').disable(); + formgroup.get('release_days').disable(); + formgroup.get('allocation_limit').clearValidators(); + formgroup.get('release_days').clearValidators(); + formgroup.get('allocation_limit').setValue('FREESALE'); + } + else if( val=='STOPSALE'){ + formgroup.get('allocation_limit').disable(); + formgroup.get('release_days').disable(); + formgroup.get('allocation_limit').clearValidators(); + formgroup.get('release_days').clearValidators(); + }else if(val == 'COUNTSALE') { + formgroup.get('release_days').enable(); + formgroup.get('allocation_limit').enable(); + formgroup.get('allocation_limit').setValue(formgroup.get('allocation_limit').value == 'FREESALE' ? formgroup.get('booking_count').value : formgroup.get('allocation_limit').value); + formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]); + formgroup.get('release_days').addValidators([Validators.required]); + }else if((!formgroup.get('Is_Required').value && (formgroup.get('allocation_limit').value || formgroup.get('release_days').value)) || formgroup.get('Is_Required').value){ + formgroup.get('release_days').enable(); + formgroup.get('allocation_limit').enable(); + formgroup.get('allocation_limit').setValue(formgroup.get('booking_count').value); + formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]); + formgroup.get('release_days').addValidators([Validators.required]); + formgroup.get('allocation_type').addValidators([Validators.required]); + }else { + formgroup.get('release_days').enable(); + formgroup.get('allocation_limit').enable(); + formgroup.get('allocation_limit').setValue(''); + formgroup.get('release_days').setValue(''); + formgroup.get('allocation_limit').clearValidators(); + formgroup.get('release_days').clearValidators(); + formgroup.get('allocation_type').clearValidators(); + } + // formgroup.get('allocation_type').addValidators([Validators.required]); + // formgroup.get('Is_Required').setValue(true); + formgroup.get('allocation_limit').updateValueAndValidity(); + formgroup.get('release_days').updateValueAndValidity(); + formgroup.get('allocation_type').updateValueAndValidity(); + this.checkvalidation(i); + } + checkvalidation(i){ + let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup; + // if(formgroup.get('Is_Required').value || (!formgroup.get('Is_Required').value || formgroup.get('Is_Required').value)){ + if(formgroup.get('allocation_type').hasError('required')){ + this.messageService.add({ + severity: 'error', + detail: 'Please select allocation type', + sticky: true // Toast will remain visible until manually closed + }); + } + if(formgroup.get('allocation_limit').hasError('required')){ + this.messageService.add({ + severity: 'error', + detail: 'Please enter allocation', + sticky: true // Toast will remain visible until manually closed + }); + } + if(formgroup.get('allocation_limit').hasError('range')){ + this.messageService.add({ + severity: 'info', + detail: 'Allocation can not be lesser than booking count', + sticky: true // Toast will remain visible until manually closed + }); + } + if(formgroup.get('release_days').hasError('required')){ + this.messageService.add({ + severity: 'error', + detail: 'Please enter release days', + sticky: true // Toast will remain visible until manually closed + }); + } + // } + } + check_Allocation_and_Realase_Validation(i){ + let formgroup = this.Allocation_Save_Form.controls['Allocation_Arr']['controls'][i] as FormGroup; + if(!formgroup.get('Is_Required').value && (formgroup.get('allocation_type').value || formgroup.get('allocation_limit').value || formgroup.get('release_days').value)){ + formgroup.get('release_days').enable(); + formgroup.get('allocation_limit').enable(); + // formgroup.get('allocation_limit').setValue(formgroup.get('booking_count').value); + formgroup.get('allocation_limit').addValidators([Validators.required,this.AmountRangeValidation(formgroup.get('booking_count').value)]); + formgroup.get('release_days').addValidators([Validators.required]); + formgroup.get('allocation_type').addValidators([Validators.required]); + }else if(!formgroup.get('Is_Required').value ){ + formgroup.get('allocation_limit').clearValidators(); + formgroup.get('release_days').clearValidators(); + formgroup.get('allocation_type').clearValidators(); + } + formgroup.get('allocation_limit').updateValueAndValidity(); + formgroup.get('release_days').updateValueAndValidity(); + formgroup.get('allocation_type').updateValueAndValidity(); + this.checkvalidation(i); + } + Copy_Group_Type_check(event){ + if(event == 'FREESALE'){ + this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').setValue('FREESALE'); + this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').disable() + }else { + if(this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').value == 'FREESALE'){ + this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').setValue(''); + } + this.Allocation_Save_Form.controls['Copy_Group'].get('allocation_limit').enable(); + } + + } + + + ShowDateTypeFields(event){ + if(event == 'SPECIFICDATES'){ + this.Allocation_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()]))); + this.Allocation_Search_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Allocation_Search_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Allocation_Search_Form.removeControl('date'); + }else { + this.Allocation_Search_Form.removeControl('Season_Id'); + this.Allocation_Search_Form.removeControl('date'); + } + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.AllSeason = res.data; + } + }) + } +} \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.module.ts new file mode 100644 index 0000000..d291943 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-allocation/hotel-update-allocation.module.ts @@ -0,0 +1,56 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateAllocationComponent } from './hotel-update-allocation.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'UpdateAllocation/:Hotel_Eaxtranet_Id/:RuleId', + component: HotelUpdateAllocationComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateAllocationComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + TooltipModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + + ], + exports:[ + HotelUpdateAllocationComponent + ] +}) +export class HotelUpdateAllocationModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.html new file mode 100644 index 0000000..86abd87 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.html @@ -0,0 +1,334 @@ + +
    +
    +
    +

    Update Cancellation Policy

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    +
    +
    + +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + Please + select Season +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Cancellation Policy

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Date + + Day + + Cancellation Type + + From + + To + + Night Type + + Value +
    +
    + {{cancel_date_Group.get('contract_date').value ? (cancel_date_Group.get('contract_date').value | date: "dd MMM YYYY") : '' }} +
    +
    +
    + {{cancel_date_Group.get('contract_day').value}} +
    +
    +
    + + +
    +
    +
    +

    Cancellation Type

    +
    + +
    +
    + +
    + Select + Full Charges + Night Count + Amount + Percentage +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    +

    Night Type

    +
    + +
    +
    + +
    + Select + First + Last + Cheapest + Highest +
    +
    +
    + Disabled +
    +
    +
    + +
    +
    + Disabled +
    +
    +
    + + +
    +
    + Please select cancellation type + Please enter cancellation from + Please enter cancellation from range greater than previous range + Please enter cancellation to + Please enter cancellation to range greater than cancellation from + Please select night type + Please enter value +
    + + + + + + + + + + + + + +
    + Date + + Day + + Cancellation Type + + From + + To + + Night Type + + Value +
    No data found
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.ts new file mode 100644 index 0000000..aac00c6 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.component.ts @@ -0,0 +1,458 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'hotel-update-cancellation', + templateUrl: './hotel-update-cancellation.component.html', +}) +export class HotelUpdateCancellationComponent implements OnInit { + Extranet_Hotel_Id; + Edit_Id; + Range_Data; + AllSeason; + Defaultdate = new Date(); + GetAllContractResp; + GetAllData; + Validation_Message_Obj = []; + cancellation_array_length; + selectedDate: Date | null = null; + DisableDate; + selectAll = ['Select All']; + hasResult = false; + enabledDates: Date[] = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Cancellation_contract_Search_Form:FormGroup; + Cancellation_contract_Save_Form:FormGroup; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Cancellation_contract_Search_Form = this.fb.group({ + room_Name:'', + rate_Plan:'', + meal_Plan:'', + currency:'', + date_type:this.validserv.required, + contract_days:'' + }) + this.GetAllSeason(); + this.GetById(); + // this.disabledDates(); + } + + GetById(){ + this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + // this.SetRoomdata(res.data); + let dates_range_arr = res.data['contract_dates'] ? JSON.parse(res.data.contract_dates) : []; + this.Cancellation_contract_Search_Form.get('room_Name').setValue(res.data.room_name); + this.Cancellation_contract_Search_Form.get('rate_Plan').setValue(res.data.rate_plan_name); + this.Cancellation_contract_Search_Form.get('meal_Plan').setValue(res.data.meal_plan_name); + this.Cancellation_contract_Search_Form.get('currency').setValue(res.data.currency_code); + this.GetAllData = res.data; + this.Range_Data = res.data.age_range ? JSON.parse(res.data.age_range) : []; + // this.GetAllData['max_adult_occupancy'] = 3; + dates_range_arr.forEach(date_range=>{ + const startDate = parseISO(date_range.date_from); + const endDate = parseISO(date_range.date_to); + + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + this.enabledDates.push(d); + } + }); + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + for(let i=0;i= new Date().getTime()){ + this.Defaultdate = new Date(this.enabledDates[i]); + break; + } + if(this.enabledDates.length -1 == i){ + this.Defaultdate = new Date(this.enabledDates[i]); + } + } + let to_date = new Date(this.enabledDates[0]); + to_date.setMonth(to_date.getMonth()-12) + let from_date = new Date(this.enabledDates[0]); + from_date.setMonth(from_date.getMonth() + 18) + this.DisableDate = this.disabledDates(to_date,from_date) + } + }) + } + disabledDates(to_date,From_date): Date[] { + const start = startOfYear(new Date(to_date)); + const end = endOfYear(new Date(From_date)); + const disabledDates: Date[] = []; + + for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { + if (!this.isDateEnabled(new Date(d))) { + disabledDates.push(new Date(d)); + } + } + + return disabledDates; + } + + isDateEnabled(date: Date): boolean { + return this.enabledDates.some(enabledDate => + isSameDay(date, enabledDate) + ); + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Cancellation_contract_Search_Form.get('contract_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Cancellation_contract_Search_Form.get('contract_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + Reset(){ + this.Cancellation_contract_Search_Form.reset() + } + + SearchCancellationcontract(){ + if (this.Cancellation_contract_Search_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Cancellation_contract_Search_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Cancellation_contract_Search_Form.getRawValue(); + let ReqObj = { + extranet_contract_id:this.Edit_Id, + date_range:[], + contract_days:val.contract_days ? val.contract_days.join(','):'', + } + if(val.date_type == 'SPECIFICDATES'){ + const selectedFromDate = new Date(val.date[0]); + const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset); + const selectedToDate = new Date(val.date[1]); + const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset); + ReqObj.date_range.push({ + date_from:fromDate, + date_to:toDate, + }); + }else if(val.date_type == 'SEASON'){ + val.Season_Id.forEach(data => { + let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data); + if (matched_season_by_id) { + if (typeof (matched_season_by_id['date_range']) == 'string') { + let splited_date = matched_season_by_id.date_range.split(', '); + splited_date.forEach((z) => { + ReqObj.date_range.push({ + date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`), + date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`), + }); + }) + } + } + }) + } + this.apiserv.Post('/ExtranetRoomContract/GetAllCancellationPolicy',ReqObj).subscribe(resp=>{ + this.hasResult = true; + if(resp){ + this.Cancellation_contract_Save_Form = this.fb.group({ + Cancellation_Contract_Arr:this.fb.array([]) + }); + if(resp.data){ + this.GetAllContractResp = resp.data; + resp.data.sort((a,b)=>{ + let from_date = new Date(a.contract_date); + let to_date = new Date(b.contract_date) + return from_date.getTime() - to_date.getTime() + }); + let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray; + resp.data.forEach((contract_data,contract_ind)=>{ + let day = this.AllDaysArr.find(e=>e.Value == contract_data.contract_day); + if(contract_ind == 0 || contract_data.contract_date != resp.data[contract_ind -1 ]['contract_date']){ + contract_Arr.push( + this.fb.group({ + Cancel_Array: this.fb.array([]) + }) + ); + this.Validation_Message_Obj.push({ + cancel_type_select:false, + cancel_from_enter:false, + cancel_from_range:false, + cancel_to_enter:false, + cancel_to_range:false, + night_type_select:false, + charge_value_enter:false, + }) + } + let formGroup = contract_Arr.controls[contract_Arr.controls.length - 1]['controls']['Cancel_Array'] as FormArray + formGroup.push(this.fb.group({ + cancel_from: [contract_data.cancel_from,Validators.compose([Validators.required])], + cancel_to: [contract_data.cancel_to,Validators.compose([Validators.required])], + cancellation_type: [contract_data.cancellation_type,Validators.compose([Validators.required])], + contract_date:contract_data.contract_date, + contract_day:day ? day.Key : '', + extranet_cancellation_policy_id:contract_data.extranet_cancellation_policy_id, + contract_type:contract_data.contract_type, + // charge_value:contract_data.charge_value + })); + let formgroup = formGroup.controls[formGroup.length -1] as FormGroup; + if(contract_data.cancellation_type != 'FULLCHARGES'){ + formgroup.addControl(`charge_value`,this.fb.control(contract_data.charge_value, [Validators.required])); + } + if(contract_data.cancellation_type == 'NIGHTCOUNT'){ + formgroup.addControl(`night_type`,this.fb.control(contract_data.night_type, [Validators.required])); + } + if(contract_ind != 0 && contract_data.contract_date == resp.data[contract_ind -1 ]['contract_date']){ + formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')]) + formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')]) + } + }); + }else { + this.GetAllContractResp = undefined; + this.commonMasterSer.showMessage(resp.status,resp.message); + } + } + }) + } + private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value == 0) { + if (initialValue && parseInt(control.value) <= parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; + } + Checkcanceltype(event,i,j){ + let formcontrol = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j] as FormGroup; + if(event == 'NIGHTCOUNT'){ + formcontrol.addControl('night_type',new FormControl('',Validators.required)); + formcontrol.addControl('charge_value',new FormControl(0,Validators.required)); + } else if(event == 'FULLCHARGES'){ + formcontrol.removeControl('charge_value'); + formcontrol.removeControl('night_type'); + } else { + if(!formcontrol.controls['charge_value']){ + formcontrol.addControl('charge_value',new FormControl(0,Validators.required)); + } + formcontrol.removeControl('night_type'); + } + this.Find_Validation(i) + } + Find_Validation(i){ + let formcontrol = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls']; + this.Validation_Message_Obj[i] = { + cancel_type_select:false, + cancel_from_enter:false, + cancel_from_range:false, + cancel_to_enter:false, + cancel_to_range:false, + night_type_select:false, + charge_value_enter:false, + } + formcontrol.forEach(formgroup=>{ + if(formgroup.controls['cancellation_type'].hasError('required')){ + this.Validation_Message_Obj[i]['cancel_type_select'] = true; + } + if(formgroup.controls['cancel_from'].hasError('required')){ + this.Validation_Message_Obj[i]['cancel_from_enter'] = true; + } + if(formgroup.controls['cancel_from'].hasError('range')){ + this.Validation_Message_Obj[i]['cancel_from_range'] = true; + } + if(formgroup.controls['cancel_to'].hasError('required')){ + this.Validation_Message_Obj[i]['cancel_to_enter'] = true; + } + if(formgroup.controls['cancel_to'].hasError('range')){ + this.Validation_Message_Obj[i]['cancel_to_range'] = true; + } + if(formgroup.controls['night_type'] && formgroup.controls['night_type'].hasError('required')){ + this.Validation_Message_Obj[i]['night_type_select'] = true; + } + if(formgroup.controls['charge_value'] && formgroup.controls['charge_value'].hasError('required')){ + this.Validation_Message_Obj[i]['charge_value_enter'] = true; + } + }) + } + ChangeFeeMinValue(controlname,min,i,j) { + let min_amt = min; + if(this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j]){ + this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).clearValidators(); + this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).markAsUntouched(); + this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).setErrors(null); + this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][i]['controls']['Cancel_Array']['controls'][j].get(controlname).updateValueAndValidity(); + this.Find_Validation(i) + } + } + Copy_first_Block_Ui(){ + let formarray = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls']; + let copy_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr']['controls'][0]['controls']['Cancel_Array']['controls']; + formarray.forEach((fomrgroup,ind)=>{ + if(ind>0){ + fomrgroup.controls['Cancel_Array']['controls'].forEach((arr_data,arr_Ind)=>{ + let copy_group = copy_Arr[arr_Ind].getRawValue(); + arr_data.get('cancellation_type').setValue(copy_group.cancellation_type); + arr_data.get('cancel_from').setValue(copy_group.cancel_from); + arr_data.get('cancel_to').setValue(copy_group.cancel_to); + if(copy_group.cancellation_type != 'FULLCHARGES'){ + if(arr_data.controls['charge_value']){ + arr_data.get('charge_value').setValue(copy_group.charge_value); + }else{ + arr_data.addControl(`charge_value`,this.fb.control(copy_group.charge_value, [Validators.required])); + } + }else if(copy_group.cancellation_type == 'FULLCHARGES'){ + arr_data.removeControl('charge_value'); + } + if(copy_group.cancellation_type == 'NIGHTCOUNT'){ + if(arr_data.controls['night_type']){ + arr_data.get('night_type').setValue(copy_group.night_type); + }else{ + arr_data.addControl(`night_type`,this.fb.control(copy_group.night_type, [Validators.required])); + } + }else { + arr_data.removeControl('night_type'); + } + arr_data.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(fomrgroup.controls[arr_Ind -1 ]?parseInt(fomrgroup.controls[arr_Ind -1].get('cancel_to').value):'')]) + arr_data.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(arr_data?parseInt(arr_data.get('cancel_from').value):'')]) + }) + } + }) + } + Save(){ + if (this.Cancellation_contract_Save_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Cancellation_contract_Save_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'].getRawValue(); + let reqObjArr = []; + val.forEach(cancellationcontract=>{ + cancellationcontract.Cancel_Array.forEach(cancellation_data=>{ + reqObjArr.push({ + extranet_cancellation_policy_id : cancellation_data.extranet_cancellation_policy_id, + extranet_contract_id : this.Edit_Id, + contract_date : cancellation_data.contract_date, + contract_day : cancellation_data.contract_day, + contract_type : cancellation_data.contract_type, + cancel_from : cancellation_data.cancel_from, + cancel_to : cancellation_data.cancel_to, + cancellation_type : cancellation_data.cancellation_type, + }); + if(cancellation_data.night_type)reqObjArr[reqObjArr.length - 1]['night_type'] = cancellation_data.night_type; + if(cancellation_data.charge_value)reqObjArr[reqObjArr.length - 1]['charge_value'] = parseInt(cancellation_data.charge_value); + }) + }); + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetCancellationPolicy',reqObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + AddCancellationArr(i,j){ + let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray; + let formGroup = contract_Arr.controls[i]['controls']['Cancel_Array'] as FormArray + formGroup.push(this.fb.group({ + cancel_from: ['',Validators.compose([Validators.required])], + cancel_to: ['',Validators.compose([Validators.required])], + cancellation_type: ['',Validators.compose([Validators.required])], + contract_date:formGroup.controls[0].get('contract_date').value, + contract_day:formGroup.controls[0].get('contract_day').value, + extranet_cancellation_policy_id:'', + contract_type:'', + // charge_value:contract_data.charge_value + })); + let formgroup = formGroup.controls[formGroup.length -1] as FormGroup; + // if(contract_data.cancellation_type != 'FULLCHARGES'){ + // formgroup.addControl(`charge_value`,this.fb.control(contract_data.charge_value, [Validators.required])); + // } + // if(contract_data.cancellation_type == 'NIGHTCOUNT'){ + // formgroup.addControl(`night_type`,this.fb.control(contract_data.night_type, [Validators.required])); + // } + if(formGroup.controls[j].get('cancel_from').value && formGroup.controls[j].get('cancel_to').value){ + formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')]) + formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')]) + } + } + RemoveCancellationArr(i,j){ + let contract_Arr = this.Cancellation_contract_Save_Form.controls['Cancellation_Contract_Arr'] as FormArray; + let formGroup = contract_Arr.controls[i]['controls']['Cancel_Array'] as FormArray; + formGroup.removeAt(j); + this.Find_Validation(i); + let formgroup = formGroup.controls[j] as FormGroup; + if(formGroup.controls[j-1]?.get('cancel_from').value && formGroup.controls[j-1]?.get('cancel_to').value || j==0){ + formgroup.get('cancel_from').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -2]?parseInt(formGroup.controls[formGroup.length -2].get('cancel_to').value):'')]) + formgroup.get('cancel_to').addValidators([Validators.required,this.AmountRangeValidation(formGroup.controls[formGroup.length -1]?parseInt(formGroup.controls[formGroup.length -1].get('cancel_from').value):'')]) + formgroup.updateValueAndValidity(); + } + } + + ShowDateTypeFields(event){ + if(event == 'SPECIFICDATES'){ + this.Cancellation_contract_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()]))); + this.Cancellation_contract_Search_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Cancellation_contract_Search_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Cancellation_contract_Search_Form.removeControl('date'); + }else { + this.Cancellation_contract_Search_Form.removeControl('Season_Id'); + this.Cancellation_contract_Search_Form.removeControl('date'); + } + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.AllSeason = res.data; + } + }) + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.module.ts new file mode 100644 index 0000000..bda50ef --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-cancellation/hotel-update-cancellation.module.ts @@ -0,0 +1,54 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateCancellationComponent } from './hotel-update-cancellation.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; + +const routes: Routes = [ + { + path: 'UpdateCancellationPolicy/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelUpdateCancellationComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateCancellationComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + + ], + exports:[ + HotelUpdateCancellationComponent + ] +}) +export class HotelUpdateCancellationModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.html new file mode 100644 index 0000000..ca46bbb --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.html @@ -0,0 +1,330 @@ + +
    +
    +
    +

    Update Child Rate

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    +
    +
    + +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + Please + select Season +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Child Age Range

    +
    + +
    +
    + +
    + {{item.from + ' to ' + item.to}} +
    + Please + select child age range +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Child Pricing

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + 1 Child + +
    +
    +
    + 2 Child + +
    +
    +
    + 3 Child + +
    +
    +
    + 4 Child + +
    +
    +
    + 5 Child + +
    +
    +
    + 6 Child + +
    +
    + {{date_wise_control.get('contract_date').value ? (date_wise_control.get('contract_date').value | date: "dd MMM YYYY") : '' }} + + {{date_wise_control.get('contract_day').value}} + + + + + + + + + + + + +
    No data found
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.ts new file mode 100644 index 0000000..911342e --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.component.ts @@ -0,0 +1,308 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'hotel-update-child', + templateUrl: './hotel-update-child.component.html', +}) +export class HotelUpdateChildComponent implements OnInit { + Extranet_Hotel_Id; + Edit_Id; + Range_Data; + GetAllContractResp; + GetAllData; + AllSeason; + Defaultdate = new Date(); + selectedDate: Date | null = null; + DisableDate; + selectAll = ['Select All']; + hasResult = false; + enabledDates: Date[] = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Child_contract_Search_Form:FormGroup; + Child_contract_Save_Form:FormGroup; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Child_contract_Search_Form = this.fb.group({ + room_Name:'', + rate_Plan:'', + meal_Plan:'', + currency:'', + contract_days:'', + sequence:this.validserv.required, + date_type:this.validserv.required, + }) + this.GetAllSeason(); + this.GetById(); + // this.disabledDates(); + } + + GetById(){ + this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + // this.SetRoomdata(res.data); + let dates_range_arr = res.data['contract_dates'] ? JSON.parse(res.data.contract_dates) : []; + this.Child_contract_Search_Form.get('room_Name').setValue(res.data.room_name); + this.Child_contract_Search_Form.get('rate_Plan').setValue(res.data.rate_plan_name); + this.Child_contract_Search_Form.get('meal_Plan').setValue(res.data.meal_plan_name); + this.Child_contract_Search_Form.get('currency').setValue(res.data.currency_code); + this.GetAllData = res.data; + this.Range_Data = res.data.age_range ? JSON.parse(res.data.age_range) : []; + // this.GetAllData['max_adult_occupancy'] = 3; + dates_range_arr.forEach(date_range=>{ + const startDate = parseISO(date_range.date_from); + const endDate = parseISO(date_range.date_to); + + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + this.enabledDates.push(d); + } + }); + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + for(let i=0;i= new Date().getTime()){ + this.Defaultdate = new Date(this.enabledDates[i]); + break; + } + if(this.enabledDates.length -1 == i){ + this.Defaultdate = new Date(this.enabledDates[i]); + } + } + let to_date = new Date(this.enabledDates[0]); + to_date.setMonth(to_date.getMonth()-12) + let from_date = new Date(this.enabledDates[0]); + from_date.setMonth(from_date.getMonth() + 18) + this.DisableDate = this.disabledDates(to_date,from_date) + } + }) + } + disabledDates(to_date,From_date): Date[] { + const start = startOfYear(new Date(to_date)); + const end = endOfYear(new Date(From_date)); + const disabledDates: Date[] = []; + + for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { + if (!this.isDateEnabled(new Date(d))) { + disabledDates.push(new Date(d)); + } + } + + return disabledDates; + } + + isDateEnabled(date: Date): boolean { + return this.enabledDates.some(enabledDate => + isSameDay(date, enabledDate) + ); + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + SearchChildcontract(){ + if (this.Child_contract_Search_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Child_contract_Search_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Child_contract_Search_Form.getRawValue(); + let ReqObj = { + extranet_contract_id:this.Edit_Id, + date_range:[], + contract_days:val.contract_days ? val.contract_days.join(','):'', + sequence:val.sequence ? parseInt(val.sequence):0, + } + if(val.date_type == 'SPECIFICDATES'){ + const selectedFromDate = new Date(val.date[0]); + const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset); + const selectedToDate = new Date(val.date[1]); + const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset); + ReqObj.date_range.push({ + date_from:fromDate, + date_to:toDate, + }); + }else if(val.date_type == 'SEASON'){ + val.Season_Id.forEach(data => { + let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data); + if (matched_season_by_id) { + if (typeof (matched_season_by_id['date_range']) == 'string') { + let splited_date = matched_season_by_id.date_range.split(', '); + splited_date.forEach((z) => { + ReqObj.date_range.push({ + date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`), + date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`), + }); + }) + } + } + }) + } + this.apiserv.Post('/ExtranetRoomContract/GetAllChildRateContract',ReqObj).subscribe(resp=>{ + this.hasResult = true; + if(resp){ + this.GetAllContractResp = resp.data; + this.Child_contract_Save_Form = this.fb.group({ + Copy_Group:this.fb.group({}), + Child_Contract_Arr:this.fb.array([]) + }); + let contract_group = this.Child_contract_Save_Form.controls['Copy_Group'] as FormGroup; + for(let i=1;i<=this.GetAllData['max_child_occupancy'];i++){ + contract_group.addControl(`child_${i}`,new FormControl('')); + } + if(resp.data){ + resp.data.sort((a,b)=>{ + let from_date = new Date(a.contract_date); + let to_date = new Date(b.contract_date) + return from_date.getTime() - to_date.getTime() + }) + resp.data.forEach((contractc_data,ind)=>{ + let formArray = this.Child_contract_Save_Form.controls['Child_Contract_Arr'] as FormArray; + let day = this.AllDaysArr.find(e=>e.Value == contractc_data.contract_day) + formArray.push(this.fb.group({ + contract_date:contractc_data.contract_date, + contract_day:day ? day.Key : '', + extranet_contract_rate_id:contractc_data.extranet_contract_rate_id, + sequence:val.sequence, + })); + for(let i=1;i<=this.GetAllData['max_child_occupancy'];i++){ + let formgroup = formArray.controls[ind] as FormGroup; + formgroup.addControl(`child_${i}`,new FormControl(contractc_data[`child_${i}`])); + } + }) + }else { + this.commonMasterSer.showMessage(resp.status,resp.message); + } + } + }) + } + copycolumn(colname,controlval?){ + let value = controlval ? controlval : this.Child_contract_Save_Form.controls['Child_Contract_Arr']['controls'][0].get(colname).value; + if(controlval === false){ + value = false + } + if(this.GetAllContractResp && this.GetAllContractResp.length > 0){ + for(let i = 0;i { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Child_contract_Save_Form.controls['Child_Contract_Arr'].getRawValue(); + let reqObjArr = []; + val.forEach(childcontract=>{ + reqObjArr.push({ + extranet_contract_rate_id : childcontract.extranet_contract_rate_id, + extranet_contract_id : this.Edit_Id, + contract_date : childcontract.contract_date, + contract_day : childcontract.contract_day, + child_1 : childcontract.child_1 ? parseFloat(childcontract.child_1) : 0, + child_2 : childcontract.child_2 ? parseFloat(childcontract.child_2) : 0, + child_3 : childcontract.child_3 ? parseFloat(childcontract.child_3) : 0, + child_4 : childcontract.child_4 ? parseFloat(childcontract.child_4) : 0, + child_5 : childcontract.child_5 ? parseFloat(childcontract.child_5) : 0, + child_6 : childcontract.child_6 ? parseFloat(childcontract.child_6) : 0, + }) + }); + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetChildRate',reqObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + Reset(){ + this.Child_contract_Search_Form.reset(); + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Child_contract_Search_Form.get('contract_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Child_contract_Search_Form.get('contract_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + + ShowDateTypeFields(event){ + if(event == 'SPECIFICDATES'){ + this.Child_contract_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()]))); + this.Child_contract_Search_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Child_contract_Search_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Child_contract_Search_Form.removeControl('date'); + }else { + this.Child_contract_Search_Form.removeControl('Season_Id'); + this.Child_contract_Search_Form.removeControl('date'); + } + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.AllSeason = res.data; + } + }) + } +} + diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.module.ts new file mode 100644 index 0000000..d978efd --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-child/hotel-update-child.module.ts @@ -0,0 +1,56 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateChildComponent } from './hotel-update-child.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { CalendarModule } from 'primeng/calendar'; +import { Routes, RouterModule } from '@angular/router'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'UpdateChildRate/:Hotel_Eaxtranet_Id/:RuleId', + component:HotelUpdateChildComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateChildComponent, + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + TooltipModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + + ], + exports:[ + HotelUpdateChildComponent + ] +}) +export class HotelUpdateChildModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.html new file mode 100644 index 0000000..af0047c --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.html @@ -0,0 +1,51 @@ + +
    +
    +
    +

    Update Meal Add-On

    +
    +
    +
    +
    +
    +
    + Meal Add On +
    +
    +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + {{data.addon_name}} +
    + Please + select meals +
    +
    +
    +
    +
    + +
    +
    diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.ts new file mode 100644 index 0000000..96d893f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.component.ts @@ -0,0 +1,83 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'hotel-update-meal-add-on', + templateUrl: './hotel-update-meal-add-on.component.html', +}) +export class HotelUpdateMealAddOnComponent implements OnInit { + + Extranet_Hotel_Id; + Edit_Id; + AllMeal; + MealUpdateForm:FormGroup; + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.MealUpdateForm = this.fb.group({ + is_meal_addon_applicable:false + }) + this.GetAllMeal(); + this.GetById(); + } + GetAllMeal(){ + this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMealAddonByOrg/'+ this.Extranet_Hotel_Id).subscribe(resp=>{ + if(resp && resp.data){ + this.AllMeal = resp.data; + } + }) + } + MealHideShow(check){ + if(check){ + this.MealUpdateForm.addControl('extranet_meal_addon_id',new FormControl('',Validators.required)) + }else { + this.MealUpdateForm.removeControl('extranet_meal_addon_id'); + } + } + GetById(){ + this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + this.MealUpdateForm.get('is_meal_addon_applicable').setValue(res.data.is_meal_addon_applicable); + if(res.data.is_meal_addon_applicable){ + this.MealHideShow(res.data.is_meal_addon_applicable); + this.MealUpdateForm.get('extranet_meal_addon_id').setValue((res.data.extranet_meal_addon_id.split(','))); + + } + } + }) + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + Save(){ + if (this.MealUpdateForm.status == "INVALID") { + this.validserv.showValidationsMsg(this.MealUpdateForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.MealUpdateForm.getRawValue(); + let reqObj = { + extranet_contract_id : this.Edit_Id, + is_meal_addon_applicable : val.is_meal_addon_applicable, + extranet_meal_addon_id : val.extranet_meal_addon_id ? val.extranet_meal_addon_id.join(',') : '', + } + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetMealAddOn',reqObj).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.module.ts new file mode 100644 index 0000000..b7818e1 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-meal-add-on/hotel-update-meal-add-on.module.ts @@ -0,0 +1,54 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateMealAddOnComponent } from './hotel-update-meal-add-on.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; + +const routes: Routes = [ + { + path: 'UpdateMealAddOn/:Hotel_Eaxtranet_Id/:RuleId', + component: HotelUpdateMealAddOnComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateMealAddOnComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + + ], + exports:[ + HotelUpdateMealAddOnComponent + ] +}) +export class HotelUpdateMealAddOnModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.html b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.html new file mode 100644 index 0000000..9a88aee --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.html @@ -0,0 +1,186 @@ + +
    +
    +
    +

    Update Nationality

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select nationality type +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select nationality applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select nationality +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select residence type +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select residence applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select residence +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.ts new file mode 100644 index 0000000..d0ac568 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.component.ts @@ -0,0 +1,139 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'hotel-update-nationality', + templateUrl: './hotel-update-nationality.component.html', +}) +export class HotelUpdateNationalityComponent implements OnInit { + + Extranet_Hotel_Id; + Edit_Id; + NationalityForm:FormGroup; + ddLoader = { + Country:false, + Residence:false, + }; + CountryList; + timer; + Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.NationalityForm = this.fb.group({ + nationality_type:'', + nationality_applicable_type:'', + residence_type:'', + residence_applicable_type:'' + }); + this.GetById(); + } + GetById(){ + this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + + this.NationalityForm.get('nationality_type').setValue(res.data.nationality_type); + this.NationalityForm.get('nationality_applicable_type').setValue(res.data.nationality_applicable_type); + if(res.data.nationality_applicable_type == 'SPECIFIC'){ + this.NationalityShowhide(res.data.nationality_applicable_type); + this.NationalityForm.get('nationality').setValue((res.data.nationality.split(','))); + this.CountryList = res.data.country ? JSON.parse(res.data.country) : []; + } + this.NationalityForm.get('residence_type').setValue(res.data.residence_type); + this.NationalityForm.get('residence_applicable_type').setValue(res.data.residence_applicable_type); + if(res.data.residence_applicable_type == 'SPECIFIC'){ + this.ResidenceShowhide(res.data.residence_applicable_type); + this.NationalityForm.get('residence').setValue((res.data.residence.split(','))); + this.CountryList = res.data.country ? JSON.parse(res.data.country) : []; + } + } + }) + } + NationalityShowhide(event){ + if(event == 'SPECIFIC'){ + this.NationalityForm.addControl('nationality',new FormControl('',Validators.required)) + }else{ + this.NationalityForm.removeControl('nationality'); + } + } + NationalityTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Nationality_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.NationalityForm.controls['nationality_applicable_type'].value == 'ALL'){ + this.NationalityForm.get('nationality_applicable_type').setValue(''); + } + } + } + getCountryList(event,name) { + if (event.value.length >= 2) { + this.ddLoader[name] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader[name] = false; + } + }); + }, 500); + } + } + Save(){ + if (this.NationalityForm.status == "INVALID") { + this.validserv.showValidationsMsg(this.NationalityForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.NationalityForm.getRawValue(); + let reqObj = { + extranet_contract_id : this.Edit_Id, + nationality_type : val.nationality_type ? val.nationality_type : '', + nationality_applicable_type : val.nationality_applicable_type ? val.nationality_applicable_type : '', + nationality : val.nationality ? val.nationality.join(',') : '', + residence_type:val.residence_type, + residence_applicable_type:val.residence_applicable_type, + residence:val.residence_applicable_type == 'SPECIFIC' ? val.residence.join(',') : '', + } + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetNationality',reqObj).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + ResidenceTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Residence_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.NationalityForm.controls['residence_applicable_type'].value == 'ALL'){ + this.NationalityForm.get('residence_applicable_type').setValue(''); + } + } + } + ResidenceShowhide(event){ + if(event == 'SPECIFIC'){ + this.NationalityForm.addControl('residence',new FormControl('',Validators.required)) + }else{ + this.NationalityForm.removeControl('residence'); + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.module.ts b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.module.ts new file mode 100644 index 0000000..74b5e92 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/hotel-update-nationality/hotel-update-nationality.module.ts @@ -0,0 +1,54 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HotelUpdateNationalityComponent } from './hotel-update-nationality.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { Routes, RouterModule } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; + +const routes: Routes = [ + { + path: 'UpdateNationality/:Hotel_Eaxtranet_Id/:RuleId', + component: HotelUpdateNationalityComponent, + }, +] + +@NgModule({ + declarations: [ + HotelUpdateNationalityComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + RouterModule.forChild(routes), + + ], + exports:[ + HotelUpdateNationalityComponent + ] +}) +export class HotelUpdateNationalityModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.html b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.html new file mode 100644 index 0000000..056f721 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.html @@ -0,0 +1,218 @@ + +
    +
    +
    +
    +

    Add Minimum Stay

    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + {{item}} + {{item}} + {{data.room_name + + (data.room_view_name ? ', ' : '') + data.room_view_name}} +
    + Please + select room name +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    + +
    +
    + +
    +
    +
    + + + Please select date greater than from previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + {{data.season_name}} +
    + + info + + Please + select Season +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Allocation Days

    +
    + +
    +
    +
    + {{item}} + {{item}} +
    + Please + select applicable days +
    +
    +
    +
    + + + Please enter minimum stay +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    {{item.season_name}}
    +
    +

    {{date}}

    +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.ts b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.ts new file mode 100644 index 0000000..bf04b91 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-add/minimum-stay-add.component.ts @@ -0,0 +1,328 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, FormArray, FormControl, ValidatorFn, AbstractControl } from '@angular/forms'; +import { Router, ActivatedRoute } from '@angular/router'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import * as moment from 'moment'; +import { forkJoin } from 'rxjs'; +import { API } from 'src/app/core/services/api.service'; +import { BreakpointsService } from 'src/app/core/services/breakpoints.services'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; + + +@Component({ + selector: 'app-minimum-stay-add', + templateUrl: './minimum-stay-add.component.html', +}) +export class MinimumStayAddComponent implements OnInit{ + + Extranet_Hotel_Id; + Edit_Id; + IsMobile; + SelectAllRoom = []; + ClearAllRoom = []; + AllRoomsData; + displayPosition: boolean; + position: string; + Season_List = []; + AllSeason; + MinDate = new Date(); + MinStayForm: FormGroup; + AllDaysArr = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + SelectAllVal = ["Select All"]; + DaysArrValue = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + SelectAll=["Select All"]; + + constructor( + public activateRoute:ActivatedRoute, + private router:Router, + private hotelmanageserv:ManageHotelService, + private fb:FormBuilder, + public validserv:ValidationService, + private apiserv:API, + public brkpointsrv:BreakpointsService, + private commonMasterSer:CommonFunctionService + ) {} + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.InitForm(); + this.getAllData(); + this.IsMobile = this.brkpointsrv.IsMobile.getValue(); + + } + + showPositionDialog(position) { + this.position = position; + this.displayPosition = true; + }; + + InitForm(){ + this.MinStayForm = this.fb.group({ + extranet_room_min_stay_id: '', + extranet_room_id: this.validserv.required, + date_type:this.validserv.required, + ApplicableDays:this.fb.array([ + this.fb.group({ + applicable_days:this.validserv.required, + min_stay:this.validserv.required, + extranet_room_min_stay_id:'' + }) + ]) + }) + } + + getAllData(){ + forkJoin( + this.GetAllRooms(), + this.GetAllSeason() + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllRoomsData = res[0] ? res[0].data : []; + if(res[0].data){ + this.SelectAllRoom = ['Select All']; + } + this.AllSeason = res[1].data ? res[1].data : []; + } + }); + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj) + } + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj) + } + + SeasonDataAddRemove(){ + this.Season_List = []; + let selected_season = this.MinStayForm.controls['Season_Id'].value; + selected_season.forEach(data=>{ + let matched_season_by_id = this.AllSeason.find(e=>e.extranet_season_id == data); + if(matched_season_by_id){ + if(typeof(matched_season_by_id['date_range']) == 'string'){ + matched_season_by_id['date_range'] = matched_season_by_id.date_range.split(', '); + matched_season_by_id['date_range'].forEach((z,i)=>{ + matched_season_by_id['date_range'][i] = moment(z.split(' - ')[0]).format('DD MMM YYYY') + ' to ' + moment(z.split(' - ')[1]).format('DD MMM YYYY') + }) + } + this.Season_List.push(matched_season_by_id); + console.log(this.Season_List) + } + }) + } + + backClick(){ + this.hotelmanageserv.Active_tab = 'MinimumStay'; + this.router.navigateByUrl("/Services/Hotel/HotelManage/" + this.Extranet_Hotel_Id); + } + ShowDateTypeFields(event){ + this.Season_List = []; + if(event == 'SPECIFICDATES'){ + this.MinStayForm.addControl('ContractDatesArr',new FormArray([this.fb.group({ + date:['', Validators.compose([Validators.required, this.dateValidation(new Date())])], + })])); + this.MinStayForm.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.MinStayForm.addControl('Season_Id',new FormControl('',Validators.required)) + this.MinStayForm.removeControl('ContractDatesArr'); + }else { + this.MinStayForm.removeControl('Season_Id'); + this.MinStayForm.removeControl('ContractDatesArr'); + } + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (toDate && control.value.length <= 1 || control.value[0] <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.MinStayForm.controls['ContractDatesArr'] as FormArray; + formArray.removeAt(index); + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if (formArray.length > 0) { + if(index > 0){ + let formdate = formArray.controls[index - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + if (formArray.controls.length >= (index + 1)) { + formArray.controls[index].get("date").clearValidators(); + formArray.controls[index].get("date").setErrors(null); + formArray.controls[index].get("date").addValidators([Validators.required,this.dateValidation(currentDate)]); + // formArray.controls[index].get("date").markAsTouched(); + formArray.controls[index].get("date").updateValueAndValidity(); + // formArray.controls[index].get("date").markAsTouched(); + } + } + } + addDate() { + let formArray = this.MinStayForm.controls['ContractDatesArr'] as FormArray; + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if(formArray.length > 0){ + if (formArray.length > 0) { + let formdate = formArray.controls[formArray.length - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + formArray.push(this.fb.group({ + extranet_season_detail_id:'', + date: ['', Validators.compose([ + Validators.required, + this.dateValidation(currentDate) + ])] + })); + } + } + CloseCalender(element, index) { + let formArray = this.MinStayForm.controls['ContractDatesArr']['controls']; + if (element.value[0] && element.value[1]) { + element.overlayVisible = false; + element.datepickerClick = true; + if (formArray.length >= (index + 2)) { + formArray[index + 1].get("date").clearValidators(); + formArray[index + 1].get("date").setErrors(null); + formArray[index + 1].get("date").addValidators([Validators.required,this.dateValidation(element.value[1])]); + formArray[index + 1].get("date").markAsTouched(); + formArray[index + 1].get("date").updateValueAndValidity(); + formArray[index + 1].get("date").markAsTouched(); + } + } + } + ChangeinWeekDays(i?,event?){ + let selected_days_by_room = []; + let formdata = this.MinStayForm.controls['ApplicableDays'].value; + if(event?.includes('Select All')){ + formdata[i].applicable_days.splice(formdata[i].applicable_days.indexOf('Select All'), 1); + this.DaysArrValue.forEach(days_val=>{ + formdata[i].applicable_days.push(days_val); + }) + this.MinStayForm.controls['ApplicableDays']['controls'][i]['controls']['applicable_days'].setValue(formdata[i].applicable_days); + } + formdata.forEach(e=>{ + if(e.applicable_days && e.applicable_days.length > 0){ + e.applicable_days.forEach(days=>{ + selected_days_by_room.push(days); + }) + } + }) + this.DaysArrValue = this.AllDaysArr.filter(item => !selected_days_by_room.includes(item)); + if(this.DaysArrValue.length == 0){ + this.SelectAllVal = [] + }else { + this.SelectAllVal = this.SelectAll; + } + } + + AddAllocationDays(){ + let formArray = this.MinStayForm.controls['ApplicableDays'] as FormArray; + formArray.push(this.fb.group({ + applicable_days:this.validserv.required, + min_stay:this.validserv.required, + extranet_room_min_stay_id:'' + })); + } + RemoveAllocation(i){ + let formArray = this.MinStayForm.controls['ApplicableDays'] as FormArray; + formArray.removeAt(i); + this.ChangeinWeekDays(); + } + Save(){ + if (this.MinStayForm.status == "VALID") { + let val = this.MinStayForm.getRawValue(); + let PostObj = { + extranet_room_id:val.extranet_room_id ? val.extranet_room_id.join(',') : '', + extranet_hotel_id:this.Extranet_Hotel_Id, + date_ranges:'', + extranet_room_min_stay:[] + }; + if(val.date_type == 'SPECIFICDATES'){ + let date_Arr = []; + val.ContractDatesArr.forEach(data=>{ + date_Arr.push({ + date_from: moment(data.date[0]).format('YYYY-MM-DD'), + date_to: moment(data.date[1]).format('YYYY-MM-DD'), + }) + }); + PostObj['date_ranges'] = JSON.stringify(date_Arr); + } + if(val.date_type == 'SEASON'){ + let date_Arr = []; + this.Season_List.forEach(data=>{ + data.date_range.forEach(season_date=>{ + date_Arr.push({ + date_from: moment(season_date.split(' to ')[0]).format('YYYY-MM-DD'), + date_to: moment(season_date.split(' to ')[1]).format('YYYY-MM-DD'), + }) + }) + }); + PostObj['date_ranges'] = JSON.stringify(date_Arr); + } + val.ApplicableDays.forEach(allocation_data=>{ + PostObj.extranet_room_min_stay.push({ + applicable_days:allocation_data.applicable_days ? allocation_data.applicable_days.join(',') : '', + min_stay:allocation_data.min_stay ? allocation_data.min_stay : "", + extranet_room_min_stay_id:allocation_data.extranet_room_min_stay_id ? allocation_data.extranet_room_min_stay_id : '', + }) + }); + + this.apiserv.Post('/ExtranetMinStay/SaveExtranetMinStay',PostObj).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.backClick() : ''; + } + }) + }else { + this.validserv.showValidationsMsg(this.MinStayForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } + } + + SelectAndRemoveAllRoom(){ + const contract_id = this.MinStayForm.get('extranet_room_id').value + if (contract_id && contract_id.length > 0 && (contract_id.includes('Select All') || contract_id.length == this.AllRoomsData.length) && !contract_id.includes('Clear All')) { + let room_id_List = [] + this.AllRoomsData.forEach(d=>{ + room_id_List.push(d.extranet_room_id) + }); + this.MinStayForm.get('extranet_room_id').setValue(room_id_List); + this.SelectAllRoom = []; + this.ClearAllRoom = ['Clear All']; + } else if (contract_id && contract_id.length > 0 && (contract_id.includes('Clear All'))){ + this.MinStayForm.get('extranet_room_id').setValue([]); + this.SelectAllRoom = ['Select All']; + this.ClearAllRoom = []; + } else { + this.SelectAllRoom = ['Select All']; + if(contract_id?.length > 0){ + this.ClearAllRoom = ['Clear All']; + } + } + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.html b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.html new file mode 100644 index 0000000..d9fa001 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.html @@ -0,0 +1,138 @@ +
    +
    +
    +

    Minimum Stay

    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + {{data.room_name + (data.room_view_name ? ', ' : '') + data.room_view_name}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Room ID + + + + Room Name + + + + Minimum Stay Date Range + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + {{data.extranet_room_id}} + {{data.room_name}} + {{item}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + +
    + + +
    + + + No data found + + +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.ts b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.ts new file mode 100644 index 0000000..8365577 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay-view/minimum-stay-view.component.ts @@ -0,0 +1,92 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'minimum-stay-view', + templateUrl: './minimum-stay-view.component.html', +}) +export class MinimumStayViewComponent implements OnInit{ + Extranet_Hotel_Id; + AllRoomsData; + Room_Id; + Result; + cols; + constructor( + public activateRoute:ActivatedRoute, + public apiserv:API, + public _commonService:CommonFunctionService, + public router:Router + ) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.GetAllRooms() + this.cols = [ + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'date_range_arr', header: 'Minimum Stay Date Range' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj).subscribe(res=>{ + this.AllRoomsData = res ? res.data : []; + }) + } + + Search(){ + let ReqObj = { + extranet_room_id:this.Room_Id ? this.Room_Id : '', + extranet_hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetMinStay/GetAllExtranetRoomMinStay',ReqObj).subscribe(res=>{ + if(res){ + this.Result = res.data ? res.data : []; + if(res.data){ + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['date_range_arr'] = e['date_ranges'] ? JSON.parse(e['date_ranges']) : []; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + + Edit(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditMinStay/${this.Extranet_Hotel_Id}/${Id}`); + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.html b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.html new file mode 100644 index 0000000..ba2e56c --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.html @@ -0,0 +1 @@ + diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.ts b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.ts new file mode 100644 index 0000000..148fab8 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'minimum-stay', + templateUrl: './minimum-stay.component.html', +}) +export class MinimumStayComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.module.ts b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.module.ts new file mode 100644 index 0000000..69361f3 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/minimum-stay.module.ts @@ -0,0 +1,56 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { MinimumStayAddComponent } from './minimum-stay-add/minimum-stay-add.component'; +import { MinimumStayViewComponent } from './minimum-stay-view/minimum-stay-view.component'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { InputTextModule } from 'primeng/inputtext'; +import { CalendarModule } from 'primeng/calendar'; +import { MinimumStayComponent } from './minimum-stay.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { DialogModule } from 'primeng/dialog'; +import { UpdateMinimumStayComponent } from './update-minimum-stay/update-minimum-stay.component'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'AddMinStay/:Hotel_Eaxtranet_Id', + component: MinimumStayAddComponent, + }, + { + path: 'EditMinStay/:Hotel_Eaxtranet_Id/:RuleId', + component:UpdateMinimumStayComponent, + }, +] + +@NgModule({ + declarations: [ + MinimumStayComponent, + MinimumStayViewComponent, + MinimumStayAddComponent, + UpdateMinimumStayComponent + ], + imports: [ + CommonModule, + NgSelectModule, + TableModule, + MatButtonModule, + ToolbarModule, + MatMenuModule, + FormsModule, + TooltipModule, + ReactiveFormsModule, + DialogModule, + InputTextModule, + CalendarModule, + RouterModule.forChild(routes), + ], + exports:[ + MinimumStayComponent + ] +}) +export class MinimumStayModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.html b/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.html new file mode 100644 index 0000000..08f231b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.html @@ -0,0 +1,208 @@ + +
    +
    +
    +

    Update Minimum Stay

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    +
    +
    + +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Season

    +
    + +
    +
    +
    + {{data.season_name}} +
    + Please + select Season +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    + +
    + {{item}} + {{item.Key}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Minimum Stay

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    Date
    +
    +
    Day
    +
    +
    + Min Stay + +
    +
    + {{date_wise_control.get('contract_date').value ? (date_wise_control.get('contract_date').value | date: "dd MMM YYYY") : '' }} + + {{date_wise_control.get('contract_day').value}} + + +
    No data found
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.ts b/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.ts new file mode 100644 index 0000000..b386a58 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/minimum-stay/update-minimum-stay/update-minimum-stay.component.ts @@ -0,0 +1,298 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { API } from 'src/app/core/services/api.service'; +import { isSameDay, startOfYear, endOfYear, addDays, parseISO } from 'date-fns'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; + +@Component({ + selector: 'app-update-minimum-stay', + templateUrl: './update-minimum-stay.component.html', +}) +export class UpdateMinimumStayComponent implements OnInit { + Extranet_Hotel_Id; + Edit_Id; + GetAllContractResp; + GetAllData; + Defaultdate = new Date(); + selectedDate: Date | null = null; + DisableDate; + selectAll = ['Select All']; + hasResult = false; + AllSeason; + enabledDates: Date[] = []; + AllDaysArr = [ + {Key:'Mon',Value:'Monday'}, + {Key:'Tue',Value:'Tuesday'}, + {Key:'Wed',Value:'Wednesday'}, + {Key:'Thu',Value:'Thursday'}, + {Key:'Fri',Value:'Friday'}, + {Key:'Sat',Value:'Saturday'}, + {Key:'Sun',Value:'Sunday'} + ]; + Minimum_stay_Search_Form:FormGroup; + Minimum_stay_Save_Form:FormGroup; + + constructor(private activateRoute:ActivatedRoute,private apiserv:API,public validserv:ValidationService,public fb:FormBuilder,public commonMasterSer:CommonFunctionService, + private hotelmanageserv:ManageHotelService,private router:Router) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Minimum_stay_Search_Form = this.fb.group({ + room_Name:'', + room_Id:'', + date_type:this.validserv.required, + contract_days:'' + }); + this.GetAllSeason(); + this.GetById(); + // this.disabledDates(); + } + + GetById(){ + this.apiserv.Get('/ExtranetMinStay/GetExtranetRoomMinStayById/'+ this.Edit_Id).subscribe(res=>{ + if(res && res.data){ + // this.SetRoomdata(res.data); + let dates_range_arr = res.data['date_ranges'] ? JSON.parse(res.data.date_ranges) : []; + this.Minimum_stay_Search_Form.get('room_Name').setValue(res.data.room_name); + this.Minimum_stay_Search_Form.get('room_Id').setValue(res.data.extranet_room_id); + this.GetAllData = res.data; + // this.GetAllData['max_adult_occupancy'] = 3; + dates_range_arr.forEach(date_range=>{ + const startDate = parseISO(date_range.date_from); + const endDate = parseISO(date_range.date_to); + + for (let d = startDate; d <= endDate; d = addDays(d, 1)) { + this.enabledDates.push(d); + } + }); + this.enabledDates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); + for(let i=0;i= new Date().getTime()){ + this.Defaultdate = new Date(this.enabledDates[i]); + break; + } + if(this.enabledDates.length -1 == i){ + this.Defaultdate = new Date(this.enabledDates[i]); + } + } + let to_date = new Date(this.enabledDates[0]); + to_date.setMonth(to_date.getMonth()-12) + let from_date = new Date(this.enabledDates[0]); + from_date.setMonth(from_date.getMonth() + 18) + this.DisableDate = this.disabledDates(to_date,from_date) + } + }) + } + disabledDates(to_date,From_date): Date[] { + const start = startOfYear(new Date(to_date)); + const end = endOfYear(new Date(From_date)); + const disabledDates: Date[] = []; + + for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { + if (!this.isDateEnabled(new Date(d))) { + disabledDates.push(new Date(d)); + } + } + + return disabledDates; + } + + isDateEnabled(date: Date): boolean { + return this.enabledDates.some(enabledDate => + isSameDay(date, enabledDate) + ); + } + BackButton(){ + this.hotelmanageserv.Active_tab = 'MinimumStay'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + SearchAdultcontract(){ + if (this.Minimum_stay_Search_Form.status == "INVALID") { + this.validserv.showValidationsMsg(this.Minimum_stay_Search_Form); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Minimum_stay_Search_Form.getRawValue(); + let ReqObj = { + extranet_room_id:val.room_Id, + date_range:[], + extranet_hotel_id:this.Extranet_Hotel_Id, + days:val.contract_days ? val.contract_days.join(','):'', + } + if(val.date_type == 'SPECIFICDATES'){ + const selectedFromDate = new Date(val.date[0]); + const fromuserTimezoneOffset = selectedFromDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const fromDate = new Date(selectedFromDate.getTime() - fromuserTimezoneOffset); + const selectedToDate = new Date(val.date[1]); + const toUserTimezoneOffset = selectedToDate.getTimezoneOffset() * 60000; // Convert minutes to milliseconds + const toDate = new Date(selectedToDate.getTime() - toUserTimezoneOffset); + ReqObj.date_range.push({ + date_from:fromDate, + date_to:toDate, + }); + }else if(val.date_type == 'SEASON'){ + val.Season_Id.forEach(data => { + let matched_season_by_id = this.AllSeason.find(e => e.extranet_season_id == data); + if (matched_season_by_id) { + if (typeof (matched_season_by_id['date_range']) == 'string') { + let splited_date = matched_season_by_id.date_range.split(', '); + splited_date.forEach((z) => { + ReqObj.date_range.push({ + date_from: new Date(`${z.split(' - ')[0]}T00:00:00.000Z`), + date_to:new Date(`${z.split(' - ')[1]}T00:00:00.000Z`), + }); + }) + } + } + }) + } + this.apiserv.Post('/ExtranetMinStay/GetUpdateMinStay',ReqObj).subscribe(resp=>{ + this.hasResult = true; + if(resp){ + this.GetAllContractResp = resp.data; + this.Minimum_stay_Save_Form = this.fb.group({ + Copy_Group:this.fb.group({ + min_stay:'', + }), + Adult_Contract_Arr:this.fb.array([]) + }); + let contract_group = this.Minimum_stay_Save_Form.controls['Copy_Group'] as FormGroup; + // for(let i=1;i<=this.GetAllData['max_adult_occupancy'];i++){ + // contract_group.addControl(`adult_${i}`,new FormControl('')); + // } + if(resp.data){ + resp.data.sort((a,b)=>{ + let from_date = new Date(a.contract_date); + let to_date = new Date(b.contract_date) + return from_date.getTime() - to_date.getTime() + }) + resp.data.forEach((contractc_data,ind)=>{ + let formArray = this.Minimum_stay_Save_Form.controls['Adult_Contract_Arr'] as FormArray; + let day = this.AllDaysArr.find(e=>e.Value == contractc_data.minstay_day) + formArray.push(this.fb.group({ + min_stay:this.fb.control(contractc_data.min_stay,this.validserv.required), + contract_date:contractc_data.date, + extranet_room_id:contractc_data.extranet_room_id, + contract_day:day ? day.Key : '', + extranet_contract_rate_id:contractc_data.extranet_room_min_stay_id, + })); + // for(let i=1;i<=this.GetAllData['max_adult_occupancy'];i++){ + // let formgroup = formArray.controls[ind] as FormGroup; + // formgroup.addControl(`adult_${i}`,new FormControl(contractc_data[`adult_${i}`])); + // } + }) + }else { + this.commonMasterSer.showMessage(resp.status,resp.message); + } + } + }) + } + copycolumn(colname,controlval?){ + let value = controlval ? controlval : this.Minimum_stay_Save_Form.controls['Adult_Contract_Arr']['controls'][0].get(colname).value; + if(this.GetAllContractResp && this.GetAllContractResp.length > 0){ + for(let i = 0;i { + this.validserv.scrollToError(); + }, 50); + return; + } + let val = this.Minimum_stay_Save_Form.controls['Adult_Contract_Arr'].getRawValue(); + let reqObjArr = []; + val.forEach(adultcontract=>{ + reqObjArr.push({ + extranet_room_min_stay_id : adultcontract.extranet_contract_rate_id, + extranet_room_id : adultcontract.extranet_room_id, + date : adultcontract.contract_date, + minstay_day : adultcontract.contract_day, + min_stay : adultcontract.min_stay ? adultcontract.min_stay :'' + }) + }); + this.apiserv.Post('/ExtranetMinStay/UpdateExtranetMinStay',reqObjArr).subscribe(resp=>{ + if(resp){ + this.commonMasterSer.showMessage(resp.status,resp.message); + resp.status ? this.BackButton() : ''; + } + }) + } + Reset(){ + this.Minimum_stay_Search_Form.reset(); + } + Check_day_type(){ + let daysArr = [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ]; + let value = this.Minimum_stay_Search_Form.get('contract_days').value; + if(value && value.length > 0 && (value.includes('Select All') || value.length == 7)){ + this.Minimum_stay_Search_Form.get('contract_days').setValue(daysArr); + this.selectAll = [] + }else { + this.selectAll = ['Select All'] + } + } + + ShowDateTypeFields(event){ + if(event == 'SPECIFICDATES'){ + this.Minimum_stay_Search_Form.addControl('date', new FormControl('', Validators.compose([Validators.required, this.dateValidation()]))); + this.Minimum_stay_Search_Form.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.Minimum_stay_Search_Form.addControl('Season_Id',new FormControl('',Validators.required)) + this.Minimum_stay_Search_Form.removeControl('date'); + }else { + this.Minimum_stay_Search_Form.removeControl('Season_Id'); + this.Minimum_stay_Search_Form.removeControl('date'); + } + } + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + } + return null; + }; + } + + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj).subscribe(res=>{ + if(res){ + this.AllSeason = res.data; + } + }) + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/overview/overview.component.html b/src/app/modules/services/hotel/hotel-manage/overview/overview.component.html new file mode 100644 index 0000000..8cb522a --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/overview/overview.component.html @@ -0,0 +1,1622 @@ +
    +
    +
    +

    Overview

    +
    +
    +
    +
    + Hotel Image +
    +

    {{Hotel_Details['hotel_name']}}

    +
    + star + star + star + star + star +
    +
    {{Hotel_Details['address']}}
    +
    +
    +
    +
    Inventory and Pricing Calendar
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + Select + {{data.room_name}}{{data.room_view ? (', ' + + data.room_view) : '' }} +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + Please select date range + + + Please select search rates date + + + Select a date range with a maximum span of 30 days + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    + + + + +
    +
    Rooms
    +
    +
    + {{Date | date : 'EEE'}} + {{Date | date : 'd'}} + {{Date | date : 'MMM'}} +
    +
    + + + + +
    + {{room_data.room_name}} +
    + +
    + + + + + + + + + + + + + + + + + + +
    +
    + Status +
    +
    +
    +
    +
    + {{status == 'STOPSALE' ? 'Sold Out' : ''}} +
    + + + + + + + +
    +
    +
    +
    + Allocation +
    +
    +
    + + +
    +
    + + +
    +
    + {{allocation.value}} +
    +
    +
    + Net Sold +
    +
    +
    + {{net_sold}} +
    +
    +
    + Available +
    +
    +
    + {{availability}} +
    +
    + + +
    + + + + + +
    +
    +
    + {{contrtact_det.contract_name}} ({{contrtact_det.rate_plan}}, + {{contrtact_det.meal_plan}}) ({{room_data.currency_code}}) +
    +
    + + + + Expand to update rates +
    +
    + + + + Collapse +
    +
    +
    + + + + +
    +
    + {{j+1}} Adult +
    +
    +
    + {{adult_rate_on_date}} +
    +
    + + +
    + Child Age Range: {{contrtact_det.child_age_range_1}} +
    + + + + + + + +
    +
    + {{j+1}} Child +
    +
    +
    + {{adult_rate_on_date}} +
    +
    + + +
    + Child Age Range: {{contrtact_det.child_age_range_2}} +
    + + + + + + + +
    +
    + {{j+1}} Child +
    +
    +
    + {{adult_rate_on_date}} +
    +
    + + + + + + + +
    +
    + No Data Found +
    +
    +
    +
    +
    Rooms
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Room Name + + + + Room View + + + + Max Adult Occupancy + + + + Max Child Occupancy + + + + Max Child Age + + + + Max Total Occupancy + + + + Extrabed Supported + + + + Free Child Allowed + + + + Room Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.room_name}} + {{data.room_view}} + {{data.max_adult_occupancy}} + {{data.max_child_occupancy}} + {{data.max_child_age}} + {{data.max_total_occupancy}} + {{data.is_extra_bed_supported}} + {{data.is_free_child}} + {{data.extranet_room_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + + + + No data found + + +
    +
    +
    +
    +
    +
    Season
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Season Name + + + + Date Range + + + + Season Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.season_name}} + {{item}} + {{data.extranet_season_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Room Contract
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Contract Status + + + + Contract Id + + + + Contract Name + + + + Room Id + + + + Room Name + + + + Rate Plan + + + + Meal Plan + + + + Nationality Type + + + + Nationality Applicability + + + + Nationality + + + + Date Range/Season + + + + Currency + + + + Meal Add On + + + + Meals + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + + Last updated + + + Action + + + + + + + {{data.status}} + + + {{data.extranet_contract_id}} + {{data.contract_name}} + {{data.extranet_room_id}} + {{data.room_name}} + {{data.rate_plan_name}} + {{data.meal_plan_name}} + {{data.nationality_type}} + {{data.nationality_applicable_type}} + {{data.nationality}} + {{item}} + {{data.currency_code}} + {{data.is_meal_addon_applicable}} + {{data.addon_name}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + {{data.last_updated}} + +
    + + + + + + + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Allocation
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Room ID + + + + Room Name + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + {{data.extranet_room_id}} + {{data.room_name}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Offers
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Offer Name + + + + Offer Type + + + + Room Name + + + + Combinable Offer + + + + Discount Code + + + + Offer days + + + + Offer Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.offer_name}} + {{data.offer_type}} + {{data.room_name}} + {{data.is_combinable_offer}} + {{data.discount_code}} + {{data.offer_days}} + {{data.extranet_offer_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Supplements
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Supplement Name + + + + Supplement Rate Type + + + + Room Name + + + + Supplement Type + + + + Supplement Dates + + + + Supplement Days + + + + Supplement Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.supplement_name}} + {{data.supplement_rate_type}} + {{data.room_name}} + {{data.supplement_type}} + {{item}} + {{data.supplement_days}} + {{data.extranet_supplement_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Meal Add-On
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Meal Add-On Name + + + + Meal Plan + + + + Currency + + + + Adult Rate + + + + Paid Child + + + + Meal Add-On Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.addon_name}} + {{data.meal_plan_name}} + {{data.currency}} + {{data.adult_rate}} + {{data.is_paid_child}} + {{data.extranet_meal_addon_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + + + No data found + + +
    +
    +
    +
    +
    +
    Block Dates
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Rule Name + + + + Block Date Type + + + + Dates + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.rule_name}} + {{data.block_date_type}} + {{item}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    Minimum Stay
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Room ID + + + + Room Name + + + + Minimum Stay Date Range + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + {{data.extranet_room_id}} + {{data.room_name}} + {{item}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + +
    + + + + +
    + + +
    + + + No data found + + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/overview/overview.component.ts b/src/app/modules/services/hotel/hotel-manage/overview/overview.component.ts new file mode 100644 index 0000000..2d760be --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/overview/overview.component.ts @@ -0,0 +1,1203 @@ +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; +import { OverViewData } from 'src/app/core/models/hotelService/OverViewData/RoomsOverView.model'; +@Component({ + selector: 'overview', + templateUrl: './overview.component.html', +}) +export class OverviewComponent implements OnInit { + + SeasonResult; + @ViewChild('tableContainer') tableContainer: ElementRef; + columnWidths: number[] = []; + Extranet_Hotel_Id; + Clone_Room_view; + Allocationcols; + AllocationResult; + timer; + cols; + BlockDateResult; + BlockDateCols; + OverViewDetail; + OverViewObj: OverViewData; + Clone_Room_data; + CloneRoomModal = false; + displayPosition = false; + AllRooms; + MealsResult; + RoomCol; + MinStayResult; + Contract_Results; + OffersResult; + OfferCols; + SupplementResult; + SupplementCols; + SeasonCols; + ContractCols; + MealCols; + Hotel_Details; + MinDate = new Date(); + OverviewForm: FormGroup; + constructor( + public activateRoute: ActivatedRoute, + public apiserv: API, + public _commonService: CommonFunctionService, + public router: Router, + private fb: FormBuilder, + public validserv: ValidationService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + //room data + this.RoomCol = [ + { field: 'room_name', header: 'Room Name' }, + { field: 'room_view', header: 'Room View' }, + { field: "max_adult_occupancy", header: 'Max Adult Occupancy' }, + { field: 'max_child_occupancy', header: 'Max Child Occupancy' }, + { field: 'max_child_age', header: 'Max Child Age' }, + { field: 'max_total_occupancy', header: 'Max Total Occupancy' }, + { field: 'is_extra_bed_supported', header: 'Extrabed Supported' }, + { field: 'is_free_child', header: 'Free Child Allowed' }, + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + //season data + this.SeasonCols = [ + { field: 'season_name', header: 'Season Name' }, + { field: 'date_range', header: 'Date Range' }, + { field: 'extranet_season_id', header: 'Season Id' }, + { field: 'updated_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + { field: 'status', header: 'Status' }, + ]; + //Contract data + this.ContractCols = [ + { field: 'extranet_contract_id', header: 'Contract Id' }, + { field: 'contract_name', header: 'Contract Name' }, + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'rate_plan_name', header: 'Rate Plan' }, + { field: 'meal_plan_name', header: 'Meal Plan' }, + { field: 'nationality_type', header: 'Nationality Type' }, + { field: 'nationality_applicable_type', header: 'Nationality Applicability' }, + { field: 'nationality', header: 'Nationality' }, + { field: 'date_range', header: 'Date Range/Season' }, + { field: 'currency_code', header: 'Currency' }, + { field: 'is_meal_addon_applicable', header: 'Meal Add On' }, + { field: 'addon_name', header: 'Meals' }, + { field: 'status', header: 'Contract Status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + { field: 'last_updated', header: 'Last Updated' }, + ]; + //Allocation Data + this.Allocationcols = [ + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'updated_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + //Offers data + this.OfferCols = [ + { field: 'offer_name', header: 'Offer Name' }, + { field: 'offer_type', header: 'Offer Type' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'is_combinable_offer', header: 'Combinable Offer' }, + { field: 'discount_code', header: 'Discount Code' }, + { field: 'offer_days', header: 'Offer days' }, + { field: 'status', header: 'Status' }, + { field: 'extranet_offer_id', header: 'Offer Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + //Supplement data + this.SupplementCols = [ + { field: 'supplement_name', header: 'Supplement Name' }, + { field: 'supplement_rate_type', header: 'Supplement Rate Type' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'supplement_type', header: 'Supplement Type' }, + { field: 'date_range_arr', header: 'supplement_dates' }, + { field: 'custom_days', header: 'Supplement days' }, + { field: 'extranet_supplement_id', header: 'Supplement Id' }, + { field: 'status', header: 'Status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' } + ]; + //Meals data + this.MealCols = [ + { field: 'addon_name', header: 'Meal Add-On Name' }, + { field: 'meal_plan_name', header: 'Meal Plan' }, + { field: 'currency', header: 'Currency' }, + { field: 'adult_rate', header: 'Adult Rate' }, + { field: 'currency', header: 'Currency' }, + { field: 'is_paid_child', header: 'Paid Child' }, + { field: 'status', header: 'Status' }, + { field: 'extranet_meal_addon_id', header: 'Meal Add-On Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + //Block Dates Data + this.BlockDateCols = [ + { field: 'rule_name', header: 'Rule Name' }, + { field: 'block_date_type', header: 'Block Date Type' }, + { field: 'Custom_from_date', header: 'Date From' }, + { field: 'Custom_to_date', header: 'Date To' }, + { field: 'status', header: 'status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + //Minimum Stay Data + this.cols = [ + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'date_range_arr', header: 'Minimum Stay Date Range' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_updated_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.Initform(); + this.GetAllData(); + } + GetAllData() { + forkJoin( + this.GetAllRooms(), + this.GetHotelDetails(this.Extranet_Hotel_Id), + this.SearchSeason(), + this.SearchContract(), + this.SearchAllocation(), + this.SearchOffers(), + this.SearchSupplement(), + this.SearchMeals(), + this.SearchBlockDate(), + this.SearchMinStay(), + this.GetOverViewData(), + ).subscribe(res => { + if (res && res.length > 0) { + // Rooms Data + this.AllRooms = res[0].data; + if (res[0]) { + this.AllRooms = res[0].data ? res[0].data : []; + if (res[0].data) { + this.AllRooms.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['is_extra_bed_supported'] = e.is_extra_bed_supported ? 'Yes' : 'No'; + e['is_free_child'] = e.is_free_child ? 'Yes' : 'No'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.AllRooms.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + // Hotel Data + this.Hotel_Details = res[1].data; + if (this.Hotel_Details) { + this.Hotel_Details['thumbnail_image'] = this.Hotel_Details['thumbnail_image'] ? JSON.parse(this.Hotel_Details['thumbnail_image']) : ''; + } + + //Season data + if (res[2]) { + this.SeasonResult = res[2].data ? res[2].data : []; + if (res[2].data) { + this.SeasonResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + }); + this.SeasonResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + //contract data + if (res[3]) { + this.Contract_Results = res[3].data ? res[3].data : []; + if (res[3].data) { + this.Contract_Results.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['nationality_type'] = this.getNationalityType(e['nationality_type']) ; + e['nationality_applicable_type'] = this.getNationalityApplicabilityType(e['nationality_applicable_type']) ; + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['contract_dates'] ? JSON.parse(e['contract_dates']) : []; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['date_range'] = e.date_range_arr.length > 0 ? e.date_range_arr.join(',') : ''; + }); + this.Contract_Results.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Allocation data + if (res[4]) { + this.AllocationResult = res[4].data ? res[4].data : []; + if (res[4].data) { + this.AllocationResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.AllocationResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Offers Data + if (res[5]) { + this.OffersResult = res[5].data ? res[5].data : []; + if (res[5].data) { + this.OffersResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['offer_type'] = this.getOfferType(e['offer_type']); + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.OffersResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Supplement Data + if (res[6]) { + this.SupplementResult = res[6].data ? res[6].data : []; + if (res[6].data) { + this.SupplementResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['supplement_rate_type'] = this.getSupplementRateType(e.supplement_rate_type); + e['supplement_type'] = this.getSupplementType(e.supplement_type); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['supplement_dates'] ? JSON.parse(e['supplement_dates']) : e['supplement_dates']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.from).format('DD MMM YYYY') + ' - ' + moment(data.to).format('DD MMM YYYY'); + }) + } + e['custom_days'] = e['supplement_days'] ? e['supplement_days'].split(',') : '' + }); + this.SupplementResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Meals Data + if (res[7]) { + this.MealsResult = res[7].data ? res[7].data : []; + if (res[7].data) { + this.MealsResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.MealsResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Block Date data + if (res[8]) { + this.BlockDateResult = res[8].data ? res[8].data : []; + if (res[8].data) { + this.BlockDateResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + e['Custom_created_on'] = this._commonService.convertDateWithTimeToShow(e.created_on); + e['block_date_type'] = e.block_date_type == 'CHECKINDATE' ? 'Check-in Date' : 'Check-out Date'; + }); + this.BlockDateResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //Minimum Stay + if(res[9]){ + this.MinStayResult = res[9].data ? res[9].data : []; + if(res[9].data){ + this.MinStayResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['date_range_arr'] = e['date_ranges'] ? JSON.parse(e['date_ranges']) : []; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + this.MinStayResult.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + + //OverviewData + if (res[10]) { + this.OverViewDetail = res[10].data; + this.GetSortedOverviewDetails(res[10].data); + } + } + }) + } + GetHotelDetails(Editid) { + if (Editid) + return this.apiserv.Get('/ExtranetOverview/GetHotelData/' + Editid) + else + return of(null) + }; + Initform() { + const startDate = new Date(); + const endDate = new Date(startDate); + endDate.setDate(startDate.getDate() + 29) + this.OverviewForm = this.fb.group({ + extranet_room_id: '', + date: new FormControl([startDate, endDate], [Validators.required, this.dateValidation()]) + }); + } + + // date validation + public dateValidation(): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (control.value.length == 2) { + const diffInTime = control.value[1].getTime() - control.value[0].getTime(); // Difference in milliseconds + const diffInDays = diffInTime / (1000 * 3600 * 24); + if (diffInDays >= 30) { + return { 'range': true }; + } + } + } + return null; + }; + } + + // scroll tab on click of button + // ngAfterViewInit() { + // this.calculateColumnWidths(); + // } + + calculateColumnWidths(scroll_side) { + const container = this.tableContainer.nativeElement; + const columns = container.querySelectorAll('th'); + this.columnWidths = Array.from(columns).map((col: HTMLElement) => col.offsetWidth); + if(scroll_side == 'right'){ + this.scrollTable(1); + }else if(scroll_side == 'left'){ + this.scrollTable(-1); + } + } + // GetAllContract(){ + // let obj = { + // extranet_hotel_id:this.Extranet_Hotel_Id + // } + // return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOfferAndSupplementContracts',obj) + // } + + + // scrollLeft() { + // this.scrollTable(-1); + // } + + // scrollRight() { + // this.scrollTable(1); + // } + + scrollTable(direction: number) { + const container = this.tableContainer.nativeElement; + const currentScroll = container.scrollLeft; + const columnIndex = this.findCurrentColumn(currentScroll); + + if (columnIndex !== -1) { + const scrollAmount = this.columnWidths[columnIndex] * direction; + container.scrollLeft += scrollAmount; + } + } + + findCurrentColumn(currentScroll: number): number { + let accumulatedWidth = 0; + for (let i = 0; i < this.columnWidths.length; i++) { + accumulatedWidth += this.columnWidths[i]; + if (accumulatedWidth > currentScroll) { + return i; + } + } + return -1; // In case something goes wrong + } + //OverView Data + GetOverViewData() { + // console.log(this.OverviewForm.getRawValue()); + let val = this.OverviewForm.getRawValue(); + let Obj = { + extranet_hotel_id: this.Extranet_Hotel_Id, + extranet_room_id: val.extranet_room_id ? val.extranet_room_id : '', + from_date: val.date ? moment(val.date[0]).format('YYYY-MM-DD') : '', + to_date: val.date ? moment(val.date[1]).format('YYYY-MM-DD') : '' + } + return this.apiserv.Post('/ExtranetOverview/GetOverView', Obj) + } + SearchOverview() { + if (this.OverviewForm.status == "INVALID") { + this.validserv.showValidationsMsg(this.OverviewForm); + return; + } + this.GetOverViewData().subscribe(res => { + if (res) { + this.OverViewDetail = res.data; + this.GetSortedOverviewDetails(this.OverViewDetail); + } + }) + } + Reset(){ + if(this.OverviewForm.get('extranet_room_id').value){ + this.OverviewForm.get('extranet_room_id').setValue(''); + this.SearchOverview(); + } + } + + GetSortedOverviewDetails(Overview_det) { + this.OverViewObj = undefined; + if (Overview_det) { + this.OverViewObj = { + Date: [], + RoomDetails: [] + } + // console.log(Overview_det) + let Unique_Date = [...new Set(Overview_det.map(item => item.overview_date))]; + const Unique_room_id = [...new Set(Overview_det.map(item => item.extranet_room_id))]; + Unique_Date.map((date: any, i) => { + Unique_Date[i] = new Date(date); + }) + Unique_Date.sort((a: any, b: any) => a - b); + if (Unique_Date.length > 0) { + Unique_room_id.forEach((room_id: any, room_ind) => { + let room_data = Overview_det.filter(e => { return e.extranet_room_id == room_id }) + const contract_names = [...new Set(room_data.map(item => item.contract_name))]; + // let room_data_list = + + let overview_data = { + room_name: room_data[0].room_name, + room_id: room_data[0].extranet_room_id, + currency_code: room_data[0].currency_code, + status: [], + allocation: [], + allocation_id:[], + net_sold: [], + availability: [], + RoomContractDetails: [] + } + // unique date and + contract_names.forEach((contract_data: any, contract_ind) => { + let contractDetails = { + contract_name: '', + aria_collapse: true, + rate_plan: '', + meal_plan: '', + child_age_range_1: '', + child_age_range_2: '', + min_stay: [], + ChildDataRange1: [], + ChildDataRange2: [], + AdultData: [] + } + let contract_details = Overview_det.find(e => { return (e.extranet_room_id == room_id && e.contract_name == contract_data) }) + contractDetails.contract_name = contract_details.contract_name; + contractDetails.rate_plan = contract_details.rate_plan_name ? contract_details.rate_plan_name : ''; + contractDetails.meal_plan = contract_details.meal_plan_name ? contract_details.meal_plan_name : ''; + contractDetails.child_age_range_1 = contract_details.child_age_range_1 ? contract_details.child_age_range_1 : ''; + contractDetails.child_age_range_2 = contract_details.child_age_range_2 ? contract_details.child_age_range_2 : ''; + for(let i=0;i { + let room_data_on_date = Overview_det.find(e => { return (e.extranet_room_id == room_id && date_data.getTime() == new Date(e.overview_date).getTime() && e.contract_name == contract_data) }) + if (room_ind == 0 && contract_ind == 0) this.OverViewObj.Date.push(date_data); + if(contract_ind == 0){ + let allocation_obj = { + id:`room${room_id}_allocation_${date_ind}`, + value:room_data_on_date ? room_data_on_date.allocation : '' + } + let available = room_data_on_date?.status == 'FREESALE' ? 'FREESALE' : room_data_on_date?.available; + overview_data.status.push(room_data_on_date ? room_data_on_date.status : ''); + overview_data.allocation.push(allocation_obj); + overview_data.allocation_id.push(room_data_on_date ? room_data_on_date.extranet_allocation_id : ''); + overview_data.availability.push(room_data_on_date ? available : ''); + overview_data.net_sold.push(room_data_on_date ? room_data_on_date.net_sold : ''); + }else if(room_data_on_date){ + let allocation_obj = { + id:`room${room_id}_allocation_${date_ind}`, + value:room_data_on_date ? room_data_on_date.allocation : '' + } + let available = room_data_on_date?.status == 'FREESALE' ? 'FREESALE' : room_data_on_date?.available; + overview_data.status[date_ind] = room_data_on_date ? room_data_on_date.status : ''; + overview_data.allocation[date_ind] = allocation_obj; + overview_data.allocation_id[date_ind] = room_data_on_date ? room_data_on_date.extranet_allocation_id : ''; + overview_data.availability[date_ind] = room_data_on_date ? available : ''; + overview_data.net_sold[date_ind] = room_data_on_date ? room_data_on_date.net_sold : ''; + } + contractDetails.min_stay.push(room_data_on_date ? room_data_on_date.min_stay : ''); + for(let i=0;i { + if((room_data.allocation[data_ind].value >= room_data.net_sold[data_ind] && (room_data.allocation[data_ind].value || room_data.allocation[data_ind].value === 0 )) || room_data.allocation[data_ind].value == 'FREESALE'){ + + let Obj = { + extranet_allocation_id:room_data.allocation_id[data_ind], + status:room_data.status[data_ind], + allocation:room_data.allocation[data_ind].value != 'FREESALE' ? parseInt(room_data.allocation[data_ind].value) : room_data.net_sold[data_ind], + net_sold:room_data.net_sold[data_ind], + } + this.apiserv.Post('/ExtranetOverview/UpdateOverViewAllocationTypeAndLimit',Obj).subscribe(resp=>{ + if(resp){ + this._commonService.showMessage(resp.status,resp.message); + if(resp.data){ + this.OverViewObj.RoomDetails[room_ind].availability[data_ind] = resp.data.status != 'FREESALE' ? resp.data.remaining_count : 'FREESALE'; + this.OverViewObj.RoomDetails[room_ind].allocation[data_ind].value = resp.data.status != 'FREESALE' ? parseInt(resp.data.allocation) : 'FREESALE'; + } + } + }) + }else { + this._commonService.showMessage(false,'allocation cannot be lesser than net sold') + } + }, 500); + } + // + + // Rooms Data and functions + + GetAllRooms() { + let ReObj = { + is_free_child: '', + is_extra_bed_supported: '', + extranet_room_view_id: '', + room_name: '', + hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetHotelRoom/GetAllExtranetHotelRoom', ReObj) + } + CloneRoom(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/CloneRoom/${this.Extranet_Hotel_Id}/${Id}`); + } + updateRoomStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetHotelRoom/UpdateExtranetHotelRoomStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.SerachRooms() : ''; + } + }); + } + SerachRooms() { + this.GetAllRooms().subscribe(res => { + this.AllRooms = res.data; + if (res) { + this.AllRooms = res.data ? res.data : []; + if (res.data) { + this.AllRooms.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['is_extra_bed_supported'] = e.is_extra_bed_supported ? 'Yes' : 'No'; + e['is_free_child'] = e.is_free_child ? 'Yes' : 'No'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }) + } + } + }) + } + EditRoom(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditRoom/${this.Extranet_Hotel_Id}/${Id}`); + } + //room Data Ends + + + // Season Data + SearchSeason() { + let ReqObj = { + season_name: '', + hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason', ReqObj) + } + updateSeasonStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetSeason/UpdateExtranetSeasonStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllSeason() : ''; + } + }); + } + + EditSeason(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSeason/${this.Extranet_Hotel_Id}/${Id}`); + } + GetAllSeason() { + this.SearchSeason().subscribe(res => { + if (res) { + this.SeasonResult = res.data ? res.data : []; + if (res.data) { + this.SeasonResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + }) + } + } + }) + } + //Season data ends + + //Contract Data + updateContractStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetRoomContractStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetallContract() : ''; + } + }); + } + SearchContract() { + let ReObj = { + extranet_hotel_id: this.Extranet_Hotel_Id, + extranet_room_id: '', + extranet_rate_plan_id: '', + extranet_meal_plan_id: '' + } + return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetRoomContract', ReObj) + } + Update(Id, pagename) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/${pagename}/${this.Extranet_Hotel_Id}/${Id}`); + } + GetallContract() { + this.SearchContract().subscribe(res => { + if (res) { + this.Contract_Results = res.data ? res.data : []; + if (res.data) { + this.Contract_Results.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['nationality_type'] = this.getNationalityType(e['nationality_type']) ; + e['nationality_applicable_type'] = this.getNationalityApplicabilityType(e['nationality_applicable_type']) ; + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['contract_dates'] ? JSON.parse(e['contract_dates']) : []; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['date_range'] = e.date_range_arr.length > 0 ? e.date_range_arr.join(',') : ''; + }) + } + } + }) + } + EditContract(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/RoomContractEdit/${this.Extranet_Hotel_Id}/${Id}`); + } + getNationalityType(value){ + if(value == 'INCLUDE'){ + return 'Include' + }else if(value == 'EXCLUDE'){ + return 'Exclude' + } + return '' + } + getNationalityApplicabilityType(value){ + if(value == 'ALL'){ + return 'All' + }else if(value == 'SPECIFIC'){ + return 'Specific' + } + return '' + } + //contract data ends + + //Allocation data + updateAllocationStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetAllocation/UpdateExtranetAllocationStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllocationDeata() : ''; + } + }); + } + + SearchAllocation() { + let ReqObj = { + extranet_room_id: '', + extranet_hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetAllocation/GetAllExtranetAllocation', ReqObj) + } + GetAllocationDeata() { + this.SearchAllocation().subscribe(res => { + if (res) { + this.AllocationResult = res.data ? res.data : []; + if (res.data) { + this.AllocationResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }) + } + } + }) + } + + EditAllocation(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/UpdateAllocation/${this.Extranet_Hotel_Id}/${Id}`); + } + //Allocation data ends + + //Offers data + + SearchOffers() { + let obj = { + extranet_hotel_id: this.Extranet_Hotel_Id, + extranet_room_id: '', + contract_name: '', + offer_name: '', + offer_type: '', + discount_code: '', + is_combinable_offer: '', + } + return this.apiserv.Post('/ExtranetOffer/GetAllExtranetOffer', obj) + } + GetAllOffers() { + this.SearchOffers().subscribe(res => { + if (res) { + this.OffersResult = res.data ? res.data : []; + if (res.data) { + this.OffersResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['offer_type'] = this.getOfferType(e['offer_type']); + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }) + } + } + }) + } + updateOfferStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetOffer/UpdateExtranetOfferStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllOffers() : ''; + } + }); + } + + EditOffer(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditOffer/${this.Extranet_Hotel_Id}/${Id}`); + } + getOfferType(value){ + if(value == 'EARLYBIRD'){ + return 'Early Bird' + }else if(value == 'STAYPAY'){ + return 'Stay Pay' + }else if(value == 'LONGSTAY'){ + return 'Long Stay' + }else if(value == 'DISCOUNT'){ + return 'Discount' + }else if(value == 'CONTRACTREMARK'){ + return 'Contract Remark' + } + return '' + } + //Offer data ends + + //supplements data + SearchSupplement() { + let obj = { + extranet_hotel_id: this.Extranet_Hotel_Id, + extranet_room_id: '', + contract_name: '', + supplement_name: '', + supplement_rate_type: '', + supplement_type: '', + } + return this.apiserv.Post('/ExtranetSupplement/GetAllExtranetSupplement', obj) + } + GetAllSupplement() { + this.SearchSupplement().subscribe(res => { + if (res) { + this.SupplementResult = res.data ? res.data : []; + if (res.data) { + this.SupplementResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['supplement_rate_type'] = this.getSupplementRateType(e.supplement_rate_type); + e['supplement_type'] = this.getSupplementType(e.supplement_type); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['supplement_dates'] ? JSON.parse(e['supplement_dates']) : e['supplement_dates']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.from).format('DD MMM YYYY') + ' - ' + moment(data.to).format('DD MMM YYYY'); + }) + } + e['custom_days'] = e['supplement_days'] ? e['supplement_days'].split(',') : '' + }) + } + } + }) + } + updateSupplementStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetSupplement/UpdateExtranetSupplementStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllSupplement() : ''; + } + }); + } + + EditSupplement(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditSuppliment/${this.Extranet_Hotel_Id}/${Id}`); + } + getSupplementType(value){ + if(value == 'ADDONRATE'){ + return 'Add-On Rate' + }else if(value == 'NEWRATE'){ + return 'New Rate' + } + return '' + } + getSupplementRateType(value){ + if(value == 'PERROOMPERNIGHT'){ + return 'Per Room Per Night' + }else if(value == 'PERPAXPERNIGHT'){ + return 'Per Pax Per Night' + }else if(value == 'PERPAXPERSTAY'){ + return 'Per Pax Per Stay' + } + return '' + } + //Supplement Data ends + + //Meals Add-on data + SearchMeals() { + let ReObj = { + addon_name: '', + extranet_meal_plan_id: '', + hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetMealAddon/GetAllExtranetMealAddon', ReObj) + } + GetAllMeals() { + this.SearchMeals().subscribe(res => { + if (res) { + this.MealsResult = res.data ? res.data : []; + if (res.data) { + this.MealsResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }) + } + } + }) + } + updateMealsStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetMealAddon/UpdateExtranetMealAddOnStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllMeals() : ''; + } + }); + } + EditMeals(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelMealEdit/${this.Extranet_Hotel_Id}/${Id}`); + } + //Meals Data ends + + //Block Date Data + SearchBlockDate() { + let ReqObj = { + rule_name: '', + block_date_type: '', + hotel_id: this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetBlockDate/GetAllExtranetBlockDate', ReqObj) + } + GetAllBlockDate() { + this.SearchBlockDate().subscribe(res => { + if (res) { + this.BlockDateResult = res.data ? res.data : []; + if (res.data) { + this.BlockDateResult.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['date_range_arr'] = e['date_range'] ? e['date_range'].split(', ') : e['date_range']; + if (typeof (e['date_range_arr']) != 'string') { + e.date_range_arr.forEach((data, ind) => { + e.date_range_arr[ind] = moment(data.split(' - ')[0]).format('DD MMM YYYY') + ' - ' + moment(data.split(' - ')[1]).format('DD MMM YYYY'); + }) + } + e['Custom_created_on'] = this._commonService.convertDateWithTimeToShow(e.created_on); + e['block_date_type'] = e.block_date_type == 'CHECKINDATE' ? 'Check-in Date' : 'Check-out Date'; + }) + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + status: val ? false : true, + }; + this.apiserv.Post('/ExtranetBlockDate/UpdateExtranetBlockDateStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.GetAllBlockDate() : ''; + } + }); + } + + Edit(Id) { + this.router.navigateByUrl(`Services/Hotel/HotelManage/HotelEditBlockDate/${this.Extranet_Hotel_Id}/${Id}`); + } + //Block Date Data Ends + + //Minimum stay + SearchMinStay(){ + let ReqObj = { + extranet_room_id:'', + extranet_hotel_id:this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetMinStay/GetAllExtranetRoomMinStay',ReqObj) + } + + EditMinStay(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/EditMinStay/${this.Extranet_Hotel_Id}/${Id}`); + } + //Minimum Stay ends + +} diff --git a/src/app/modules/services/hotel/hotel-manage/overview/overview.module.ts b/src/app/modules/services/hotel/hotel-manage/overview/overview.module.ts new file mode 100644 index 0000000..7b7d57a --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/overview/overview.module.ts @@ -0,0 +1,47 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { OverviewComponent } from './overview.component'; +import { CalendarModule } from 'primeng/calendar'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; + + + +@NgModule({ + declarations: [ + OverviewComponent + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + CalendarModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + + ], + exports:[ + OverviewComponent + ] +}) +export class OverviewModule { } diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.html b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.html new file mode 100644 index 0000000..5d2dfbd --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.html @@ -0,0 +1,1245 @@ + + +
    +
    +
    +

    Room Contract

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + {{item}} + {{item}} + {{data.room_name + + (data.room_view_name ? ', ' : '') + data.room_view_name}} +
    + Please + select room name +
    +
    +
    +
    + + + +
    +
    +
    +

    Rate Plan

    +
    + +
    +
    +
    + Select + {{data.rate_plan_name}} +
    + Please + select rate plan +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + Select + {{data.meal_plan_name}} +
    + Please + select meal plan +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select nationality type +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select nationality applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Nationality

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select nationality +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Type

    +
    + +
    +
    +
    + Select + Include + Exclude +
    + Please + select residence type +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence Applicability

    +
    + +
    +
    +
    + Select + {{data.Label}} +
    + Please + select residence applicalbility +
    +
    +
    +
    + + + +
    +
    +
    +

    Residence

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select residence +
    +
    +
    +
    + + + +
    +
    +
    +

    Date Type

    +
    + +
    +
    +
    + Select + Specific Dates + Season +
    + Please + select Date type +
    +
    + +
    +
    + +
    +
    +
    + + + Please select date greater than from today's date or previous range + + + Please select range to date + + + Please select date range + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + {{data.season_name}} +
    + + info + + Please + select Season +
    +
    +
    +
    +
    +
    + Meal Add On +
    +
    +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + {{data.addon_name}} +
    + Please + select meals +
    +
    +
    +
    +
    +
    +
    +
    +

    Pricing Details

    +
    +
    +
    + + + +
    + {{Room_data.get('extranet_room_name').value}} ({{(showRate_Plan_Name ? (showRate_Plan_Name + ', + ') : '') + (showRate_meal_Name ? showRate_meal_Name : '')}}) +
    +
    +
    +
    +
    +
    + + + Please + enter contract name +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    +
    + {{item}} + {{item}} +
    + Please + enter contract days +
    +
    +
    +
    Adult Pricing
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Occupancy +
    + 1 Adult + +
    +
    +
    + 2 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 3 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 4 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 5 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 6 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 7 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 8 Adult +
    +
    + ExtraBed Included +
    +
    +
    + 9 Adult +
    +
    + ExtraBed Included +
    +
    Price +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    Child + Pricing
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Child Age Range + + Occupancy + + ExtraBed Included + + Charges +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Cancellation Policy

    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Policy Type

    +
    + +
    +
    +
    + Select + Day +
    + Please + select cancellation policy type +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + From + day + Please + enter range greater than previous range +
    +
    +
    +
    + + + To + days + Please + enter to value greater than from value +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Cancellation Type

    +
    + +
    +
    +
    + Select + Full Charges + Night Count + Amount + Percentage +
    + Please + select cancellation type +
    +
    +
    +
    + + + +
    +
    +
    +

    Night Type

    +
    + +
    +
    +
    + Select + First + Last + Cheapest + Highest +
    + Please + select night type +
    +
    +
    +
    + + + Please + enter value +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    + +
    {{item.season_name}}
    +
    +

    {{date}}

    +
    +
    +
    + + + +
    + +
    + +
    + To determine the cancellation fee, we consider both the number of nights booked and the type of night + selected (e.g., "First Night"). For instance, if you choose "First Night" in type and specify 3 nights, the + cancellation fee will be calculated from the first 3 nights of the stay. +
    +
    + + + +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.ts new file mode 100644 index 0000000..77878d8 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/rate-setting-add.component.ts @@ -0,0 +1,783 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-rate-setting-add', + templateUrl: './rate-setting-add.component.html', +}) +export class RateSettingAddComponent implements OnInit { + displayPosition: boolean; + position: string; + ActiveTab = 0; + Extranet_Hotel_Id; + Clone_Rule; + SelectAllRoom = []; + ClearAllRoom = []; + CancelModal = false; + HotelRoomContractForm:FormGroup; + AllRoomsData; + Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + AllRatePlan; + timer; + Season_List = []; + Selected_Room_List = []; + AllSeason; + SelectAll=["Select All"]; + showRate_Plan_Name; + showRate_meal_Name; + AllMeal; + MinDate = new Date(); + CountryList; + Edit_Id; + AllMealPlan; + ddLoader = { + Country:false, + Residence:false, + } + IsMobile; + AllDaysArr = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; + SelectAllVal=[]; + DaysArrValue=[]; + constructor(public activateRoute:ActivatedRoute,private router:Router,private hotelmanageserv:ManageHotelService, + public apiserv:API,public fb:FormBuilder,public validserv:ValidationService,public commonMasterSer:CommonFunctionService) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.Edit_Id = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.Clone_Rule = this.activateRoute.snapshot['_routerState'].url.includes('CloneContract') && this.Edit_Id ? true :false; + this.InitForm(); + this.getAllData(); + } + CheckTabInd(event){ + this.ActiveTab = event.index; +} + InitForm(){ + this.HotelRoomContractForm = this.fb.group({ + room_name:this.validserv.required, + extranet_rate_plan_id:this.validserv.required, + extranet_meal_plan_id:this.validserv.required, + currency_code:'', + nationality_type:'', + nationality_applicable_type:'', + residence_type:'', + residence_applicable_type:'', + date_type:this.validserv.required, + is_meal_addon_applicable:false, + RoomPricingDetail:this.fb.array([]) + }); + } + getAllData() { + forkJoin( + this.GetAllRooms(), + this.GetAllPlan(), + this.GetAllMealPlan(), + this.GetHotelDataById(), + this.GetAllSeason(), + this.GetAllMeal(), + this.GetContractById(this.Edit_Id) + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllRoomsData = res[0] ? res[0].data : []; + if(res[0].data){ + this.SelectAllRoom = ['Select All']; + } + this.AllRatePlan = res[1] ? res[1].data : []; + this.AllMealPlan = res[2].data; + this.HotelRoomContractForm.get('currency_code').setValue(res[3].data ? res[3].data['currency'] : ''); + this.AllSeason = res[4].data ? res[4].data : []; + this.AllMeal = res[5].data ? res[5].data : []; + this.SetContractFormValue(res[6] ? res[6].data :'') + } + }); + } + GetContractById(Editid) { + if (Editid) + return this.apiserv.Get('/ExtranetRoomContract/GetExtranetRoomContractById/' + Editid) + else + return of(null) + }; + GetAllPlan(){ + return this.apiserv.Get('/ExtranetRoomContract/GetAllExtranetHotelRatePlan/EN') + } + GetAllMeal(){ + return this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMealAddonByOrg/'+ this.Extranet_Hotel_Id) + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj) + } + GetHotelDataById() { + if (this.Extranet_Hotel_Id) + return this.apiserv.Get('/ExtranetHotel/GetExtranetHotelById/' + this.Extranet_Hotel_Id) + else + return of(null) + }; + GetAllMealPlan(){ + return this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMeal/EN') + } + GetAllSeason(){ + let ReqObj = { + season_name:'', + hotel_id:this.Extranet_Hotel_Id + } + return this.apiserv.Post('/ExtranetSeason/GetAllExtranetSeason',ReqObj) + } + showPositionDialog(position) { + this.position = position; + this.displayPosition = true; + }; + + BackButton(){ + this.hotelmanageserv.Active_tab = 'RoomContract'; + this.router.navigateByUrl(`Services/Hotel/HotelManage/${this.Extranet_Hotel_Id}`); + } + NationalityShowhide(event){ + if(event == 'SPECIFIC'){ + this.HotelRoomContractForm.addControl('nationality',new FormControl('',Validators.required)) + }else{ + this.HotelRoomContractForm.removeControl('nationality'); + } + } + ResidenceShowhide(event){ + if(event == 'SPECIFIC'){ + this.HotelRoomContractForm.addControl('residence',new FormControl('',Validators.required)) + }else{ + this.HotelRoomContractForm.removeControl('residence'); + } + } + NationalityTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Nationality_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Nationality_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.HotelRoomContractForm.controls['nationality_applicable_type'].value == 'ALL'){ + this.HotelRoomContractForm.get('nationality_applicable_type').setValue(''); + } + } + } + ResidenceTypeCheck(event){ + if(event == 'INCLUDE'){ + this.Residence_type = [{Label:'All',Value:'ALL'},{Label:'Specific',Value:'SPECIFIC'}]; + }else{ + this.Residence_type = [{Label:'Specific',Value:'SPECIFIC'}]; + if(this.HotelRoomContractForm.controls['residence_applicable_type'].value == 'ALL'){ + this.HotelRoomContractForm.get('residence_applicable_type').setValue(''); + } + } + } + getCountryList(event,name) { + if (event.value.length >= 2) { + this.ddLoader[name] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader[name] = false; + } + }); + }, 500); + } + } + ShowDateTypeFields(event){ + this.Season_List = []; + if(event == 'SPECIFICDATES'){ + this.HotelRoomContractForm.addControl('ContractDatesArr',new FormArray([this.fb.group({ + date:['', Validators.compose([Validators.required, this.dateValidation(new Date(new Date().setDate(new Date().getDate() - 1)))])], + })])); + this.HotelRoomContractForm.removeControl('Season_Id'); + }else if(event == 'SEASON'){ + this.HotelRoomContractForm.addControl('Season_Id',new FormControl('',Validators.required)) + this.HotelRoomContractForm.removeControl('ContractDatesArr'); + }else { + this.HotelRoomContractForm.removeControl('Season_Id'); + this.HotelRoomContractForm.removeControl('ContractDatesArr'); + } + } + addDate() { + let formArray = this.HotelRoomContractForm.controls['ContractDatesArr'] as FormArray; + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if(formArray.length > 0){ + if (formArray.length > 0) { + let formdate = formArray.controls[formArray.length - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + formArray.push(this.fb.group({ + extranet_season_detail_id:'', + date: ['', Validators.compose([ + Validators.required, + this.dateValidation(currentDate) + ])] + })); + } + } + public dateValidation(toDate): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value) { + if (control.value.length <= 1 || control.value[1] == null) { + return { 'todate': true }; + } + if (toDate && control.value.length <= 1 || control.value[0] <= toDate) { + return { 'range': true }; + } + } + return null; + }; + } + removeDate(index) { + let formArray = this.HotelRoomContractForm.controls['ContractDatesArr'] as FormArray; + formArray.removeAt(index); + let date = new Date(); + let currentDate = date; + currentDate = new Date(currentDate.getTime() - 1 * 24 * 60 * 60 * 1000); + if (formArray.length > 0) { + if(index > 0){ + let formdate = formArray.controls[index - 1].get('date').value; + if (formdate && formdate.length == 2) { + currentDate = formdate[1]; + } + } + if (formArray.controls.length >= (index + 1)) { + formArray.controls[index].get("date").clearValidators(); + formArray.controls[index].get("date").setErrors(null); + formArray.controls[index].get("date").addValidators([Validators.required,this.dateValidation(currentDate)]); + // formArray.controls[index].get("date").markAsTouched(); + formArray.controls[index].get("date").updateValueAndValidity(); + // formArray.controls[index].get("date").markAsTouched(); + } + } + } + CloseCalender(element, index) { + let formArray = this.HotelRoomContractForm.controls['ContractDatesArr']['controls']; + if (element.value[0] && element.value[1]) { + element.overlayVisible = false; + element.datepickerClick = true; + if (formArray.length >= (index + 2)) { + formArray[index + 1].get("date").clearValidators(); + formArray[index + 1].get("date").setErrors(null); + formArray[index + 1].get("date").addValidators([Validators.required,this.dateValidation(element.value[1])]); + formArray[index + 1].get("date").markAsTouched(); + formArray[index + 1].get("date").updateValueAndValidity(); + formArray[index + 1].get("date").markAsTouched(); + } + } + } + MealHideShow(check){ + if(check){ + this.HotelRoomContractForm.addControl('extranet_meal_addon_id',new FormControl('',Validators.required)) + }else { + this.HotelRoomContractForm.removeControl('extranet_meal_addon_id'); + } + } + SeasonDataAddRemove(){ + this.Season_List = []; + let selected_season = this.HotelRoomContractForm.controls['Season_Id'].value; + selected_season.forEach(data=>{ + let matched_season_by_id = this.AllSeason.find(e=>e.extranet_season_id == data); + if(matched_season_by_id){ + if(typeof(matched_season_by_id['date_range']) == 'string'){ + matched_season_by_id['date_range'] = matched_season_by_id.date_range.split(', '); + matched_season_by_id['date_range'].forEach((z,i)=>{ + matched_season_by_id['date_range'][i] = moment(z.split(' - ')[0]).format('DD MMM YYYY') + ' to ' + moment(z.split(' - ')[1]).format('DD MMM YYYY') + }) + } + this.Season_List.push(matched_season_by_id); + console.log(this.Season_List) + } + }) + } + AddRemoveRoomContract(event,formVal?){ + const contract_id = this.HotelRoomContractForm.get('room_name').value + if (contract_id && contract_id.length > 0 && (contract_id.includes('Select All') || contract_id.length == this.AllRoomsData.length) && !contract_id.includes('Clear All')) { + let room_id_List = [] + this.AllRoomsData.forEach(d=>{ + room_id_List.push(d.extranet_room_id) + }); + this.HotelRoomContractForm.get('room_name').setValue(room_id_List); + event = this.HotelRoomContractForm.get('room_name').value + this.SelectAllRoom = []; + this.ClearAllRoom = ['Clear All']; + } else if (contract_id && contract_id.length > 0 && (contract_id.includes('Clear All'))){ + this.HotelRoomContractForm.get('room_name').setValue([]); + this.SelectAllRoom = ['Select All']; + this.ClearAllRoom = []; + event = this.HotelRoomContractForm.get('room_name').value + } else { + this.SelectAllRoom = ['Select All']; + if(contract_id?.length > 0){ + this.ClearAllRoom = ['Clear All']; + } + } + const addedItems = event.filter(item => !this.Selected_Room_List.includes(item)); + const removedItems = this.Selected_Room_List.filter(item => !event.includes(item)); + if(addedItems.length){ + addedItems.forEach(item=>{ + this.AddItems(item,formVal) + }) + }else if(removedItems.length){ + removedItems.forEach(item=>{ + this.RemoveItems(item); + }) + } + this.Selected_Room_List = [...event]; + } + AddItems(item,formVal){ + let Room_Details = this.AllRoomsData.find(e=>e.extranet_room_id == item); + let formArray = this.HotelRoomContractForm.get('RoomPricingDetail') as FormArray; + if(Room_Details){ + let age_range = JSON.parse(Room_Details.age_range) + formArray.push(this.fb.group({ + contract_name:this.validserv.required, + extranet_room_name:Room_Details.room_name, + // type: this.validserv.required, + contract_days: this.fb.array([ + this.fb.group({ + extranet_room_id:Room_Details.extranet_room_id, + days:this.fb.control(formVal && formVal.ExtranetRoomContractRate[0]?.days ? formVal.ExtranetRoomContractRate[0].days : [], [Validators.required]), + age_range1:'', + age_range2:'', + }) + ]), + })); + if(formVal && formVal.ExtranetRoomContractRate[0]?.days){ + this.ChangeinWeekDays( 0,formVal.ExtranetRoomContractRate[0]?.days,0); + } + if(this.Clone_Rule){ + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][0].get('contract_name').setValue(formVal ? formVal.ExtranetRoomContractRate[0]?.contract_name : '') + } + let rate_plan_id = this.HotelRoomContractForm.get('extranet_rate_plan_id').value; + if(rate_plan_id != '20240724044902547713' && rate_plan_id != '20240724044902546366'){ + let formgroup = formArray.controls[formArray.controls.length - 1] as FormGroup; + formgroup.addControl(`type`,new FormControl(formVal ? formVal.ExtranetRoomContractCancellationPolicy[0].type : [],Validators.required)); + formgroup.addControl(`cancel_policy`,new FormArray([this.fb.group({ + from: [formVal ? formVal.ExtranetRoomContractCancellationPolicy[0].from : 0,Validators.compose([Validators.required])], + to: [formVal ? formVal.ExtranetRoomContractCancellationPolicy[0].to : '',Validators.compose([Validators.required,this.AmountRangeValidation(0)])], + charge_type: this.fb.control(formVal && formVal.ExtranetRoomContractCancellationPolicy[0] ? formVal.ExtranetRoomContractCancellationPolicy[0].charge_type : [], [Validators.required]), + charge_value: this.fb.control(formVal && formVal.ExtranetRoomContractCancellationPolicy[0]? formVal.ExtranetRoomContractCancellationPolicy[0].charge_value : [], [Validators.required]), + })])); + this.Checkcanceltype(formVal?.ExtranetRoomContractCancellationPolicy[0].charge_type,0,0); + if(formVal && formVal.ExtranetRoomContractCancellationPolicy[0] && formVal && formVal.ExtranetRoomContractCancellationPolicy[0].charge_type == 'NIGHTCOUNT'){ + formgroup.controls['cancel_policy']['controls'][0].get('night_type').setValue(formVal.ExtranetRoomContractCancellationPolicy[0].night_type) + } + } + let Adult_Bed_Obj = Room_Details.adult_extrabed_details_json ? JSON.parse(Room_Details.adult_extrabed_details_json) : ''; + for(let i=1;i <= Room_Details.max_adult_occupancy;i++){ + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].addControl(`adult_${i}`,new FormControl(formVal ? formVal.ExtranetRoomContractRate[0][`adult_${i}`] : '',Validators.required)) + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].addControl(`supplement_${i}`,new FormControl({value: Adult_Bed_Obj ? Adult_Bed_Obj[`adult_${i}`] : false, disabled: true})) + } + let paid_child_extrabed_obj = JSON.parse(Room_Details.paid_child_extrabed_details); + for(let i=1;i <= age_range.length;i++){ + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].get(`age_range${i}`).setValue(age_range[i-1]['from'] + ' to ' + age_range[i-1]['to']); + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].addControl(`is_child_extra_bed_age_range${i}`,new FormControl(formVal ? formVal.ExtranetRoomContractRate[0][`is_child_extra_bed_age_range${i}`] : false)); + for(let j=1;j <= Room_Details.max_child_occupancy;j++){ + if(Room_Details.max_child_occupancy == Room_Details.max_free_child || j > Room_Details.max_free_child || i == 2){ + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].addControl(`age_range${i}_child_${j}`,new FormControl(formVal ? formVal.ExtranetRoomContractRate[0][`age_range${i}_child_${j}`] : [],Validators.required)) + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].addControl(`age_range${i}_extrabed_${j}`,new FormControl({value: false, disabled: true})); + if(paid_child_extrabed_obj?.length > 0){ + formArray.controls[formArray.controls.length -1]['controls']['contract_days']['controls'][0].get(`age_range${i}_extrabed_${j}`).setValue(paid_child_extrabed_obj ? paid_child_extrabed_obj[i-1].Child_Extra_bed_detail[j-1] : false); + } + } + } + } + this.DaysArrValue[formArray.controls.length -1] = this.AllDaysArr; + this.SelectAllVal[formArray.controls.length -1] = this.SelectAll; + if(formVal?.ExtranetRoomContractRate[0].days){ + this.ChangeinWeekDays(0,0); + } + } + } + RemoveItems(item){ + let formdata = this.HotelRoomContractForm.get('RoomPricingDetail').value; + let index = 0; + formdata.forEach((data,ind)=>{ + if(data.contract_days[0].extranet_room_id == item){ + index = ind + } + }) + let formArray = this.HotelRoomContractForm.get('RoomPricingDetail') as FormArray; + formArray.removeAt(index); + let formvalue = this.HotelRoomContractForm.get('RoomPricingDetail').value; + for(let i=0;i < formvalue.length;i++){ + this.ChangeinWeekDays(i); + } + } + AddCancelArr(ind,formVal?){ + let formArray = this.HotelRoomContractForm.get('RoomPricingDetail') as FormArray; + let cancel_arr = formArray.controls[ind]['controls']['cancel_policy']; + let min_amnt = cancel_arr.controls[cancel_arr.controls.length - 1].get('to').value; + formArray.controls[ind]['controls']['cancel_policy'].push( + this.fb.group({ + from: [formVal?.from ? formVal?.from : '',Validators.compose([Validators.required])], + to: [formVal?.to ? formVal.to : '',Validators.compose([Validators.required,this.AmountRangeValidation(0)])], + charge_type: this.fb.control(formVal?.charge_type ? formVal.charge_type : [], [Validators.required]), + charge_value: this.fb.control(formVal?.charge_value ? formVal.charge_value : [], [Validators.required]), + }) + ); + if(min_amnt){ + formArray.controls[ind]['controls']['cancel_policy']['controls'][formArray.controls[ind]['controls']['cancel_policy']['controls'].length -1].get('from').setValue(min_amnt ? (parseInt(min_amnt) + 1) : '') + this.ChangeFeeMinValue('to',min_amnt ? (parseInt(min_amnt) + 1) : min_amnt ,ind,formArray.controls[ind]['controls']['cancel_policy']['controls'].length -1); + } + formVal ? this.Checkcanceltype(formVal?.charge_type,0,formArray.controls[ind]['controls']['cancel_policy']['controls'].length -1) :''; + if(formVal?.charge_type == 'NIGHTCOUNT'){ + formArray.controls[ind]['controls']['cancel_policy']['controls'][formArray.controls[ind]['controls']['cancel_policy']['controls'].length -1].get('night_type').setValue(formVal.night_type) + } + } + removeCancelArr(room_ind,arr_ind){ + let formArray = this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][room_ind]['controls']['cancel_policy'] as FormArray; + formArray.removeAt(arr_ind); + if(formArray.controls[arr_ind]){ + let amount = arr_ind == 0 ? '' : formArray.controls[arr_ind-1].get('to').value; + this.ChangeFeeMinValue('from',amount,room_ind,arr_ind); + } + } + Checkcanceltype(event,room_ind,cancel_ind){ + let formcontrol = this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][room_ind]['controls']['cancel_policy']['controls'][cancel_ind] as FormGroup; + if(event == 'NIGHTCOUNT'){ + formcontrol.addControl('night_type',new FormControl('',Validators.required)); + if(!formcontrol.controls['charge_value']){ + formcontrol.addControl('charge_value',new FormControl('',Validators.required)); + } + } else if(event == 'FULLCHARGES'){ + formcontrol.removeControl('night_type'); + formcontrol.removeControl('charge_value'); + } else { + if(!formcontrol.controls['charge_value']){ + formcontrol.addControl('charge_value',new FormControl('',Validators.required)); + } + formcontrol.removeControl('night_type'); + } + } + AddContractArr(room_ind,room_id,formVal?){ + let Room_Details = this.AllRoomsData.find(e=>e.extranet_room_id == room_id); + let formArray = this.HotelRoomContractForm.get('RoomPricingDetail') as FormArray; + if(Room_Details){ + let age_range = JSON.parse(Room_Details.age_range) + formArray.controls[room_ind]['controls']['contract_days'].push( + this.fb.group({ + extranet_room_id:Room_Details.extranet_room_id, + days:this.fb.control(formVal?.days ? formVal.days : [], [Validators.required]), + age_range1:'', + age_range2:'', + }) + ) + if(formVal?.days){ + this.ChangeinWeekDays( 0,formVal.days,formArray.controls[room_ind]['controls']['contract_days']['controls'].length -1); + } + let room_days_arr = formArray.controls[room_ind]['controls']['contract_days'] as FormArray; + let Adult_Bed_Obj = Room_Details.adult_extrabed_details_json ? JSON.parse(Room_Details.adult_extrabed_details_json) : ''; + for(let i=1;i <= Room_Details.max_adult_occupancy;i++){ + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].addControl(`adult_${i}`,new FormControl(formVal ? formVal[`adult_${i}`] :'',Validators.required)) + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].addControl(`supplement_${i}`,new FormControl({value: Adult_Bed_Obj ? Adult_Bed_Obj[`adult_${i}`] : false, disabled: true})) + } + let paid_child_extrabed_obj = JSON.parse(Room_Details.paid_child_extrabed_details); + for(let i=1;i <= age_range.length;i++){ + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].get(`age_range${i}`).setValue(age_range[i-1]['from'] + ' to ' + age_range[i-1]['to']); + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].addControl(`is_child_extra_bed_age_range${i}`,new FormControl(formVal ? formVal[`is_child_extra_bed_age_range${i}`] : false)); + for(let j=1;j <= Room_Details.max_child_occupancy;j++){ + if(Room_Details.max_child_occupancy == Room_Details.max_free_child || j > Room_Details.max_free_child || i == 2){ + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].addControl(`age_range${i}_child_${j}`,new FormControl(formVal ? formVal[`age_range${i}_child_${j}`] : '',Validators.required)) + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].addControl(`age_range${i}_extrabed_${j}`,new FormControl({value: false, disabled: true})); + if(paid_child_extrabed_obj?.length > 0){ + formArray.controls[room_ind]['controls']['contract_days']['controls'][room_days_arr.controls.length -1].get(`age_range${i}_extrabed_${j}`).setValue(paid_child_extrabed_obj ? paid_child_extrabed_obj[i-1].Child_Extra_bed_detail[j-1] : false); + } + } + } + } + } + console.log(formArray) + } + RemoveContractArr(room_ind,contract_day_ind){ + let formArray = this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][room_ind]['controls']['contract_days'] as FormArray; + formArray.removeAt(contract_day_ind); + } + CopyAdultValues(room_ind,contract_day_ind,adult_value,room_id){ + if(adult_value || adult_value == 0){ + let Room_Details = this.AllRoomsData.find(e=>e.extranet_room_id == room_id); + let formArray = this.HotelRoomContractForm.get('RoomPricingDetail') as FormArray; + for(let i=1;i <= Room_Details.max_adult_occupancy;i++){ + formArray.controls[room_ind]['controls']['contract_days']['controls'][contract_day_ind].get(`adult_${i}`).setValue(adult_value) + } + } + } + ChangeinWeekDays(i,event?,j?){ + let selected_days_by_room = []; + let formdata = this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['contract_days'].value; + if( event && event.includes('Select All')){ + formdata[j].days.splice(formdata[j].days.indexOf('Select All'), 1); + this.DaysArrValue[i].forEach(days_val=>{ + formdata[j].days.push(days_val); + }) + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['contract_days'].controls[j]['controls']['days'].setValue(formdata[j].days); + } + formdata.forEach(e=>{ + if(e.days && e.days.length > 0){ + e.days.forEach(days=>{ + selected_days_by_room.push(days); + }) + } + }) + this.DaysArrValue[i] = this.AllDaysArr.filter(item => !selected_days_by_room.includes(item)); + if(this.DaysArrValue[i].length == 0){ + this.SelectAllVal[i] = [] + }else { + this.SelectAllVal[i] = this.SelectAll; + } + } + Save(){ + if (this.HotelRoomContractForm.status == "VALID") { + let formvalue = this.HotelRoomContractForm.getRawValue(); + let postData = { + extranet_hotel_id:this.Extranet_Hotel_Id, + extranet_rate_plan_id:formvalue.extranet_rate_plan_id, + extranet_meal_plan_id:formvalue.extranet_meal_plan_id, + currency_code:formvalue.currency_code, + nationality_type:formvalue.nationality_type ? formvalue.nationality_type : '', + nationality_applicable_type:formvalue.nationality_applicable_type ? formvalue.nationality_applicable_type : '', + nationality:formvalue.nationality_applicable_type == 'SPECIFIC' ? formvalue.nationality.join(',') : '', + residence_type:formvalue.residence_type, + residence_applicable_type:formvalue.residence_applicable_type, + residence:formvalue.residence_applicable_type == 'SPECIFIC' ? formvalue.residence.join(',') : '', + contract_dates:'', + is_meal_addon_applicable:formvalue.is_meal_addon_applicable, + date_type:formvalue.date_type, + season:formvalue.Season_Id ? formvalue.Season_Id.join(',') : '', + extranet_meal_addon_id:formvalue.is_meal_addon_applicable ? formvalue.extranet_meal_addon_id.join(',') : '', + RoomPricingDetail:[] + } + if(formvalue.date_type == 'SPECIFICDATES'){ + let date_Arr = []; + formvalue.ContractDatesArr.forEach(data=>{ + date_Arr.push({ + date_from: moment(data.date[0]).format('YYYY-MM-DD'), + date_to: moment(data.date[1]).format('YYYY-MM-DD'), + }) + }); + postData['contract_dates'] = JSON.stringify(date_Arr); + } + if(formvalue.date_type == 'SEASON'){ + let date_Arr = []; + this.Season_List.forEach(data=>{ + data.date_range.forEach(season_date=>{ + date_Arr.push({ + date_from: moment(season_date.split(' to ')[0]).format('YYYY-MM-DD'), + date_to: moment(season_date.split(' to ')[1]).format('YYYY-MM-DD'), + }) + }) + }); + postData['contract_dates'] = JSON.stringify(date_Arr); + } + if(formvalue.RoomPricingDetail && formvalue.RoomPricingDetail.length > 0){ + formvalue.RoomPricingDetail.forEach(roomdata=>{ + let subObj = { + contract_days : [], + cancel_policy : [] + } + if(roomdata.contract_days && roomdata.contract_days.length > 0){ + roomdata.contract_days.forEach(contract_data=>{ + subObj.contract_days.push({ + extranet_room_id:contract_data.extranet_room_id, + contract_name:roomdata.contract_name, + days:contract_data.days ? contract_data.days.join(',').toLowerCase() : '', + adult_1:contract_data['adult_1'] ? parseFloat(contract_data['adult_1']) : null, + adult_2:contract_data['adult_2'] ? parseFloat(contract_data['adult_2']) : null, + adult_3:contract_data['adult_3'] ? parseFloat(contract_data['adult_3']) : null, + adult_4:contract_data['adult_4'] ? parseFloat(contract_data['adult_4']) : null, + adult_5:contract_data['adult_5'] ? parseFloat(contract_data['adult_5']) : null, + adult_6:contract_data['adult_6'] ? parseFloat(contract_data['adult_6']) : null, + adult_7:contract_data['adult_7'] ? parseFloat(contract_data['adult_7']) : null, + adult_8:contract_data['adult_8'] ? parseFloat(contract_data['adult_8']) : null, + adult_9:contract_data['adult_9'] ? parseFloat(contract_data['adult_9']) : null, + age_range1_child_1:contract_data['age_range1_child_1'] ? parseFloat(contract_data['age_range1_child_1']) : null, + age_range1_child_2:contract_data['age_range1_child_2'] ? parseFloat(contract_data['age_range1_child_2']) : null, + age_range1_child_3:contract_data['age_range1_child_3'] ? parseFloat(contract_data['age_range1_child_3']) : null, + age_range1_child_4:contract_data['age_range1_child_4'] ? parseFloat(contract_data['age_range1_child_4']) : null, + age_range1_child_5:contract_data['age_range1_child_5'] ? parseFloat(contract_data['age_range1_child_5']) : null, + age_range1_child_6:contract_data['age_range1_child_6'] ? parseFloat(contract_data['age_range1_child_6']) : null, + age_range2_child_1:contract_data['age_range2_child_1'] ? parseFloat(contract_data['age_range2_child_1']) : null, + age_range2_child_2:contract_data['age_range2_child_2'] ? parseFloat(contract_data['age_range2_child_2']) : null, + age_range2_child_3:contract_data['age_range2_child_3'] ? parseFloat(contract_data['age_range2_child_3']) : null, + age_range2_child_4:contract_data['age_range2_child_4'] ? parseFloat(contract_data['age_range2_child_4']) : null, + age_range2_child_5:contract_data['age_range2_child_5'] ? parseFloat(contract_data['age_range2_child_5']) : null, + age_range2_child_6:contract_data['age_range2_child_6'] ? parseFloat(contract_data['age_range2_child_6']) : null, + }) + }) + } + if(roomdata.cancel_policy && roomdata.cancel_policy.length > 0){ + roomdata.cancel_policy.forEach(cancel_data=>{ + subObj.cancel_policy.push({ + type:roomdata.type, + from:cancel_data.from.toString(), + to:cancel_data.to, + charge_type:cancel_data.charge_type, + charge_value:cancel_data.charge_value ? parseInt(cancel_data.charge_value):0, + night_type:cancel_data['night_type'] ? cancel_data['night_type'] : '', + }) + }) + } + postData.RoomPricingDetail.push(subObj); + }) + } + console.log(postData) + this.apiserv.Post('/ExtranetRoomContract/SaveExtranetRoomContract',postData).subscribe(data=>{ + if(data){ + this.commonMasterSer.showMessage(data.status,data.message); + data.status ? this.BackButton() : ''; + } + }) + }else{ + this.validserv.showValidationsMsg(this.HotelRoomContractForm); + setTimeout(() => { + this.validserv.scrollToError(); + }, 50); + } + } + Rate_Plan_Check(){ + let rate_plan_id = this.HotelRoomContractForm.get('extranet_rate_plan_id').value; + if(rate_plan_id == '20240724044902547713' || rate_plan_id == '20240724044902546366'){ + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'].forEach(formgroup=>{ + formgroup.removeControl('cancel_policy'); + formgroup.removeControl('type'); + }) + }else{ + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'].forEach(formgroup=>{ + // formgroup.removeControl('cancel_policy'); + // formgroup.removeControl('type'); + if(!formgroup.contains('cancel_policy')){ + formgroup.addControl(`type`,new FormControl([],Validators.required)) + formgroup.addControl(`cancel_policy`,new FormArray([this.fb.group({ + from: [0,Validators.compose([Validators.required])], + to: [[],Validators.compose([Validators.required,this.AmountRangeValidation(0)])], + charge_type: this.validserv.required, + charge_value: this.validserv.required, + })])) + } + }) + } + if(rate_plan_id){ + let planName = this.AllRatePlan.find(e=>e.extranet_rate_plan_id == rate_plan_id); + this.showRate_Plan_Name = planName.rate_plan_name; + }else { + this.showRate_Plan_Name = undefined; + } + } + Meal_Plan_Show(){ + let meal_plan_id = this.HotelRoomContractForm.get('extranet_meal_plan_id').value; + if(meal_plan_id){ + let planName = this.AllMealPlan.find(e=>e.extranet_meal_plan_id == meal_plan_id); + this.showRate_meal_Name = planName.meal_plan_name; + }else { + this.showRate_meal_Name = undefined; + } + } + ChangeFeeMinValue(controlname,min,i,j) { + let min_amt = min; + if(this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j] && controlname != 'from'){ + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).clearValidators(); + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).addValidators([Validators.required, this.AmountRangeValidation(min_amt)]); + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).markAsUntouched(); + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).setErrors(null); + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).updateValueAndValidity(); + } + if(controlname == 'from' && this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j]){ + this.HotelRoomContractForm.controls['RoomPricingDetail']['controls'][i]['controls']['cancel_policy']['controls'][j].get(controlname).setValue(min_amt ? (parseInt(min_amt) + 1) : 0) + this.ChangeFeeMinValue('to',min_amt ? (parseInt(min_amt) + 1) : 0,i,j); + } + } + private AmountRangeValidation(initialValue): ValidatorFn { + return (control: AbstractControl): { [key: string]: boolean } | null => { + if (control.value || control.value == 0) { + if (initialValue && parseInt(control.value) <= parseInt(initialValue)) { + return { 'range': true }; + } + } + return null; + }; + } + //set form data + SetContractFormValue(formValue) { + if (formValue) { + let Val = formValue; + // console.log(Val); + this.HotelRoomContractForm.get('room_name').setValue(Val.extranet_room_id ? Val.extranet_room_id.split(','):[]); + this.HotelRoomContractForm.get('extranet_rate_plan_id').setValue(Val.extranet_rate_plan_id); + this.HotelRoomContractForm.get('extranet_meal_plan_id').setValue(Val.extranet_meal_plan_id); + this.HotelRoomContractForm.get('nationality_applicable_type').setValue(Val.nationality_applicable_type); + this.HotelRoomContractForm.get('nationality_type').setValue(Val.nationality_type); + this.HotelRoomContractForm.get('residence_applicable_type').setValue(Val.nationality_applicable_type); + this.HotelRoomContractForm.get('residence_type').setValue(Val.nationality_type); + this.HotelRoomContractForm.get('date_type').setValue(Val.date_type); + this.HotelRoomContractForm.get('is_meal_addon_applicable').setValue(Val.is_meal_addon_applicable); + this.Meal_Plan_Show(); + this.Rate_Plan_Check(); + if(Val.nationality_applicable_type == 'SPECIFIC'){ + this.NationalityShowhide(Val.nationality_applicable_type); + this.HotelRoomContractForm.get('nationality').setValue(Val.nationality ? Val.nationality.split(','):[]); + this.CountryList = Val.country ? JSON.parse(Val.country) : []; + } + if(Val.nationality_applicable_type == 'SPECIFIC'){ + this.ResidenceShowhide(Val.nationality_applicable_type); + this.HotelRoomContractForm.get('residence').setValue(Val.residence ? Val.residence.split(','):[]); + this.CountryList = Val.country ? JSON.parse(Val.country) : []; + } + if(Val.is_meal_addon_applicable){ + this.MealHideShow(Val.is_meal_addon_applicable); + this.HotelRoomContractForm.get('extranet_meal_addon_id').setValue(Val.extranet_meal_addon_id ? Val.extranet_meal_addon_id.split(','):[]); + } + if (Val.ExtranetRoomContractRate) { + Val.ExtranetRoomContractRate.forEach((data,ind) => { + Val.ExtranetRoomContractRate[ind]['days'] = data.days ? data.days.split(',') : []; + for (let i = 0; i < Val.ExtranetRoomContractRate[ind]['days'].length; i++) { + Val.ExtranetRoomContractRate[ind]['days'][i] = Val.ExtranetRoomContractRate[ind]['days'][i][0].toUpperCase() + Val.ExtranetRoomContractRate[ind]['days'][i].substr(1); + } + }) + Val.ExtranetRoomContractRate.forEach((formvalue,formInd)=>{ + if(formInd == 0){ + this.AddRemoveRoomContract(this.HotelRoomContractForm.get('room_name').value, Val); + } + if(formInd > 0){ + // this.AddCancelArr(0,Val.ExtranetRoomContractCancellationPolicy[formInd]); + this.AddContractArr(0,formvalue.extranet_room_id,formvalue); + } + }); + } + if(Val.ExtranetRoomContractCancellationPolicy){ + Val.ExtranetRoomContractCancellationPolicy.forEach((cancellation_data,cancel_ind)=>{ + if(cancel_ind > 0){ + this.AddCancelArr(0,cancellation_data); + } + }) + } + this.ShowDateTypeFields(Val.date_type); + if(Val.date_type == 'SPECIFICDATES'){ + let date_arr = Val.contract_dates ? JSON.parse(Val.contract_dates) : []; + date_arr.forEach((date_data,date_ind)=>{ + if(date_ind)this.addDate(); + this.HotelRoomContractForm.controls['ContractDatesArr']['controls'][date_ind].get('date').setValue([new Date(date_data.date_from),new Date(date_data.date_to)]) + }) + }else if(Val.date_type == 'SEASON'){ + this.HotelRoomContractForm.get('Season_Id').setValue(Val.season ? Val.season.split(',') : []); + this.SeasonDataAddRemove(); + } + if(this.Clone_Rule){ + this.HotelRoomContractForm.disable(); + } + } + } +} \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.html b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.html new file mode 100644 index 0000000..b37264f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.html @@ -0,0 +1,244 @@ +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    +
    + +
    +
    +
    + + + +
    + +
    +
    Adult Pricing
    +
    + + + + + + + + + + + + + + + + + + + +
    Occupancy +
    + 1 Adult + +
    +
    + 2 Adult + + 3 Adult + + 4 Adult + + 1 Adult + + 2 Adult + + 3 Adult + + 4 Adult +
    Price +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    Child Pricing
    +
    + + + + + + + + + + + +
    + Child Age Range + + Occupancy + + Charges +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    Child Extrabed
    +
    + + + + + + + + + + + + + +
    + Child Age Range + + Extrabed Included +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.ts new file mode 100644 index 0000000..2d0c555 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'sub-tab1', + templateUrl: './sub-tab1.component.html', +}) +export class SubTab1Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.html b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.html new file mode 100644 index 0000000..1b9fd1f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.html @@ -0,0 +1,194 @@ +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Allocation Type

    +
    + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + Meal Add On +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + +
    +
    +
    +
    Adult Pricing
    +
    + + + + + + + + + + + + + + + + + + + +
    Occupancy + 1 Adult + + 2 Adult + + 3 Adult + + 4 Adult + + 1 Adult + + 2 Adult + + 3 Adult + + 4 Adult +
    Price +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    Child Pricing
    +
    + + + + + + + + + + + + + +
    + Child Age Range + + Occupancy + + Extrabed Included + + Charges +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.ts new file mode 100644 index 0000000..4f0df6f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'sub-tab2', + templateUrl: './sub-tab2.component.html', +}) +export class SubTab2Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.html b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.html new file mode 100644 index 0000000..1b9fd1f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.html @@ -0,0 +1,194 @@ +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Contract Days

    +
    + +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    +

    Allocation Type

    +
    + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + Meal Add On +
    +
    + + + +
    +
    +
    +

    Meals

    +
    + +
    +
    +
    + +
    +
    +
    +
    Adult Pricing
    +
    + + + + + + + + + + + + + + + + + + + +
    Occupancy + 1 Adult + + 2 Adult + + 3 Adult + + 4 Adult + + 1 Adult + + 2 Adult + + 3 Adult + + 4 Adult +
    Price +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    Child Pricing
    +
    + + + + + + + + + + + + + +
    + Child Age Range + + Occupancy + + Extrabed Included + + Charges +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.ts new file mode 100644 index 0000000..af57c91 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'sub-tab3', + templateUrl: './sub-tab3.component.html', +}) +export class SubTab3Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.html b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.html new file mode 100644 index 0000000..b1f5dc1 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.html @@ -0,0 +1,304 @@ +
    +
    +
    +

    Room Contract

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Room Name

    +
    + +
    +
    +
    + Select + {{data.room_name + (data.room_view_name ? ', ' : '') + + data.room_view_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Rate Plan

    +
    + +
    +
    +
    + Select + {{data.rate_plan_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Meal Plan

    +
    + +
    +
    +
    + Select + {{data.meal_plan_name}} +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Contract Status + + + + Contract Id + + + + Contract Name + + + + Room Id + + + + Room Name + + + + Rate Plan + + + + Meal Plan + + + + Nationality Type + + + + Nationality Applicability + + + + Nationality + + + + Date Range/Season + + + + Currency + + + + Meal Add On + + + + Meals + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + + Last updated + + + Action + + + + + + + {{data.status}} + + + {{data.extranet_contract_id}} + {{data.contract_name}} + {{data.extranet_room_id}} + {{data.room_name}} + {{data.rate_plan_name}} + {{data.meal_plan_name}} + {{data.nationality_type}} + {{data.nationality_applicable_type}} + {{data.nationality}} + {{item}} + {{data.currency_code}} + {{data.is_meal_addon_applicable}} + {{data.addon_name}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + {{data.last_updated}} + +
    + + + + + + + + + + + + +
    + + +
    + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.ts new file mode 100644 index 0000000..82eca1f --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.component.ts @@ -0,0 +1,175 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { forkJoin } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'rate-setting', + templateUrl: './rate-setting.component.html', +}) +export class RateSettingComponent implements OnInit { + displayPosition: boolean; + position: string; + Extranet_Hotel_Id; + AllMealPlan; + AllRatePlan; + Result; + AllRoomsData; + ExtranetMealPlan; + ExtranetRatePlan; + HotelRoomContractForm:FormGroup; + ExtranetRoom; + cols; + constructor(public activateRoute:ActivatedRoute,private router:Router, public apiserv:API,public _commonService:CommonFunctionService, + public validserv:ValidationService,public fb:FormBuilder) { } + + ngOnInit(): void { + this.Extranet_Hotel_Id = this.activateRoute.snapshot.paramMap.get('Hotel_Eaxtranet_Id') as string; + this.cols = [ + { field: 'extranet_contract_id', header: 'Contract Id' }, + { field: 'contract_name', header: 'Contract Name' }, + { field: 'extranet_room_id', header: 'Room Id' }, + { field: 'room_name', header: 'Room Name' }, + { field: 'rate_plan_name', header: 'Rate Plan' }, + { field: 'meal_plan_name', header: 'Meal Plan' }, + { field: 'nationality_type', header: 'Nationality Type' }, + { field: 'nationality_applicable_type', header: 'Nationality Applicability' }, + { field: 'nationality', header: 'Nationality' }, + { field: 'date_range', header: 'Date Range/Season' }, + { field: 'currency_code', header: 'Currency' }, + { field: 'is_meal_addon_applicable', header: 'Meal Add On' }, + { field: 'addon_name', header: 'Meals' }, + { field: 'status', header: 'Contract Status' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + { field: 'last_updated', header: 'Last Updated' }, + ]; + this.getAllData(); + this.HotelRoomContractForm = this.fb.group({ + contract_name:this.validserv.required, + }) + } + getAllData() { + forkJoin( + this.GetAllRooms(), + this.GetAllPlan(), + this.GetAllMealPlan() + ).subscribe(res=>{ + if(res && res.length > 0){ + this.AllRoomsData = res[0] ? res[0].data : []; + this.AllRatePlan = res[1] ? res[1].data : []; + this.AllMealPlan = res[2].data; + } + }); + } + showPositionDialog(position) { + this.position = position; + this.displayPosition = true; + }; + GetAllPlan(){ + return this.apiserv.Get('/ExtranetRoomContract/GetAllExtranetHotelRatePlan/EN') + } + GetAllMealPlan(){ + return this.apiserv.Get('/ExtranetMealAddon/GetAllExtranetMeal/EN') + } + GetAllRooms(){ + let ReqObj = { + extranet_hotel_id : this.Extranet_Hotel_Id, + extranet_room_id : '', + room_name : '', + room_view_name : '', + } + return this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetHotelRoomName',ReqObj) + } + updateStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetRoomContract/UpdateExtranetRoomContractStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + Search(){ + let ReObj = { + extranet_hotel_id:this.Extranet_Hotel_Id, + extranet_room_id:this.ExtranetRoom ? this.ExtranetRoom : '', + extranet_rate_plan_id:this.ExtranetRatePlan ? this.ExtranetRatePlan : '', + extranet_meal_plan_id:this.ExtranetMealPlan ? this.ExtranetMealPlan : '' + } + this.apiserv.Post('/ExtranetRoomContract/GetAllExtranetRoomContract',ReObj).subscribe(res=>{ + if (res) { + this.Result = res.data ? res.data : []; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['nationality_type'] = this.getNationalityType(e['nationality_type']) ; + e['nationality_applicable_type'] = this.getNationalityApplicabilityType(e['nationality_applicable_type']) ; + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + e['date_range_arr'] = e['contract_dates'] ? JSON.parse(e['contract_dates']) : []; + if(typeof(e['date_range_arr']) != 'string'){ + e.date_range_arr.forEach((data,ind)=>{ + e.date_range_arr[ind] = moment(data.date_from).format('DD MMM YYYY') + ' - ' + moment(data.date_to).format('DD MMM YYYY'); + }) + } + e['date_range'] = e.date_range_arr.length > 0 ? e.date_range_arr.join(',') : ''; + }); + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + } + } + }) + } + Reset(){ + this.ExtranetMealPlan = undefined; + this.ExtranetRatePlan = undefined; + this.ExtranetRoom = undefined; + } + Update(Id,pagename){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/${pagename}/${this.Extranet_Hotel_Id}/${Id}`); + } + EditContract(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/RoomContractEdit/${this.Extranet_Hotel_Id}/${Id}`); + } + getNationalityType(value){ + if(value == 'INCLUDE'){ + return 'Include' + }else if(value == 'EXCLUDE'){ + return 'Exclude' + } + return '' + } + getNationalityApplicabilityType(value){ + if(value == 'ALL'){ + return 'All' + }else if(value == 'SPECIFIC'){ + return 'Specific' + } + return '' + } + RoomView(Id){ + this.router.navigateByUrl(`Services/Hotel/HotelManage/CloneContract/${this.Extranet_Hotel_Id}/${Id}`); + } +} diff --git a/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.module.ts b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.module.ts new file mode 100644 index 0000000..eee06e5 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-manage/rate-setting/rate-setting.module.ts @@ -0,0 +1,73 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RateSettingComponent } from './rate-setting.component'; +import { RouterModule, Routes } from '@angular/router'; +import { MatMenuModule } from '@angular/material/menu'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FileUploadModule } from 'primeng/fileupload'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { RateSettingAddComponent } from './rate-setting-add/rate-setting-add.component'; +import { CalendarModule } from 'primeng/calendar'; +import { TabViewModule } from 'primeng/tabview'; +import { SubTab1Component } from './rate-setting-add/sub-tab-content/sub-tab1/sub-tab1.component'; +import { SubTab2Component } from './rate-setting-add/sub-tab-content/sub-tab2/sub-tab2.component'; +import { SubTab3Component } from './rate-setting-add/sub-tab-content/sub-tab3/sub-tab3.component'; +import { TooltipModule } from 'primeng/tooltip'; + +const routes: Routes = [ + { + path: 'RoomContractAdd/:Hotel_Eaxtranet_Id', + component:RateSettingAddComponent, + }, + { + path: 'RoomContractEdit/:Hotel_Eaxtranet_Id/:RuleId', + component:RateSettingAddComponent, + }, + { + path: 'CloneContract/:Hotel_Eaxtranet_Id/:RuleId', + component:RateSettingAddComponent, + }, +] + +@NgModule({ + declarations: [ + RateSettingComponent, + RateSettingAddComponent, + SubTab1Component, + SubTab2Component, + SubTab3Component + ], + imports: [ + CommonModule, + ToastModule, + TableModule, + DialogModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + TooltipModule, + MatCheckboxModule, + ButtonModule, + FileUploadModule, + NgSelectModule, + TabViewModule, + RouterModule.forChild(routes), + ], + exports:[ + RateSettingComponent + ] +}) +export class RateSettingModule { } diff --git a/src/app/modules/services/hotel/hotel-search/hotel-search.component.html b/src/app/modules/services/hotel/hotel-search/hotel-search.component.html new file mode 100644 index 0000000..a2dbab8 --- /dev/null +++ b/src/app/modules/services/hotel/hotel-search/hotel-search.component.html @@ -0,0 +1,312 @@ +
    +
    +
    +

    Hotel Search

    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Hotel Name

    +
    + +
    +
    +
    + + {{item.hotelName }} {{item.cityName }}, {{item.countryName }} + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Vendor Name

    +
    + +
    +
    +
    + Select + {{data.vendor_name}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Star Rating

    +
    + +
    +
    +
    + Select + 1 Star + 2 Star + 3 Star + 4 Star + 5 Star +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + + {{item.cityName }}, {{item.countryName }} + +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Status

    +
    + +
    +
    +
    + Select + Active + Deactive +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + + Status + + + + Hotel Name + + + + Hotel Mapping Code + + + + Vendor Name + + + + Star Rating + + + + Country + + + + City + + + + Currency + + + + Extranet Hotel Id + + + + Created By + + + + Created On + + + + Updated By + + + + Updated On + + + Action + + + + + + + {{data.status}} + + + {{data.hotel_name}} + {{data.hotel_code_mapping}} + {{data.vendor_name}} + {{data.star_rating}} + {{data.country}} + {{data.city}} + {{data.currency}} + {{data.extranet_hotel_id}} + {{data.created_by}} + {{data.Custom_created_on}} + {{data.updated_by}} + {{data.Custom_updated_on}} + + + + + + + + + + + + + No data found + + +
    +
    \ No newline at end of file diff --git a/src/app/modules/services/hotel/hotel-search/hotel-search.component.ts b/src/app/modules/services/hotel/hotel-search/hotel-search.component.ts new file mode 100644 index 0000000..e7d9f7b --- /dev/null +++ b/src/app/modules/services/hotel/hotel-search/hotel-search.component.ts @@ -0,0 +1,226 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { API } from 'src/app/core/services/api.service'; +import { environment } from 'src/environments/environment'; + +@Component({ + selector: 'app-hotel-search', + templateUrl: './hotel-search.component.html', +}) +export class HotelSearchComponent implements OnInit { + + constructor(private apiserv: API, public fb: FormBuilder, public _commonService: CommonFunctionService, private router: Router, private hotelmanageserv: ManageHotelService) { } + timer; + Result; + HotelList; + AllVendors; + cols; + Cdn_url = environment.cdnFileUrl; + All + ddLoader = { + Country: false, + city: false, + hotel_list: false, } + CountryList; + CityList; + HotelSearchForm: FormGroup; + ngOnInit(): void { + this.HotelSearchForm = this.fb.group({ + hotel_code_mapping: '', + vendor_id: '', + star_rating: '', + country_code: null, + city_code: null, + is_active: '' + }); + this.cols = [ + { field: 'hotel_name', header: 'Hotel Name' }, + { field: 'hotel_code_mapping', header: 'Hotel Mapping Code' }, + { field: "vendor_name", header: 'Vendor Name' }, + { field: 'star_rating', header: 'Star Rating' }, + { field: 'country', header: 'Country' }, + { field: 'city', header: 'City' }, + { field: 'currency', header: 'Currency' }, + { field: 'status', header: 'Status' }, + { field: 'extranet_hotel_id', header: 'Extranet Hotel Id' }, + { field: 'created_by', header: 'Created By' }, + { field: 'Custom_created_on', header: 'Created On' }, + { field: 'updated_by', header: 'Updated By' }, + { field: 'Custom_updated_on', header: 'Updated On' }, + ]; + this.GetallVendors(); + } + + getCountryList(event) { + if (event.value.length >= 2) { + this.ddLoader['Country'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGet(`/MasterSearch/GetAllCountry/en/${event.value}`).subscribe(res => { + if (res) { + this.CountryList = res; + this.ddLoader['Country'] = false; + } + }); + }, 500); + } + } + GetallVendors(){ + this.apiserv.Get('/ExtranetHotel/GetAllVendorNameByOrg').subscribe(res => { + if(res && res.data){ + this.AllVendors = res.data; + } + }) + + } + getHotelCitySearch(event) { + if (event.value.length >= 2) { + let reqObj = { + cityName: event.value, + languageCode: 'en', + lattitude: '0', + longitude: '0' + } + this.ddLoader.city = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost("/Hotel/GetHotelCities", reqObj).subscribe(res => { + if (res) { + this.CityList = res.cities; + this.ddLoader.city = false; + } + }); + }, 500); + } + if (!event.value) { + this.CityList = []; + } + }; + Search() { + let val = this.HotelSearchForm.getRawValue(); + let ReqObj = { + hotel_code_mapping: val.hotel_code_mapping ? val.hotel_code_mapping : '', + vendor_id: val.vendor_id ? val.vendor_id : '', + star_rating: val.star_rating ? parseInt(val.star_rating) : 0, + country_code: val.country_code ? val.country_code : '', + city_code: val.city_code ? val.city_code : '', + is_active: val.is_active ? val.is_active : '' + } + this.apiserv.Post('/ExtranetHotel/GetAllExtranetHotel', ReqObj).subscribe(res => { + if (res) { + this.Result = res.data ? res.data :[]; + if (res.data) { + this.Result.forEach(e => { + e['status'] = e.is_active ? 'Active' : 'Deactive'; + e['Custom_updated_on'] = this._commonService.convertDateWithTimeToShow(e.updated_on); + e['Custom_created_on'] = e['created_on'] ? this._commonService.convertDateWithTimeToShow(e.created_on) : e['created_on']; + }); + // customSort(event: SortEvent) { + this.Result.sort((a: any, b: any) => { + // Sort by status: Active first, then Deactive + if (a.status !== b.status) { + return a.status === 'Active' ? -1 : 1; + } + + // If both are Active, sort by activeDate + if (a.status === 'Active') { + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + } + + // If both are Deactive, sort by deactiveDate + return new Date(b.updated_on).getTime() - new Date(a.updated_on).getTime(); + }); + // } + } + } + }) + } + updateStatus(id, val) { + let obj = { + Id: id, + Status: val ? false : true, + }; + this.apiserv.Post('/ExtranetHotel/UpdateExtranetHotelStatus', obj).subscribe(res => { + if (res) { + this._commonService.showMessage(res['status'], res['message']); + res['status'] ? this.Search() : ''; + } + }); + } + ManageHotel(Id) { + this.hotelmanageserv.Active_tab = 'OverView' + this.router.navigateByUrl(`Services/Hotel/HotelManage/${Id}`); + } + Reset() { + this.HotelSearchForm = this.fb.group({ + hotel_code_mapping: '', + vendor_id: '', + star_rating: '', + country_code: null, + city_code: null, + is_active: '' + }); + } + + GetHotels(event){ + if (event.value.length >= 2) { + let obj ={ + languageCode:'en', + cityName:event.value, + lattitude:'0', + longitude:'0', + } + this.ddLoader['hotel_list'] = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.apiserv.AdminGoPost(`/Hotel/GetHotels`,obj).subscribe(res => { + if (res) { + this.HotelList = res.hotels; + this.ddLoader['hotel_list'] = false; + } + }); + }, 500); + } +} +btnClick() { + this.router.navigateByUrl("Services/Hotel/HotelAdd"); + } + SelectImage(e, filedata, extranet_hotel_id) { + if (e.currentFiles.length != 0) { + let file = e.files[0]; + if (file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { + const reader = new FileReader(); + console.log(file) + reader.readAsText(file); // Read as binary data + reader.onload = (res) => { + const binaryString = res.target.result as string; + const hasScriptTag = this._commonService.hasScriptTagInBinary(binaryString); + if (hasScriptTag) { + filedata.clear(); + this._commonService.showMessage(false, 'Invalid file (contains script tag)'); + } else { + //base 64 + // this.HotelRoomForm.get(contol).setValue(file); + // if (fileInfo && fileInfo.length > 0 && fileArr && fileArr.length > 0) { + let formdata = new FormData(); + // fileArr.forEach((x) => { + formdata.append("file", file); + formdata.append("extranet_hotel_id", extranet_hotel_id); + // }); + filedata.clear(); + // let file_info_list = JSON.stringify(fileInfo).replaceAll('ExtranetRoomId', edit_id); + this.apiserv.PostFileExtranet("/ExtranetHotelUpload/UploadHotelContrctFromFile", formdata).subscribe(res=>{ + if(res){ + this._commonService.showMessage(res.status,res.message); + } + }); + // } + }; + } + } + } + } +} diff --git a/src/app/modules/services/hotel/hotel.component.html b/src/app/modules/services/hotel/hotel.component.html new file mode 100644 index 0000000..e69de29 diff --git a/src/app/modules/services/hotel/hotel.component.ts b/src/app/modules/services/hotel/hotel.component.ts new file mode 100644 index 0000000..cd3475a --- /dev/null +++ b/src/app/modules/services/hotel/hotel.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-hotel', + templateUrl: './hotel.component.html', +}) +export class HotelComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/services/hotel/hotel.module.ts b/src/app/modules/services/hotel/hotel.module.ts new file mode 100644 index 0000000..fff9c7a --- /dev/null +++ b/src/app/modules/services/hotel/hotel.module.ts @@ -0,0 +1,70 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { HotelComponent } from './hotel.component'; +import { HotelAddComponent } from './hotel-add/hotel-add.component'; +import { HotelSearchComponent } from './hotel-search/hotel-search.component'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CalendarModule } from 'angular-calendar'; +import { DialogModule } from 'primeng/dialog'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; +import { ToolbarModule } from 'primeng/toolbar'; +import { ButtonModule } from 'primeng/button'; +import { ManageHotelService } from 'src/app/core/services/HotelServices/manage-hotel.service'; +import { FileUploadModule } from 'primeng/fileupload'; + + +const routes: Routes = [ + { + path: 'HotelSearch', + component:HotelSearchComponent, + }, + { + path: 'HotelAdd', + component:HotelAddComponent, + }, + { + path: '', + component:HotelComponent, + }, + { + path: 'HotelManage', + loadChildren: () => + import('./hotel-manage/hotel-manage.module').then( + (m) => m.HotelManageModule + ), + }, +] +@NgModule({ + declarations: [ + HotelComponent, + HotelSearchComponent, + HotelAddComponent + ], + imports: [ + ToastModule, + TableModule, + DialogModule, + CommonModule, + FileUploadModule, + ToolbarModule, + MatMenuModule, + CalendarModule, + NgSelectModule, + InputTextModule, + ReactiveFormsModule, + FormsModule, + MatButtonModule, + MatCheckboxModule, + ButtonModule, + RouterModule.forChild(routes), + ], + providers:[ManageHotelService ] +}) +export class HotelModule { } diff --git a/src/app/modules/services/services.module.ts b/src/app/modules/services/services.module.ts new file mode 100644 index 0000000..011bea8 --- /dev/null +++ b/src/app/modules/services/services.module.ts @@ -0,0 +1,76 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +// import { ExpServicesComponent } from './activity-services/exp-services/exp-services.component'; + +const routes: Routes = [ + { + path: 'Hotel', + loadChildren: () => + import('./hotel/hotel.module').then( + (m) => m.HotelModule + ), + }, + { + path: 'ActivityInventory', + loadChildren: () => + import('./activity/activity.module').then( + (m) => m.ActivityModule + ), + }, + { + path: 'ActivityConfing', + loadChildren: () => + import('./activity-config/activity-config.module').then( + (m) => m.ActivityConfigModule + ), + }, + + { + path: 'ActivityServices', + loadChildren: () => + import( + './activity-services/activity-services.module' + ).then((m) => m.ActivityServicesModule), + }, + { + path: 'FlightServices', + loadChildren: () => + import('./flight-services/flight-services.module').then( + (m) => m.FlightServicesModule + ), + }, + { + path: 'FlightInventory', + loadChildren: () => + import('./flight-inventory/flight-inventory.module').then( + (m) => m.FlightInventoryModule + ), + }, + { + path: 'FlightInventoryReport', + loadChildren: () => + import('./flight-inventory-report/flight-inventory-report.module').then( + (m) => m.FlightInventoryReportModule + ), + }, + { + path: '', + pathMatch: 'full', + redirectTo: 'search', + }, +]; + +@NgModule({ + declarations: [ + + ], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + RouterModule.forChild(routes), + ], +}) +export class ServicesModule {} diff --git a/src/app/modules/user-configuration/role-management/role-add/role-add.component.html b/src/app/modules/user-configuration/role-management/role-add/role-add.component.html new file mode 100644 index 0000000..3fe37c3 --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-add/role-add.component.html @@ -0,0 +1,132 @@ + +
    +
    +
    +
    +

    Add Role Management

    +
    +
    +
    +
    +
    +
    + + + Please + enter role name +
    +
    +
    +
    + + + Please + enter role description +
    +
    +
    +
    + Role Type + + + Please + select role type +
    +
    + +
    +
    +
    +
    + + + + + {{ col.header }} + + + + + + + + + + + {{ rowData.menu_name }} + + + + +
    + + View +
    + + +
    + + Add +
    + + +
    + + Edit +
    + + +
    + + Download +
    + + +
    + + Status +
    + + +
    +
    +
    +
    + Active +
    +
    +
    + +
    +
    + \ No newline at end of file diff --git a/src/app/modules/user-configuration/role-management/role-add/role-add.component.ts b/src/app/modules/user-configuration/role-management/role-add/role-add.component.ts new file mode 100644 index 0000000..e8c6943 --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-add/role-add.component.ts @@ -0,0 +1,605 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TreeNode } from 'primeng/api'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { dtoRoleAccessMapping, dtoRoleMaster, dtoRoleMaster_Root } from 'src/app/core/models/user-role-management/user-role.model'; +import { API } from 'src/app/core/services/api.service'; + +interface Column { + field: string; + header: string; +} + +@Component({ + selector: 'app-role-add', + templateUrl: './role-add.component.html', +}) + +export class RoleAddComponent implements OnInit { + + constructor( + private router: Router, + private ApiServ: API, + public fb: FormBuilder, + public validationServ: ValidationService, + public route: ActivatedRoute, + public commonServ: CommonFunctionService + ) { } + files!: TreeNode[]; + selectedNodes: TreeNode[] = [] + HeaderList!: Column[]; + formdata: FormGroup; + allStaff; + EditId; + newMenuList = []; + RoleAccessMapping = []; + AllMenuMasterNew; + roleAccessMappingdata; + roleType = [ + { value: 'Extranet', label: 'Extranet' } + ] + ngOnInit(): void { + this.ngOnintForm(); + this.ngOinitEditForm(); + this.commonServ.LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + this.HeaderList = [ + { field: 'menu_name', header: 'Name' }, + { field: 'View', header: 'View' }, + { field: 'Add', header: 'Add' }, + { field: 'Edit', header: 'Edit' }, + { field: 'Download', header: 'Download' }, + { field: 'Status', header: 'Status' }, + ]; + } + ngOnintForm() { + let VData = JSON.parse(securityFunctions.getSessionStorage('VData')); + console.log(VData); + this.formdata = this.fb.group({ + role_name: this.validationServ.required, + reporting_role_id: [''], + role_description: this.validationServ.required, + role_type: ['Extranet'], + extranet_vendor_id: [VData.vendor_name], + is_active: [false] + }); + this.formdata.get('role_type').disable(); + this.formdata.get('extranet_vendor_id').disable(); + this.GetAllMenu(false); + }; + + + + /** + * @author Abdul razzak + * @description Copies and binds menu items based on the provided list. + * @param {array} list - The list of menu items to copy and bind. + */ + CopyBindMenu(list) { + let role_type = '2405170833594899108' + let aisemenu = []; + // Sort the list based on sequence + let FliterList = list.sort(function (a, b) { return a.sequence - b.sequence; }); + // Filter all parent menu items + let AllParentlist = list.filter(e => (role_type == '2405170833594899108' ? true : e.ui_controller == '') && e.parent_id == ''); + AllParentlist.forEach(e => { + // Check menu type and push data accordingly + if (e.menu_type == '2305170833594899101') { + aisemenu.push( + { + "data": { + "menu_name": e.menu_name, + "menu_id": e.menu_id, + "View": false, + "Add": false, + "Edit": false, + "Download": false, + "Status": false, + }, + // "parent": null, + "children": [] + } + ); + } else { + aisemenu.push( + { + "data": { + "menu_name": e.menu_name, + "menu_id": e.menu_id, + "View": false, + "Add": false, + "Edit": false, + "Status": false, + "Download": false, + } + } + ); + } + let index = aisemenu.length - 1; + // Filter submenu items for the current parent menu + let submenu = FliterList.filter(s => s.parent_id == e.menu_id); + // If submenu items exist, recursively copy submenu + if (submenu.length > 0) { + this.CopysubMenu(aisemenu[index], submenu, FliterList); + } + }); + this.newMenuList = aisemenu; + } + /** + * @author Abdul Razzak + * @description Copies submenu items and binds them to the provided menu. + * @param {object} menu - The menu object to which submenu items are to be copied and bound. + * @param {array} FilterSubmenu - The list of submenu items to copy and bind. + * @param {array} Allmenu - The list of all menu items. + */ + CopysubMenu(menu, FilterSubmenu, Allmenu) { + if (FilterSubmenu.length > 0) { + FilterSubmenu.forEach(e => { + // Check menu type and push data accordingly + if (e.menu_type == '2305170833594899101') { + menu.children.push( + { + "data": { + "menu_name": e.menu_name, + "menu_id": e.menu_id, + "View": false, + "Add": false, + "Edit": false, + "Download": false, + "Status": false, + }, + "children": [] + } + ); + } else { + menu.children.push( + { + "data": { + "menu_name": e.menu_name, + "menu_id": e.menu_id, + "View": false, + "Add": false, + "Edit": false, + "Download": false, + "Status": false, + } + } + ); + } + let index = menu.children.length - 1; + // Filter submenu items for the current submenu + let submenu = Allmenu.filter(a => a.parent_id == e.menu_id); + // If submenu items exist, recursively copy submenu + if (submenu.length > 0) { + this.CopysubMenu(menu.children[index], submenu, Allmenu); + } + }) + } + } + /** + * @author Abdul Razzak + * @description Checks data against provided list and updates selectedNodes accordingly. + * @param data - The data object to be checked. + * @param list - The list object containing flags for Add, Edit, and View. + * @param name - The name of the property to be updated in data.node.parent. + */ + checkData(data, list, name) { + // If View permission is not granted, disable Add and Edit + if (!list.View) { + list.Add = false + list.Edit = false + list.Status = false + list.Download = false + }; + // If Add, Edit, and View permissions are granted, add data.node to selectedNodes + if (list.Add && list.Edit && list.View && list.Download && list.Status) { + this.selectedNodes = [...this.selectedNodes, data.node]; + } + // If any of the permissions are not granted, remove data.node from selectedNodes + else if (!list.Add || !list.Edit || !list.View || list.Status || list.Download) { + this.selectedNodes = this.selectedNodes.filter(selectedNode => selectedNode !== data.node); + }; + // Update parent data property if any of the permissions are granted + if (list.Add || list.Edit || list.View || list.Status || list.Download) { + if (data.node.parent) { + data.node.parent.data[name] = true; + } + }; + // Recursively check children nodes + if (data.node.children) this.CheeckcolumLevel(data, name, list[name]); + // Check if any parent or child nodes are checked + let parentdata = this.getParentNode(data.node); + this.isAnyParentOrChildChecked(parentdata); + }; + + + /** + * @author Abdul Razzak + * @description Function to check if any child node has properties (View, Edit, Add) set to true + * @param node + * @returns boolen + */ + isAnyChildChecked(node): any { + // If node has no children, check its own properties + if (!node.children || node.children.length === 0) { + return node.data.View || node.data.Edit || node.data.Add || node.data.Download || node.data.Status; + } + // If node has children, check each child recursively + for (const child of node.children) { + if (this.isAnyChildChecked(child)) { + return true; // If any child or its descendants are checked, return true + } + } + // If none of the children or their descendants are checked, return false + return false; + } + + /** + * @author Abdul Razzak + * @description Checks if any parent or child nodes are checked and updates their partialSelected property accordingly. + * @param {object} node - The node to check for parent or child checked status. + */ + isAnyParentOrChildChecked(node) { + if (!node) return; + // Check if any child nodes are checked + let isChildChecked = this.isAnyChildChecked(node); + // Check if all children are checked + let parentlevel = this.areAllChildrenChecked(node); + // Set partialSelected property for the current node based on child checked status + if (node.children && (isChildChecked) && !parentlevel) { + node.partialSelected = true; + this.selectedNodes = this.selectedNodes.filter(selectedNode => selectedNode !== node); + } else { + if (node.children && (isChildChecked)) { + node.partialSelected = true; + } else node.partialSelected = false + if (parentlevel) { + node.partialSelected = false + this.selectedNodes = [...this.selectedNodes, node]; + } + } + // Recursively set partialSelected property for all children + if (node.children) { + for (const child of node.children) { + this.isAnyParentOrChildChecked(child); + } + } + } + + /** + * @author Abdul Razzak + * @description Checks the parent level permissions for a given node and its children. + * @param {object} data - The data object containing the node whose permissions are to be checked. + * @param {boolean} val - The value to set for Add, Edit, and View permissions. + */ + CheckParentLevel(data, val) { + if (data.node) { + // Set Add, Edit, and View permissions for the current node + data.node.data.Add = val; + data.node.data.Edit = val; + data.node.data.View = val; + data.node.data.Status = val; + data.node.data.Download = val; + // Recursively check child level permissions if children exist + data.node['children'] ? this.checkchildLevel(data.node['children'], val) : ''; + }; + }; + /** + * @author Abdul Razzak + * @description Checks the child level permissions for a given submenu and its children. + * @param {array} submenu - The array containing submenu items whose permissions are to be checked. + * @param {boolean} val - The value to set for Add, Edit, and View permissions. + */ + checkchildLevel(submenu, val) { + submenu.forEach(e => { + // Set Add, Edit, and View permissions for each submenu item + e.data.Add = val; + e.data.Edit = val; + e.data.Status = val; + e.data.Download = val; + e.data.View = val; + if (e['children']) { + // Recursively check child level permissions if children exist + this.checkchildLevel(e['children'], val); + } + }) + }; + + + /** + * @author Abdul Razzak + * @description Checks the column level permissions for a given node and its children. + * @param {object} data - The data object containing the node whose permissions are to be checked. + * @param {string} name - The name of the permission to be checked (e.g., 'View', 'Add', 'Edit'). + * @param {boolean} val - The value to set for the specified permission. + */ + CheeckcolumLevel(data, name, val) { + if (data.node) { + // Set Add and Edit permissions to false if View permission is set to false + name == 'View' && !val ? data.node.data.Add = val : ''; + name == 'View' && !val ? data.node.data.Edit = val : ''; + name == 'View' && !val ? data.node.data.Status = val : ''; + name == 'View' && !val ? data.node.data.Download = val : ''; + // Set the specified permission for the current node + data.node.data[name] = val; + // Recursively set column level permissions for children if they exist + data.node['children'] ? this.SetchildcolumLevel(data.node['children'], name, val) : ''; + } + }; + + /** + * @author Abdul Razzak + * @description Sets the column level permissions for children submenu items. + * @param {array} submenu - The array containing submenu items whose permissions are to be set. + * @param {string} name - The name of the permission to be set (e.g., 'View', 'Add', 'Edit'). + * @param {boolean} val - The value to set for the specified permission. + */ + SetchildcolumLevel(submenu, name, val) { + submenu.forEach(e => { + // Set Add and Edit permissions to false if View permission is set to false + name == 'View' && !val ? e.data.Add = val : ''; + name == 'View' && !val ? e.data.Edit = val : ''; + name == 'View' && !val ? e.data.Status = val : ''; + name == 'View' && !val ? e.data.Download = val : ''; + // Set the specified permission for the submenu item + if (name != 'View') e.data.View ? e.data[name] = val : ''; + else e.data[name] = val; + // Update selectedNodes based on permissions + if (e.data.Add && e.data.Edit && e.data.View && e.data.Status && e.data.Download) { + this.selectedNodes = [...this.selectedNodes, e]; + } else if (!e.data.Add || !e.data.Edit || !e.data.View || e.data.Status || e.data.Download) { + this.selectedNodes = this.selectedNodes.filter(selectedNode => selectedNode !== e); + }; + // Recursively set column level permissions for children if they exist + if (e['children']) { + this.SetchildcolumLevel(e['children'], name, val); + } + }) + + }; + + /** + * @author Abdul Razzak + * @description Checks a TreeNode and adds it to the selectedNodes if it's not already included. + * @param {TreeNode} node - The TreeNode to be checked and added. + */ + checkNode(node: TreeNode) { + if (!this.selectedNodes.includes(node)) { + this.selectedNodes = [...this.selectedNodes, node]; + } + }; + /** + * @author Abdul Razzak + * @description Finds a TreeNode with the specified menu ID within an array of TreeNode objects. + * @param {TreeNode[]} nodes - The array of TreeNode objects to search. + * @param {number} menuId - The menu ID to search for. + * @returns {TreeNode | null} - The matching TreeNode if found, otherwise null. + */ + findMatchingNode(nodes: TreeNode[], menuId: number): TreeNode | null { + for (const node of nodes) { + if (node.data.menu_id === menuId) { + return node; + } + if (node.children) { + const matchingChild = this.findMatchingNode(node.children, menuId); + if (matchingChild) { + return matchingChild; + } + } + } + + return null; + }; + + /** + * @author Abdul Razzak + * @description Checks if all children and their descendants of a TreeNode are checked. + * @param {TreeNode} node - The TreeNode to check. + * @returns {boolean} - True if all children and their descendants are checked, otherwise false. + */ + areAllChildrenChecked(node): boolean { + if (!node.children || node.children.length === 0) { + // If node has no children, return true if node's permissions are all true + return node.data.View && node.data.Edit && node.data.Add && node.data.Download && node.data.Status; + } + for (const child of node.children) { + // Recursively check all children and their descendants + if (!this.areAllChildrenChecked(child)) { + return false; // If any child or its descendants are not checked, return false + } + } + return true; // All children and their descendants are checked + }; + + /** + * @author Abdul Razzak + * @description Recursively finds the topmost parent node of the given node. + * @param node - The node whose parent is to be found. + * @returns - The topmost parent node. + */ + getParentNode(node) { + // If node has a parent, recursively call getParentNode with the parent node + if (node.parent) { + return this.getParentNode(node.parent); // Return the result of the recursive call + } else { + // If node has no parent, return the node itself (topmost parent) + return node; + } + }; + + ngOinitEditForm() { + this.EditId = this.route.snapshot.paramMap.get('RuleId') as string; + if (this.EditId) { + this.ApiServ.AdminGet("/RoleMaster/GetAllRoleByRoleId_Root/" + this.EditId).subscribe((res) => { + if (res.respObj) { + this.setValue(res.respObj); + } + }); + } + }; + + /** + * @author Abdul Razzak + * @description Sets values for form fields based on the provided data. + * @param {object} data - The data object containing roleMaster and roleAccessMapping information. + */ + setValue(data) { + if (data.roleMaster) { + this.formdata.get('role_name').setValue(data.roleMaster['role_name']); + this.formdata.get('role_description').setValue(data.roleMaster['role_description']); + this.formdata.get('role_type').setValue(data.roleMaster['role_type']); + this.formdata.get('is_active').setValue(data.roleMaster['is_active']); + this.GetAllMenu(true); + } + this.roleAccessMappingdata = data.roleAccessMapping; + }; + /** + * @author Abdul Razzak + * @description Sets role access mapping based on the provided roleAccessMappingdata. + */ + setroleAccessMapping() { + if (this.roleAccessMappingdata) { + if (this.roleAccessMappingdata.length > 0) { + this.roleAccessMappingdata.forEach(r => { + let json = JSON.parse(r.permission) + if (json.View) { + let Obj = this.findMatchingNode(this.newMenuList, r.menu_id); + if (Obj) { + Obj.data['Add'] = json.Add; + Obj.data['Edit'] = json.Edit; + Obj.data['View'] = json.View; + Obj.data['Status'] = json.Status; + Obj.data['Download'] = json.Download; + if (Obj.data['Add'] && Obj.data['Edit'] && Obj.data['View'] && Obj.data['Status'] && Obj.data['Download']) { + this.selectedNodes = [...this.selectedNodes, Obj]; + } else if (!Obj.data['Add'] || !Obj.data['Edit'] || !Obj.data['View'] || Obj.data['Status'] || Obj.data['Download']) { + this.selectedNodes = this.selectedNodes.filter(selectedNode => selectedNode !== Obj); + }; + } + } + }) + this.newMenuList.forEach(e => { + let parentdata = this.getParentNode(e); + this.isAnyParentOrChildChecked(parentdata); + }) + } + } + }; + save() { + if (this.formdata.valid) { + let val = this.formdata.getRawValue(); + let postdata = new dtoRoleMaster() + postdata.reporting_role_id = ''; + postdata.role_description = val.role_description; + postdata.role_name = val.role_name; + postdata.role_type = val.role_type; + postdata.extranet_vendor_id = this.commonServ.LoginUserData.extranet_vendor_id; + postdata.is_active = val.is_active; + postdata.role_id = this.EditId ? this.EditId : ''; + this.RoleAccessMapping = []; + if (this.newMenuList.length > 0) { + this.newMenuList.forEach(MainObj => { + let e = MainObj.data + let PostdataArr = new dtoRoleAccessMapping(); + PostdataArr.project_id = ''; + PostdataArr.menu_id = e.menu_id; + PostdataArr.is_active = val.is_active; + let obj = {} + obj['View'] = e.View; + obj['Add'] = e.Add; + obj['Delete'] = e.Delete; + obj['Edit'] = e.Edit; + obj['Status'] = e.Status; + obj['Download'] = e.Download; + PostdataArr.permission = JSON.stringify(obj); + this.RoleAccessMapping.push(PostdataArr) + MainObj['children'] ? this.AddSubmenu(MainObj['children']) : ''; + }) + } + let postObj = new dtoRoleMaster_Root(); + postObj.roleMaster = postdata; + postObj.roleAccessMapping = this.RoleAccessMapping; + let url = this.EditId ? "UpdateRoleMaster_Root" : "SaveRoleMaster_Root"; + this.ApiServ.AdminPost("/RoleMaster/"+ url, postObj).subscribe( + (res) => { + if (res) { + res["resp"] ? this.showToastrMsg(res) : this.showToastrMsg(res); + } + } + ); + } else { + this.validationServ.showValidationsMsg(this.formdata); + } + }; + + /** + * @author Abdul Razzak + * @description Adds submenu items to the RoleAccessMapping array based on the provided data. + * @param {TreeNode[]} data - The array of TreeNode objects representing submenu items. + */ + AddSubmenu(data) { + let val = this.formdata.getRawValue(); + data.forEach(MainObj => { + let e = MainObj.data + let PostdataArr = new dtoRoleAccessMapping(); + PostdataArr.project_id = ''; + PostdataArr.menu_id = e.menu_id; + PostdataArr.is_active = val.is_active; + let obj = {} + obj['View'] = e.View; + obj['Add'] = e.Add; + obj['Delete'] = e.Delete; + obj['Edit'] = e.Edit; + obj['Status'] = e.Status; + obj['Download'] = e.Download; + PostdataArr.permission = JSON.stringify(obj); + this.RoleAccessMapping.push(PostdataArr); + MainObj['children'] ? this.AddSubmenu(MainObj.children) : '' + }); + }; + + showToastrMsg(respData) { + this.commonServ.showMessage(respData['resp'], respData['respMsg']); + setTimeout(() => { + respData["resp"] ? this.BackButton() : ""; + }, 500); + }; + + /** + * Navigates to the view page of Role Management when the back button is clicked. + */ + BackButton() { + this.router.navigateByUrl("UserConfiguration/RoleManagement/Search"); + }; + + + /** + * @author Abdul Razzak + * @description Retrieves all menu items based on the project ID and affiliate ID (if present), + * and updates the menu list accordingly. Optionally triggers role access mapping setting. + * @param {boolean} check - Indicates whether to set role access mapping after updating the menu list. + */ + GetAllMenu(check) { + this.commonServ.LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + if (this.commonServ.LoginUserData.extranet_vendor_id) { + this.ApiServ.AdminGet(`/MenuMasterNew/GetMenuMasterNewsByOrgId/2405170833594899108`).subscribe(res => { + if (res) { + this.AllMenuMasterNew = res; + this.CopyBindMenu(this.AllMenuMasterNew); + if (check) { + this.setroleAccessMapping() + } + } + }) + } else { + this.newMenuList = []; + } + }; + + backClick() { + this.router.navigateByUrl("/UserConfiguration/RoleManagement/Search"); + } + +} diff --git a/src/app/modules/user-configuration/role-management/role-management.component.html b/src/app/modules/user-configuration/role-management/role-management.component.html new file mode 100644 index 0000000..e69de29 diff --git a/src/app/modules/user-configuration/role-management/role-management.component.scss b/src/app/modules/user-configuration/role-management/role-management.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/modules/user-configuration/role-management/role-management.component.ts b/src/app/modules/user-configuration/role-management/role-management.component.ts new file mode 100644 index 0000000..24ec213 --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-management.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-role-management', + templateUrl: './role-management.component.html', + styleUrls: ['./role-management.component.scss'] +}) +export class RoleManagementComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/user-configuration/role-management/role-management.module.ts b/src/app/modules/user-configuration/role-management/role-management.module.ts new file mode 100644 index 0000000..4b25d47 --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-management.module.ts @@ -0,0 +1,68 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Routes, RouterModule } from '@angular/router'; +import { RoleViewComponent } from './role-view/role-view.component'; +import { RoleAddComponent } from './role-add/role-add.component'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TreeModule } from 'primeng/tree'; +import { TreeTableModule } from 'primeng/treetable'; +import { ButtonModule } from 'primeng/button'; +import { TreeSelectModule } from 'primeng/treeselect'; +import { CheckboxModule } from 'primeng/checkbox'; +import { TriStateCheckboxModule } from 'primeng/tristatecheckbox'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { NodeService } from 'src/app/core/services/nodeservice'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ToastModule } from 'primeng/toast'; +import { MessageService } from 'primeng/api'; +import { MatButtonModule } from '@angular/material/button'; + + +const routes: Routes = [ + { + path: 'Search', + component: RoleViewComponent, + }, + { + path: 'Add', + component: RoleAddComponent, + }, + { + path: 'Edit/:RuleId', + component: RoleAddComponent, + }, +] + + +@NgModule({ + declarations: [ + RoleViewComponent, + RoleAddComponent + ], + imports: [ + TableModule, + CommonModule, + MatMenuModule, + ToolbarModule, + ToastModule, + InputTextModule, + MatCheckboxModule, + TreeModule, + TreeSelectModule, + TreeTableModule, + ButtonModule, + CheckboxModule, + TriStateCheckboxModule, + FormsModule, + NgSelectModule, + MatButtonModule, + ReactiveFormsModule, + RouterModule.forChild(routes), + ], + providers: [NodeService,MessageService] +}) +export class RoleManagementModule { } diff --git a/src/app/modules/user-configuration/role-management/role-view/role-view.component.html b/src/app/modules/user-configuration/role-management/role-view/role-view.component.html new file mode 100644 index 0000000..96f32ff --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-view/role-view.component.html @@ -0,0 +1,145 @@ + +
    +
    +
    +

    Role Management

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + Role Id + + + Role Name + + + Role Type + + + + Vendor + + + Updated By + + + Updated On + + + Status + + + Action + + + + + + {{data.role_id}} + + {{data.role_name}} + + + {{data.role_type}} + + {{data.vendor_name}} + {{data.updated_by}} + {{data.Custom_updated_on }} + + + {{data.status}} + + + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/user-configuration/role-management/role-view/role-view.component.ts b/src/app/modules/user-configuration/role-management/role-view/role-view.component.ts new file mode 100644 index 0000000..31c92a2 --- /dev/null +++ b/src/app/modules/user-configuration/role-management/role-view/role-view.component.ts @@ -0,0 +1,90 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-role-view', + templateUrl: './role-view.component.html', +}) +export class RoleViewComponent implements OnInit { + + cols: any[]; + allStaff; + role_name = ''; + reporting_role_id = ''; + role_description = ''; + AllRole; + @ViewChild('dt') myTable; + constructor( + private router: Router, + private ApiServ: API, + public commonServ: CommonFunctionService + ) { } + + ngOnInit(): void { + this.cols = [ + { field: "role_id", header: "Role Id" }, + { field: "role_name", header: "Role Name" }, + { field: "role_type", header: "Role Type" }, + { field: "affiliate_name", header: "Agency Name" }, + { field: "role_description", header: "Role Description" }, + { field: "reporting_role_id", header: "Reporting Role Id" }, + { field: "updated_by", header: "Updated By" }, + { field: "updated_on", header: "Updated On" }, + { field: "status", header: "Status" }, + ]; + } + roleType = { + Extranet: 'Extranet', + } + + + Search() { + let LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + let searchObj = { + role_name: this.role_name, + role_description: this.role_description, + reporting_role_id: '', + extranet_vendor_id: LoginUserData.extranet_vendor_id, + } + this.ApiServ.AdminPost('/RoleMaster/GetAllRoleBySearchFilters', searchObj).subscribe(res => { + if (res) { + this.AllRole = res; + this.AllRole.forEach(e => { + e['role_type'] = this.roleType[e['role_type']] + e['status'] = e['is_active'] ? 'Active' : 'Deactive' + e['Custom_updated_on'] = this.commonServ.convertDateWithTimeToShow(e.updated_on); + }); + this.myTable ? this.myTable.first = 0 : ''; + } + }) + }; + + UpdateStatus(id, status) { + let obj = { + Id: id, + Status: status ? false : true, + }; + this.ApiServ.AdminPost("/RoleMaster/UpdateStatusRoleMaster", obj).subscribe( + (data) => { + if (data) { + this.commonServ.showMessage(data['resp'], data['respMsg']) + this.Search(); + } + } + ); + } + Edit(role_id) { + this.router.navigate(["UserConfiguration/RoleManagement/Edit/" + role_id]); + } + Reset() { + this.role_name = ''; + this.role_description = ''; + } + btnClick() { + this.router.navigateByUrl("/UserConfiguration/RoleManagement/Add"); + } + +} diff --git a/src/app/modules/user-configuration/user-configuration.module.ts b/src/app/modules/user-configuration/user-configuration.module.ts new file mode 100644 index 0000000..31ee954 --- /dev/null +++ b/src/app/modules/user-configuration/user-configuration.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Routes, RouterModule } from '@angular/router'; +import { UserManagementComponent } from './user-management/user-management.component'; +import { RoleManagementComponent } from './role-management/role-management.component'; + +const routes: Routes = [ + { + path: 'RoleManagement', + loadChildren: () => + import('./role-management/role-management.module').then( + (m) => m.RoleManagementModule + ), + }, + { + path: 'UserManagement', + loadChildren: () => + import('./user-management/user-management.module').then( + (m) => m.UserManagementModule + ), + }, +] + +@NgModule({ + declarations: [ + RoleManagementComponent, + UserManagementComponent + ], + imports: [ + CommonModule, + RouterModule.forChild(routes), + ] +}) +export class UserConfigurationModule { } diff --git a/src/app/modules/user-configuration/user-management/user-add/user-add.component.html b/src/app/modules/user-configuration/user-management/user-add/user-add.component.html new file mode 100644 index 0000000..ae87043 --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-add/user-add.component.html @@ -0,0 +1,350 @@ + +
    +
    +
    +
    +

    Add User Management

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + Please + enter name +
    +
    +
    +
    +
    + + + +
    +
    +
    +

    Contact Number

    +
    + +
    +
    +
    + {{ '(' + + data.MobileCode + +')' + ' ' + data.CountryName }} +
    + +
    +
    + +
    +
    + + Please enter a phone number + + please enter valid phone number + + The phone number should have a minimum of 5 digits + + + The phone number should not exceed 13 digit + +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Country

    +
    + +
    +
    +
    + + {{item.country_name }} + +
    + Please + select country +
    +
    +
    +
    + + + +
    +
    +
    +

    City

    +
    + +
    +
    +
    + +
    + Please + select city + +
    +
    +
    +
    + + + +
    +
    +
    +

    Timezone

    +
    + +
    +
    +
    + {{timeZone.Utc + + ' ' + + timeZone.Timezone_Description}} +
    + Please + select timezone +
    +
    +
    +
    + + + +
    +
    +
    +

    User Role

    +
    + +
    +
    +
    + +
    + Please + select user role +
    +
    +
    +
    + + + Please enter + email Id + Invalid + email Id +
    +
    +
    +
    + +
    + + +
    + Please + enter + password + Please + check + the + password criteria +
      +
      +
    • + One + lowercase + letter
    • +
    • + One + uppercase + letter
    • +
    • + One + number
    • +
      +
      +
    • + One + special character
    • +
    • + 8 + characters + minimum
    • +
      +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + New Password +
    + + +
    + Please + Enter + New Password + Please + check the + password criteria +
      +
    • + One + lowercase letter
    • +
    • + One + uppercase letter
    • +
    • + One + number +
    • +
    • + One special character
    • +
    • + 8 + characters minimum
    • +
    +
    +
    +
    +
    + Confirm New Password +
    + + +
    + Please + Enter Confirm Password +
    +
    +
    +
    + + + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/app/modules/user-configuration/user-management/user-add/user-add.component.ts b/src/app/modules/user-configuration/user-management/user-add/user-add.component.ts new file mode 100644 index 0000000..371af0e --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-add/user-add.component.ts @@ -0,0 +1,262 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { forkJoin, of } from 'rxjs'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { ValidationService } from 'src/app/core/common/validation.service'; +import { changeUserLoginPassword } from 'src/app/core/models/common-model/userModel'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-user-add', + templateUrl: './user-add.component.html', +}) +export class UserAddComponent implements OnInit { + + constructor( + private router: Router, + private activateRoute: ActivatedRoute, + public fb: FormBuilder, + public commonService: CommonFunctionService, + private ApiServ: API, + public validationService: ValidationService, + + ) { } + + formdata: FormGroup; + Editid = null + PasswordForm: FormGroup; + NewPass = false; + confirmPass = false; + AllCountryNamePhone = []; + TimeZonedata = []; + + ngOnInit(): void { + this.Editid = this.activateRoute.snapshot.paramMap.get('RuleId') as string; + this.pageSetUp(); + }; + pageSetUp() { + this.FormOnInit(); + this.GetAllData(); + + }; + GetAllData() { + forkJoin( + this.GetUserDetailsById(this.Editid), + this.GetAllCountryNamePhone(), + this.getAllTimezoneData() + ).subscribe(res => { + if (res && res.length > 0) { + if (res[0]) this.FormSetvalue(res[0]['Result']) + else this.GetRoleData();; + + if (!this.Editid) this.formdata.addControl('password', this.validationService.passwordV2); + this.AllCountryNamePhone = res[1]; + this.TimeZonedata = res[2]; + } + }) + }; + FormOnInit() { + let VData = JSON.parse(securityFunctions.getSessionStorage('VData')); + this.formdata = this.fb.group({ + vendor_name: [VData.vendor_name], + first_name: this.validationService.required, + user_mobile_country_code: this.validationService.required, + user_mobile: ['', [Validators.required, Validators.pattern("^[0-9]*$"), + Validators.minLength(5), Validators.maxLength(13)]], + email: this.validationService.email, + country: this.validationService.required, + timezone: this.validationService.required, + city: [{ value: null, disabled: true }, Validators.required], + is_active: [], + role_id: this.validationService.required, + extranet_vendor_id: [], + }); + }; + initPasswordForm() { + this.PasswordForm = this.fb.group({ + new_password: this.validationService.passwordV2, + Confirm_password: this.validationService.required + }) + }; + save() { + if (this.formdata.invalid) { + this.validationService.showValidationsMsg(this.formdata) + return + } + let value = this.formdata.getRawValue(); + let user_login = { + first_name: value.first_name, + user_mobile_country_code: value.user_mobile_country_code, + user_mobile: value.user_mobile, + email: value.email.trim(), + country: value.country, + timezone: value.timezone, + city: value.city, + role_id: value.role_id, + password: this.Editid ? '' : value.password, + user_id: this.userDetails?.user_id ? this.userDetails?.user_id : '', + extranet_vendor_id: this.commonService.LoginUserData.extranet_vendor_id, + user_type: this.userDetails?.user_type ? this.userDetails?.user_type : '210526104324609566', + }; + let url = this.Editid ? '/Update' : '/Save'; + this.ApiServ.AdminGoPost('/ExtranetUserMaster'+url, user_login).subscribe(res => { + if (res) { + this.commonService.showMessage(res.Resp, res.Message); + setTimeout(() => { + res.Resp ? this.backClick() : ''; + }, 500); + } + }) + }; + UpdateUserPassword() { + let formValue = this.PasswordForm.getRawValue(); + if (this.PasswordForm.status == "INVALID") { + this.validationService.showValidationsMsg(this.PasswordForm); + return; + } + if (formValue.new_password === formValue.Confirm_password) { + let formData = new changeUserLoginPassword(); + formData.user_id = this.userDetails.user_id; + formData.password = formValue.Confirm_password; + formData.email = this.userDetails.email; + formData.user_type = this.userDetails.user_type; + let obj = { + key: securityFunctions.encryptRSA(securityFunctions.rsa_public_key, JSON.stringify(formData)), + }; + this.ApiServ.AdminGoPost('/ExtranetUserMaster/ChangedPassword', obj).subscribe(data => { + if (data) { + this.commonService.showMessage(data['Resp'], data['Message']); + setTimeout(() => { + data['Resp'] ? this.displayPosition = false : ""; + }, 500); + } + }) + } else { + this.commonService.showMessage(false, 'password does not match'); + } + }; + userDetails = undefined; + FormSetvalue(data) { + this.userDetails = data; + this.formdata.get('first_name').setValue(data.first_name); + this.formdata.get('user_mobile_country_code').setValue(data.user_mobile_country_code); + this.formdata.get('user_mobile').setValue(data.user_mobile); + this.formdata.get('email').setValue(data.email); + this.formdata.get('email').disable(); + this.formdata.get('country').setValue(data.country); + this.UpdateCountry(); + this.formdata.get('timezone').setValue(data.timezone); + this.formdata.get('city').setValue(data.city); + this.formdata.get('role_id').setValue(data.role_id); + if (data.user_type == '210526104324609565') { + this.formdata.get('role_id').disable(); + } + this.formdata.get('extranet_vendor_id').setValue(data.extranet_vendor_id); + data.user_type == '210526104324609565' ? this.UserTypeCheck = true : this.UserTypeCheck = false; + this.GetRoleData(); + let Countries = []; + let Cities = []; + if (data.Cities.length > 0) { + data.Cities.forEach(e => { + Cities.push({ + city_code: e._key, + city_name: e._value + }); + }); + this.commonService.CityList = Cities; + }; + if (data.Countries.length > 0) { + data.Countries.forEach(e => { + Countries.push({ + country_code: e._key, + country_name: e._value + }); + }); + this.commonService.CountryList = Countries; + }; + } + displayPosition!: boolean; + position!: string; + showPositionDialog(position: string) { + this.initPasswordForm(); + this.position = position; + this.displayPosition = true; + }; + + UpdateCountry() { + this.formdata.get('city').setValue(null); + if (this.formdata.get('country').value) { + this.formdata.get('city').enable(); + } else { + this.formdata.get('city').disable(); + } + }; + + backClick() { + this.router.navigateByUrl("/UserConfiguration/UserManagement/Search"); + }; + + GetAllVendorGroup() { + let searchObj = { + vendor_group_name: '', + } + return this.ApiServ.AdminGoPost('/ExtranetVendorGroupMaster/GetAll', searchObj) + }; + GetUserDetailsById(Editid) { + if (Editid) + return this.ApiServ.AdminGOGet('/ExtranetUserMaster/GetById/' + Editid) + else + return of(null) + }; + UserTypeCheck = false; + GetAllRoleByType() { + return this.ApiServ.AdminGet(`/RoleMaster/GetAllRoleByType/Extranet`) + } + + // All API + GetAllCountryNamePhone() { + return this.ApiServ.AdminGet('/CountryNamePhone/GetAllCountryNamePhone') + }; + + getAllTimezoneData() { + return this.ApiServ.AdminGet('/TimezoneCity/GetAllTimezoneCity') + }; + // ddLoader = false + // timer; + // AllVendor + // ExtranetVendorMaster(val) { + // if (val.length >= 2) { + // let searchObj = { + // vendor_name: val, + // }; + // this.ddLoader = true; + // clearTimeout(this.timer); + // this.timer = setTimeout(() => { + // this.ApiServ.AdminGoPost('/ExtranetVendorMaster/GetAll', searchObj).subscribe(res => { + // if (res) { + // this.AllVendor = res.Result; + // this.ddLoader = false; + // } + // }); + // }, 500); + // } + // if (!val) { + // this.AllVendor = []; + // } + // }; + allRoleList = [] + GetRoleData() { + if (this.commonService?.LoginUserData?.extranet_vendor_id) { + this.GetAllRoleByType().subscribe(res => { + if (res) { + this.allRoleList = res; + } + }) + } else { + this.allRoleList = [] + } + }; + +} diff --git a/src/app/modules/user-configuration/user-management/user-management.component.html b/src/app/modules/user-configuration/user-management/user-management.component.html new file mode 100644 index 0000000..1ca51cf --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-management.component.html @@ -0,0 +1 @@ +

    user-management works!

    diff --git a/src/app/modules/user-configuration/user-management/user-management.component.scss b/src/app/modules/user-configuration/user-management/user-management.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/modules/user-configuration/user-management/user-management.component.ts b/src/app/modules/user-configuration/user-management/user-management.component.ts new file mode 100644 index 0000000..4a03c00 --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-management.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-user-management', + templateUrl: './user-management.component.html', +}) +export class UserManagementComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/modules/user-configuration/user-management/user-management.module.ts b/src/app/modules/user-configuration/user-management/user-management.module.ts new file mode 100644 index 0000000..0151c3b --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-management.module.ts @@ -0,0 +1,58 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { UserViewComponent } from './user-view/user-view.component'; +import { UserAddComponent } from './user-add/user-add.component'; +import { MatMenuModule } from '@angular/material/menu'; +import { InputTextModule } from 'primeng/inputtext'; +import { TableModule } from 'primeng/table'; +import { ToolbarModule } from 'primeng/toolbar'; +import { RouterModule, Routes } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import { InterceptLoader } from 'src/app/core/common/intercept-loader.service'; +import { ToastModule } from 'primeng/toast'; +import { MessageService } from 'primeng/api'; +import { MatButtonModule } from '@angular/material/button'; + +const routes: Routes = [ + { + path: 'Search', + component: UserViewComponent, + }, + { + path: 'Add', + component: UserAddComponent, + }, + { + path: 'Edit/:RuleId', + component: UserAddComponent, + }, +] + +@NgModule({ + declarations: [ + UserViewComponent, + UserAddComponent + ], + imports: [ + DialogModule, + ReactiveFormsModule, + FormsModule, + TableModule, + CommonModule, + ButtonModule, + MatMenuModule, + ToastModule, + ToolbarModule, + NgSelectModule, + InputTextModule, + MatButtonModule, + RouterModule.forChild(routes), + ], providers: [MessageService, + { provide: HTTP_INTERCEPTORS, useClass: InterceptLoader, multi: true } + ], +}) +export class UserManagementModule { } diff --git a/src/app/modules/user-configuration/user-management/user-view/user-view.component.html b/src/app/modules/user-configuration/user-management/user-view/user-view.component.html new file mode 100644 index 0000000..b1c4a90 --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-view/user-view.component.html @@ -0,0 +1,140 @@ + +
    +
    +
    +

    User Management

    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    + + + User Id + + Name + + Email Id + + Vendor + + User Role + + User Type + + Updated By + + Updated On + + Status + + Action + + + + + {{data.user_id}} + {{data.first_name}} + {{data.email}} + {{data.vendor_name}} + {{data.role_name}} + {{data.user_role}} + {{data.updated_by}} + {{data.custom_updated_on}} + + + {{data.status}} + + +
    + + + + + +
    + + +
    + + + No data found + + +
    +
    +
    + + \ No newline at end of file diff --git a/src/app/modules/user-configuration/user-management/user-view/user-view.component.ts b/src/app/modules/user-configuration/user-management/user-view/user-view.component.ts new file mode 100644 index 0000000..e84c55d --- /dev/null +++ b/src/app/modules/user-configuration/user-management/user-view/user-view.component.ts @@ -0,0 +1,108 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; +import { CommonFunctionService } from 'src/app/core/common/common-function.service'; +import { securityFunctions } from 'src/app/core/common/security'; +import { API } from 'src/app/core/services/api.service'; + +@Component({ + selector: 'app-user-view', + templateUrl: './user-view.component.html', +}) +export class UserViewComponent implements OnInit { + + cols: any[]; + user_name = ''; + user_email = ''; + vendor_id = null; + AllExtranetUser; + @ViewChild('dt') myTable; + constructor( + private router: Router, + private ApiServ: API, + public commonserv: CommonFunctionService + ) { } + ngOnInit(): void { + this.commonserv.LoginUserData = securityFunctions.getSessionStorage('LoginUserData') ? JSON.parse(securityFunctions.getSessionStorage('LoginUserData')) : null + this.cols = [ + { field: "user_id", header: "User Id" }, + { field: "first_name", header: "Name" }, + { field: "email", header: "Email Id" }, + { field: "vendor_name", header: "Vendor" }, + { field: "role_name", header: "User Role" }, + { field: "user_role", header: "User Type" }, + { field: "updated_by", header: "Updated By" }, + { field: "updated_on", header: "Updated On" }, + { field: "status", header: "Status" }, + ]; + }; + + Search() { + let searchObj = { + first_name: this.user_name ? this.user_name : '', + email: this.user_email ? this.user_email : '', + extranet_vendor_id: this.commonserv.LoginUserData.extranet_vendor_id, + }; + this.ApiServ.AdminGoPost('/ExtranetUserMaster/GetAll', searchObj).subscribe(res => { + if (res) { + this.myTable.first = 0; + this.AllExtranetUser = res.Result; + this.AllExtranetUser.forEach(e => { + e['status'] = e['is_active'] ? 'Active' : 'Deactive' + e['custom_updated_on'] = this.commonserv.UtcToLocaleTime(e.updated_on, "DD MMM YYYY, HH:mm:ss"); + }); + } + }) + }; + + UpdateStatus(id, status) { + let obj = { + Id: id, + Status: status ? false : true, + }; + this.ApiServ.AdminGoPost("/ExtranetUserMaster/UpdateStatus", obj).subscribe( + (data) => { + if (data) { + this.commonserv.showMessage(data['Resp'], data['Message']); + this.Search(); + } + } + ); + }; + + Reset() { + this.user_name = ''; + this.user_email = ''; + this.vendor_id = null; + }; + + edit(user_id) { + this.router.navigate([`/UserConfiguration/UserManagement/Edit/${user_id}`]); + }; + ddLoader = false + timer; + AllVendor + ExtranetVendorMaster(val) { + if (val.length >= 2) { + let searchObj = { + vendor_name: val, + }; + this.ddLoader = true; + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.ApiServ.AdminPost('/ExtranetVendorMaster/GetAll', searchObj).subscribe(res => { + if (res) { + this.AllVendor = res.Result; + this.ddLoader = false; + } + }); + }, 500); + } + if (!val) { + this.AllVendor = []; + } + }; + + btnClick() { + this.router.navigateByUrl("/UserConfiguration/UserManagement/Add"); + } +} diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/files-lazy.json b/src/assets/files-lazy.json new file mode 100644 index 0000000..4deaf89 --- /dev/null +++ b/src/assets/files-lazy.json @@ -0,0 +1,18 @@ +{ + "data": [{ + "label": "Lazy Node 0", + "data": "Node 0", + "leaf": false + }, + { + "label": "Lazy Node 1", + "data": "Node 1", + "leaf": false + }, + { + "label": "Lazy Node 1", + "data": "Node 2", + "leaf": false + } + ] +} \ No newline at end of file diff --git a/src/assets/files.json b/src/assets/files.json new file mode 100644 index 0000000..64af3bd --- /dev/null +++ b/src/assets/files.json @@ -0,0 +1,121 @@ +{ + "data": [ + { + "label": "Dining", + "children": [ + { + "label": "Fruits" + }, + { + "label": "pastries" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + }, + { + "label": "Minibar" + } + ] + }, + { + "label": "Swimming pools", + "children": [ + { + "label": "Indoor Pool" + }, + { + "label": "Outdoor pool" + } + ] + }, + { + "label": "Media and Entertainment", + "children": [ + { + "label": "TV" + }, + { + "label": "Satellite or cable television" + } + ] + }, + { + "label": "Internet", + "children": [ + { + "label": "Locker" + }, + { + "label": "WiFi" + } + ] + }, + { + "label": "Personal Items", + "children": [ + { + "label": "Hair Dryers" + }, + { + "label": "Irons" + } + ] + }, + { + "label": "Television", + "children": [ + { + "label": "Cable TV" + }, + { + "label": "Satelite TV" + } + ] + }, + { + "label": "Facility", + "children": [ + { + "label": "Gym" + } + ] + }, + { + "label": "Bath and Personal Care", + "children": [ + { + "label": "Toiletries" + }, + { + "label": "Bathtub" + } + ] + }, + { + "label": "Refreshments", + "children": [ + { + "label": "Coffee or tea making facility" + }, + { + "label": "Minibar" + } + ] + } + ] +} diff --git a/src/assets/image/Hotel-Image.jpg b/src/assets/image/Hotel-Image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..472691a161485107fd239aa8f22959830f25e6e6 GIT binary patch literal 44079 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 literal 0 HcmV?d00001 diff --git a/src/assets/image/hotel.jpeg b/src/assets/image/hotel.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..07a24c9923326f2857047a20c2dd4369765946c2 GIT binary patch literal 74509 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 z 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 I%71PD**0YK8vpH!et5qfoQeVTLcZ! z1Od5J!k`dp%1k7&wrVIs4O2-7h)qBOVF)sZq#E~;7}6|c5H%-_6QdRnN5+-p3VR~$j3?LUvNKj5`agy^w&Lo6z>|42w7+p z^v=Yb=z0U?5gU!2ioqxRh_Qj9&twu}W+*e=YJ?@n2ZYcw}%m^fOuwiDo2f?KFTO}C4jO15enkx0CO?|I|h zRmRwRql3*=87tJ?pgwV!#CvfIG0|^~Mq>)(C)B{j+`w$DtBXVKxw@vWHT66eb{Ux- z?eA19^E!(W!bW2gf3N9p;N*hIj)I>4P;3aP-qOV-|IItky`VmYXxvIP?sBkjsM`)a zZasSzu2O~%xA|yj63Q7LK?CklTCOCv4?X2k3}ZPv0UfQOLD?JPs(s)Pqr1RWYu8~A zJ;rSH$vuEk&guy>)d4bnZ7i!iP84`wwKhCEG?26SRiIv$gM_1Wmur$6L|IwwSt?@9 ze(T)D&ZE!*$2@Cl*%ZYpXS?e9c5o@w-=8nU*_*e05o0mRb}UDb1qJrR)K{vT#)2s$ z5U(@;>yz;Aa()ooM!{-RUlso)c>80D5Iv_kosd_TE`)Osot;LDdPvfLWtp02#_I(%*97RhnVa=DcgV;=((SUr9%SPg)wKg=@sRxo%?TJFiaO8|Yf1bbb8w{uX$Q>cP~7E8%QZ9Yoc#|7LPW?zpm zE{2jkVUPvrrf!&k)&@+#(-xUGAdmNScN>_TtJBc{$l`O=mnf}M(e_&*Kc=BW2H)&$ z{JnpVc^rkwY6erpfNS~4#l;iF zHb(-aJGHdbXndMruMIhzU$o{`lr;SAaAoCwS#7Nh3CK~Ouddt|=VJxAYJh%P@*zqH zQ{z_i$IFINaK85w$0*$uLTybz*O-5p=hi*!#NOeJ&Sc9{p`FhtS26N#H}cb`vDs?C z<4aW0Ty4i{|H|x3p0qdir8@AqYZ2)-K8|7L0E4PCxpg{w0P=1~x=bFLr2~7Pl+4JO z_hVf;yMEO9vG{|@11$bl0xUja6Ml(%RV_AK6L{S44{0t^?vpSw76PQX zIqto4NQzp|Q2~BEmXBI)WwxO`0UbGG1 ztJBi+Ul+QMCozdXRpLN@XOS&pnw@|7*I!bIfc%EN8YlfNk2cC@><{kE>GOy(3w9%k z@ASB23#N90czr^f?LBcxPAPDu@D)p8?YTNt>5B~_EATeD-Y9*+0N0RXxNICohc8L= zbxBD}tsq?k9A9lyIbM-g`3$ASI1q2OLX!gt9JFnQ4HR**I5qBM^1G9)SR5iWJSlYE8+*~l#3^Pw*jPmvRzfyvU`Fe)r~+v=w;drVCfWStRR4G6CrBp z@q6rZj_DEH<}g0x70`q%ur`Mj?NJyYbI?wT+mPI+DKk*W+x&i7+QQ}bKlHww!;x)< z{gc4@+iT-l)T+$mvLnIwt8p}bcRr*^tc)vAy0DqdJQV+bggbn793+h<169&dMY~UZ@CjOMoA(Om5ndI{j4q{tZ84 z=2^JYdH&8sSw~69!YGc%M$UgPew{+U_dq@b<5SQDc&1eUB53eM6Y}Iaal)kVZu^8>tA6) z(I&vGXtYiiHt>U5ECqKV-aY537CG2smoK&A0QZt|CcEdQ?*5w1O(WjUHH@+Y4u>Eb z)V#CiU~Ch@>&D4vN4JEeAqH3s854ltp8P9JI-N;;Xu`Bt_qOM(#kS)J^&)kE|Mpny zVafY9F~!XnVcvfc6+1{&hDkJq)Sr=|T>cYu2;P2zs}jUN#(j6tHY3%hQ8j4JfmLE1 zqweSdI--yHv~MxP>G9@h*_4-T!aac9B#VcUc?nZNtP7_QV_l(+3B8-S-*>qw0kRtk zk4b@*{MFr$A<#QHNq#nu9oGUDZ@9;$tO&-w&)hPP!M{taSm&W1k=X8w4OULq>Vx^; z^74Bh3$?cc`r*h2EoB@lFN%)XG|{@lY!P za%7lv>WifC^GOkQVF?kC0VpI2Wr{?ZqEMe7J!*$S+F4ndAdz-Rq$ZEu_dgS23E@!} Xul)ZBDb!8T>s!T~@;b>pfxq@&8#d&) literal 0 HcmV?d00001 diff --git a/src/assets/products.json b/src/assets/products.json new file mode 100644 index 0000000..742215d --- /dev/null +++ b/src/assets/products.json @@ -0,0 +1,363 @@ +{ + "data": [{ + "id": "1000", + "code": "f230fh0g3", + "name": "Bamboo Watch", + "description": "Product Description", + "image": "bamboo-watch.jpg", + "price": 65, + "category": "Accessories", + "quantity": 24, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1001", + "code": "nvklal433", + "name": "Black Watch", + "description": "Product Description", + "image": "black-watch.jpg", + "price": 72, + "category": "Accessories", + "quantity": 61, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1002", + "code": "zz21cz3c1", + "name": "Blue Band", + "description": "Product Description", + "image": "blue-band.jpg", + "price": 79, + "category": "Fitness", + "quantity": 2, + "inventoryStatus": "InActive", + "rating": 3 + }, + { + "id": "1003", + "code": "244wgerg2", + "name": "Blue T-Shirt", + "description": "Product Description", + "image": "blue-t-shirt.jpg", + "price": 29, + "category": "Clothing", + "quantity": 25, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1004", + "code": "h456wer53", + "name": "Bracelet", + "description": "Product Description", + "image": "bracelet.jpg", + "price": 15, + "category": "Accessories", + "quantity": 73, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1005", + "code": "av2231fwg", + "name": "Brown Purse", + "description": "Product Description", + "image": "brown-purse.jpg", + "price": 120, + "category": "Accessories", + "quantity": 0, + "inventoryStatus": "InActive", + "rating": 4 + }, + { + "id": "1006", + "code": "bib36pfvm", + "name": "Chakra Bracelet", + "description": "Product Description", + "image": "chakra-bracelet.jpg", + "price": 32, + "category": "Accessories", + "quantity": 5, + "inventoryStatus": "InActive", + "rating": 3 + }, + { + "id": "1007", + "code": "mbvjkgip5", + "name": "Galaxy Earrings", + "description": "Product Description", + "image": "galaxy-earrings.jpg", + "price": 34, + "category": "Accessories", + "quantity": 23, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1008", + "code": "vbb124btr", + "name": "Game Controller", + "description": "Product Description", + "image": "game-controller.jpg", + "price": 99, + "category": "Electronics", + "quantity": 2, + "inventoryStatus": "InActive", + "rating": 4 + }, + { + "id": "1009", + "code": "cm230f032", + "name": "Gaming Set", + "description": "Product Description", + "image": "gaming-set.jpg", + "price": 299, + "category": "Electronics", + "quantity": 63, + "inventoryStatus": "Active", + "rating": 3 + }, + { + "id": "1010", + "code": "plb34234v", + "name": "Gold Phone Case", + "description": "Product Description", + "image": "gold-phone-case.jpg", + "price": 24, + "category": "Accessories", + "quantity": 0, + "inventoryStatus": "InActive", + "rating": 4 + }, + { + "id": "1011", + "code": "4920nnc2d", + "name": "Green Earbuds", + "description": "Product Description", + "image": "green-earbuds.jpg", + "price": 89, + "category": "Electronics", + "quantity": 23, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1012", + "code": "250vm23cc", + "name": "Green T-Shirt", + "description": "Product Description", + "image": "green-t-shirt.jpg", + "price": 49, + "category": "Clothing", + "quantity": 74, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1013", + "code": "fldsmn31b", + "name": "Grey T-Shirt", + "description": "Product Description", + "image": "grey-t-shirt.jpg", + "price": 48, + "category": "Clothing", + "quantity": 0, + "inventoryStatus": "InActive", + "rating": 3 + }, + { + "id": "1014", + "code": "waas1x2as", + "name": "Headphones", + "description": "Product Description", + "image": "headphones.jpg", + "price": 175, + "category": "Electronics", + "quantity": 8, + "inventoryStatus": "InActive", + "rating": 5 + }, + { + "id": "1015", + "code": "vb34btbg5", + "name": "Light Green T-Shirt", + "description": "Product Description", + "image": "light-green-t-shirt.jpg", + "price": 49, + "category": "Clothing", + "quantity": 34, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1016", + "code": "k8l6j58jl", + "name": "Lime Band", + "description": "Product Description", + "image": "lime-band.jpg", + "price": 79, + "category": "Fitness", + "quantity": 12, + "inventoryStatus": "Active", + "rating": 3 + }, + { + "id": "1017", + "code": "v435nn85n", + "name": "Mini Speakers", + "description": "Product Description", + "image": "mini-speakers.jpg", + "price": 85, + "category": "Clothing", + "quantity": 42, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1018", + "code": "09zx9c0zc", + "name": "Painted Phone Case", + "description": "Product Description", + "image": "painted-phone-case.jpg", + "price": 56, + "category": "Accessories", + "quantity": 41, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1019", + "code": "mnb5mb2m5", + "name": "Pink Band", + "description": "Product Description", + "image": "pink-band.jpg", + "price": 79, + "category": "Fitness", + "quantity": 63, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1020", + "code": "r23fwf2w3", + "name": "Pink Purse", + "description": "Product Description", + "image": "pink-purse.jpg", + "price": 110, + "category": "Accessories", + "quantity": 0, + "inventoryStatus": "InActive", + "rating": 4 + }, + { + "id": "1021", + "code": "pxpzczo23", + "name": "Purple Band", + "description": "Product Description", + "image": "purple-band.jpg", + "price": 79, + "category": "Fitness", + "quantity": 6, + "inventoryStatus": "InActive", + "rating": 3 + }, + { + "id": "1022", + "code": "2c42cb5cb", + "name": "Purple Gemstone Necklace", + "description": "Product Description", + "image": "purple-gemstone-necklace.jpg", + "price": 45, + "category": "Accessories", + "quantity": 62, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1023", + "code": "5k43kkk23", + "name": "Purple T-Shirt", + "description": "Product Description", + "image": "purple-t-shirt.jpg", + "price": 49, + "category": "Clothing", + "quantity": 2, + "inventoryStatus": "InActive", + "rating": 5 + }, + { + "id": "1024", + "code": "lm2tny2k4", + "name": "Shoes", + "description": "Product Description", + "image": "shoes.jpg", + "price": 64, + "category": "Clothing", + "quantity": 0, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1025", + "code": "nbm5mv45n", + "name": "Sneakers", + "description": "Product Description", + "image": "sneakers.jpg", + "price": 78, + "category": "Clothing", + "quantity": 52, + "inventoryStatus": "Active", + "rating": 4 + }, + { + "id": "1026", + "code": "zx23zc42c", + "name": "Teal T-Shirt", + "description": "Product Description", + "image": "teal-t-shirt.jpg", + "price": 49, + "category": "Clothing", + "quantity": 3, + "inventoryStatus": "InActive", + "rating": 3 + }, + { + "id": "1027", + "code": "acvx872gc", + "name": "Yellow Earbuds", + "description": "Product Description", + "image": "yellow-earbuds.jpg", + "price": 89, + "category": "Electronics", + "quantity": 35, + "inventoryStatus": "Active", + "rating": 3 + }, + { + "id": "1028", + "code": "tx125ck42", + "name": "Yoga Mat", + "description": "Product Description", + "image": "yoga-mat.jpg", + "price": 20, + "category": "Fitness", + "quantity": 15, + "inventoryStatus": "Active", + "rating": 5 + }, + { + "id": "1029", + "code": "gwuby345v", + "name": "Yoga Set", + "description": "Product Description", + "image": "yoga-set.jpg", + "price": 20, + "category": "Fitness", + "quantity": 25, + "inventoryStatus": "Active", + "rating": 8 + } + ] +} \ No newline at end of file diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts new file mode 100644 index 0000000..794c4b9 --- /dev/null +++ b/src/environments/environment.dev.ts @@ -0,0 +1,12 @@ +export const environment = { + production: false, + cdnBaseUrl: 'https://edgeftp.b-cdn.net/', + cdnFileUrl: 'https://edgeftp.b-cdn.net/dev/', + client_id: "2109111018200000022", + ExtranetAPIBaseUrl: "https://extranetapi.dev.futuretravelplatform.com/api/v1", + AdminAPIGOBaseUrl: "https://adminapi-go.dev.futuretravelplatform.com/api", + APIBaseUrl: "https://adminapi.dev.futuretravelplatform.com/api", + hotelApiBaseUrl: "https://hotelapi.dev.futuretravelplatform.com/api", + APIBaseGoUrl: "https://adminapi-go.dev.futuretravelplatform.com/api", + +}; diff --git a/src/environments/environment.preprod.ts b/src/environments/environment.preprod.ts new file mode 100644 index 0000000..821b473 --- /dev/null +++ b/src/environments/environment.preprod.ts @@ -0,0 +1,10 @@ +export const environment = { + production: true, + client_id: "2109111018200000021", + ExtranetAPIBaseUrl: "https://extranetapi.preprod.amadeusonlinesuite.com/api/v1", + AdminAPIGOBaseUrl: "https://adminapi-go.preprod.amadeusonlinesuite.com/api", + APIBaseUrl: "https://adminapi.preprod.amadeusonlinesuite.com/api", + fileUploadBaseUrl:'https://edge.amadeusonlinesuite.com/preprod', + hotelApiBaseUrl: "https://hotelapi.preprod.amadeusonlinesuite.com/api", + APIBaseGoUrl: "https://adminapi-go.preprod.amadeusonlinesuite.com/api", + }; \ No newline at end of file diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 0000000..4264e34 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,12 @@ +export const environment = { + production: false, + cdnBaseUrl: 'https://edgeftp.b-cdn.net/', + cdnFileUrl: 'https://edgeftp.b-cdn.net/prod/', + client_id: "2109111018200000022", + ExtranetAPIBaseUrl: "https://extranetapi.futuretravelplatform.com/api/v1", + AdminAPIGOBaseUrl: "https://adminapi-go.futuretravelplatform.com/api", + APIBaseUrl: "https://adminapi.futuretravelplatform.com/api", + hotelApiBaseUrl: "https://hotelapi.futuretravelplatform.com/api", + APIBaseGoUrl: "https://adminapi-go.futuretravelplatform.com/api", + +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..96f80a4 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,25 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, + cdnBaseUrl: 'https://edgeftp.b-cdn.net/', + cdnFileUrl: 'https://edgeftp.b-cdn.net/dev/', + client_id: "2109111018200000022", + ExtranetAPIBaseUrl: "https://extranetapi.dev.futuretravelplatform.com/api/v1", + AdminAPIGOBaseUrl: "https://adminapi-go.dev.futuretravelplatform.com/api", + APIBaseUrl: "https://adminapi.dev.futuretravelplatform.com/api", + hotelApiBaseUrl: "https://hotelapi.dev.futuretravelplatform.com/api", + APIBaseGoUrl: "https://adminapi-go.dev.futuretravelplatform.com/api", + +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. diff --git a/src/environments/environment.uat.ts b/src/environments/environment.uat.ts new file mode 100644 index 0000000..1f77e99 --- /dev/null +++ b/src/environments/environment.uat.ts @@ -0,0 +1,10 @@ +export const environment = { + production: true, + client_id: "2109111018200000021", + ExtranetAPIBaseUrl: "https://extranetapi.aosuat.com/api/v1", + AdminAPIGOBaseUrl: "https://adminapi-go.aosuat.com/api", + APIBaseUrl: "https://adminapi.aosuat.com/api", + fileUploadBaseUrl: "https://edge.aosuat.com/uat", + hotelApiBaseUrl: "https://hotelapi.aosuat.com/api", + APIBaseGoUrl: "https://adminapi-go.aosuat.com/api", +}; \ No newline at end of file diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..997406ad22c29aae95893fb3d666c30258a09537 GIT binary patch literal 948 zcmV;l155mgP)CBYU7IjCFmI-B}4sMJt3^s9NVg!P0 z6hDQy(L`XWMkB@zOLgN$4KYz;j0zZxq9KKdpZE#5@k0crP^5f9KO};h)ZDQ%ybhht z%t9#h|nu0K(bJ ztIkhEr!*UyrZWQ1k2+YkGqDi8Z<|mIN&$kzpKl{cNP=OQzXHz>vn+c)F)zO|Bou>E z2|-d_=qY#Y+yOu1a}XI?cU}%04)zz%anD(XZC{#~WreV!a$7k2Ug`?&CUEc0EtrkZ zL49MB)h!_K{H(*l_93D5tO0;BUnvYlo+;yss%n^&qjt6fZOa+}+FDO(~2>G z2dx@=JZ?DHP^;b7*Y1as5^uphBsh*s*z&MBd?e@I>-9kU>63PjP&^#5YTOb&x^6Cf z?674rmSHB5Fk!{Gv7rv!?qX#ei_L(XtwVqLX3L}$MI|kJ*w(rhx~tc&L&xP#?cQow zX_|gx$wMr3pRZIIr_;;O|8fAjd;1`nOeu5K(pCu7>^3E&D2OBBq?sYa(%S?GwG&_0-s%_v$L@R!5H_fc)lOb9ZoOO#p`Nn`KU z3LTTBtjwo`7(HA6 z7gmO$yTR!5L>Bsg!X8616{JUngg_@&85%>W=mChTR;x4`P=?PJ~oPuy5 zU-L`C@_!34D21{fD~Y8NVnR3t;aqZI3fIhmgmx}$oc-dKDC6Ap$Gy>a!`A*x2L1v0 WcZ@i?LyX}70000 + + + + ExtraNet + + + + + + + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..400f4c5 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,14 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +document.getElementById('bootstrapCssUrl').setAttribute('href', `${environment.cdnBaseUrl}Bootstrap/bootstrap.css`); + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 0000000..429bb9e --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,53 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/src/scss/_badge.scss b/src/scss/_badge.scss new file mode 100644 index 0000000..d568b96 --- /dev/null +++ b/src/scss/_badge.scss @@ -0,0 +1,63 @@ +.listBox{ + overflow: auto !important; +} + .p-listbox { + border: 0 !important; + margin-bottom: 20px; +} + + .p-listbox-list { + display: flex !important; + padding: 0 !important; +} + .p-listbox .p-listbox-list .p-listbox-item.p-highlight { + color: var(--primary-theme) !important; + background: rgb(255, 206, 54) !important; +} + + + .p-listbox:not(.p-disabled) + .p-listbox-item:not(.p-highlight):not(.p-disabled):hover { + color: var(--secondary-theme) !important; + background: var(--primary-theme) !important; + // border: 2px solid var(--secondary-theme) !important; +} + + .p-listbox .p-listbox-list .p-listbox-item:focus { + box-shadow: none !important; +} + + .p-listbox-item { + border: 1px solid var(--primary-theme) !important; + border-radius: 5px !important; + padding: 5px 15px !important; + margin-right: 10px !important; +} + +@media screen and (max-width: 960px) { + .p-listbox-list { + flex-wrap: wrap; + } + .ListBox { + .p-listbox .p-listbox-list .p-listbox-item { + width: 100% !important; + padding: 1px 27px !important; + justify-content: center; + } + .p-listbox-list-wrapper { + padding-bottom: 20px; + } + + } + .p-listbox .p-listbox-list .p-listbox-item { + width: 100px !important; + height: 30px !important; + justify-content: center !important; + } + .p-listbox-list li { + margin-bottom: 10px !important; + } + .p-listbox .p-listbox-list .p-listbox-item { + padding: 5px 12px !important; + } +} diff --git a/src/scss/_buttons.scss b/src/scss/_buttons.scss new file mode 100644 index 0000000..2595e76 --- /dev/null +++ b/src/scss/_buttons.scss @@ -0,0 +1,125 @@ +.p-button:focus { + box-shadow: none !important; +} + +.btn-primary { + color: #ffffff !important; + background: var(--primary-theme) !important; + border: 1px solid var(--primary-theme) !important; +} + +.btn-secondary { + color: var(--primary-theme) !important; + background-color: #ffffff !important; + border: 1px solid var(--primary-theme) !important; +} + +.btn-secondary:hover { + background: #eceefa !important; +} + +.btn-back { + cursor: pointer; + display: inline-flex; + align-items: center; + margin: 0 0 8px; + + svg { + height: 17px; + } + + span { + font-size: 18px; + font-weight: 600; + } +} + +.btn-copy { + display: block; + background-color: var(--secondary-light); + color: var(--primary-theme); + width: 24px; + padding: 5px; + border-radius: 5px; + margin: 0 auto; + margin-top: 10px; +} + +.btn-arrowForward { + background-color: #e6e6e6; + padding: 6px 10px; + align-self: self-end; +} + +.btn-icon { + cursor: pointer; + color: var(--primary-theme); + border: 0 !important; + + .p-button { + background-color: #f2f3f8 !important; + color: var(--primary-theme); + border: 0 !important; + } + + .p-button:enabled:hover { + background-color: #f2f3f8 !important; + color: var(--primary-theme) !important; + border: 0 !important; + } +} + +.btn-icon:hover { + background-color: #f2f3f8 !important; + color: var(--primary-theme) !important; + border: 0 !important; +} + +.p-checkbox-focused { + box-shadow: none !important; +} + + +.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle { + border-color: var(--primary-theme) !important; + border-width: 5px !important; +} + +.mat-radio-button.mat-primary .mat-radio-inner-circle { + background-color: #ffffff !important; +} + +.mat-radio-button.mat-primary .mat-radio-inner-circle, + +.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple), + +.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple, +.mat-radio-button.mat-primary:active .mat-radio-persistent-ripple { + background-color: #ffffff; +} + +.ng-btnDanger { + background-color: #f32121; + color: #fff; + padding: 2px 10px; + height: 30px; + font-size: 12px; + border: 1px solid #f32121; + border-radius: 4px; +} + +.btn-duplicate { + height: 30px; + font-size: 12px; + padding: 2px 10px; + border-radius: 4px; +} + +.overflow-auto { + overflow: auto; +} + +.app-AddMore { + padding-top: 20px; + text-align: center; +} \ No newline at end of file diff --git a/src/scss/_calendar.scss b/src/scss/_calendar.scss new file mode 100644 index 0000000..d5aaa14 --- /dev/null +++ b/src/scss/_calendar.scss @@ -0,0 +1,238 @@ +// grid calendar +.calGrid { + display: grid; + grid-template-columns: 86% auto; + gap: 10px; + } + + .p-datepicker-other-month { + opacity: 0; +} + + .p-calendar .p-datepicker { + padding: 0px; +} + + .p-calendar { + width: 100% !important; +} + + .p-calendar .p-inputtext{ + padding: 8px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 14px; + outline: none; + width: 100% !important; + height: 40px; + color: var(--text-color); +} + .p-calendar .p-datepicker { + left: 0px !important; +} + .p-button.p-button-icon-only { + width: 40px; + height: 40px; + padding: 0.35rem 0; +} + .p-calendar-w-btn .p-datepicker-trigger { + border-left: 0 !important; + border-top-right-radius: 4px !important; + border-bottom-right-radius: 4px !important; +} +.dateForHighlight .p-datepicker table td span { + border-radius: 75%; + background-color: rgba(28, 143, 181, 0.45); +} +.dateForHighlight .p-datepicker table td span.p-disabled { + background-color: transparent; +} +.dateForHighlight .p-datepicker table td.p-datepicker-today > span { + background-color: #ced4da; +} + .p-calendar-w-btn .p-inputtext { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + .p-icon-wrapper { + content: "\ebcc"; + color: #7b7272; + font-size: 1.25rem !important; + font-family: 'Material Icons'; +} + .p-button { + background-color: #f2f3f8; + border: 1px solid #ccc; +} + .p-button:enabled:hover { + background: #f2f3f8; + color: unset; + border-color: #ccc; +} + .p-button.p-button-text:enabled:hover { + color: #fff; + background: var(--primary-theme); +} + .p-datepicker-buttonbar .p-button:first-child { + display: none; +} + .p-datepicker .p-datepicker-buttonbar { + margin-top: 10px; + justify-content: end !important; + border-top: 1px solid #ccc; + padding: 10px; +} + .p-datepicker .p-datepicker-buttonbar .p-button { + padding: 8px 19px; + border: 0; + border-radius: 4px; + background: var(--primary-theme); + color: #fff; +} + .p-datepicker-buttonbar .p-button-label { + font-size: 12px; +} + .p-datepicker-header .p-datepicker-prev-icon, + .p-datepicker-header .p-datepicker-next-icon { + color: #000; + font-size: 14px; +} + .p-datepicker { + font-size: 15px !important; + border-radius: 4px; + background-color: #fff; +} + + .p-datepicker table th { + padding: 10px 0px; +} + + .p-datepicker table td { + padding: 0; +} + +.p-datepicker-year { + padding: 0px 6px; +} + + .p-datepicker .p-datepicker-header { + padding: 5px; + padding-bottom: 0; +} + + .p-datepicker-year { + padding: 0px 5px; +} + + .p-datepicker-header .p-datepicker-title { + font-weight: bolder; +} + + .p-datepicker .p-datepicker-header .p-datepicker-prev:focus, + .p-datepicker .p-datepicker-header .p-datepicker-next:focus { + box-shadow: unset !important; +} + + .p-datepicker-calendar thead { + border-bottom: 1px solid rgb(238, 238, 238); +} + + .p-datepicker-calendar thead tr th span { + font-size: 13px; + font-weight: 400; +} + + .p-datepicker table td span { + display: block; + cursor: pointer; + text-align: center; + width: 35px !important; + height: 35px !important; + line-height: 35px !important; + font-size: 12px; +} + + .p-datepicker table td > span.p-highlight { + color: #fff !important; + background-color: var(--primary-theme) !important; +} + + .p-disabled, + .p-component:disabled { + opacity: 0.3 !important; +} + +// full calender + .fc-header-toolbar { + .fc-toolbar-chunk:last-of-type { + display: none !important; + } +} + .fc .fc-button-group { + position: inherit !important; +} + .fc .fc-toolbar { + justify-content: center !important; +} + .fc .fc-toolbar.fc-header-toolbar { + background: var(--primary-theme); + color: #fff; + padding: 10px; + position: relative !important; + margin: 0 !important; +} + .fc-today-button { + display: none !important; +} + .fc-prev-button { + position: absolute !important; + left: 15px !important; + color: #f7f8fa !important; + border: 0 !important; + bottom: 11px !important; + background: var(--primary-theme) !important; +} + .fc-next-button { + position: absolute !important; + right: 15px !important; + background: var(--primary-theme) !important; + border: 0 !important; + color: #ffffff !important; + bottom: 11px !important; +} + .fc.fc-theme-standard .fc-toolbar .fc-button:focus { + box-shadow: none !important; + outline: none !important; +} + .fc-scrollgrid-sync-inner { + padding: 10px !important; +} +// full calender +@media screen and (max-width: 960px) { + .p-datepicker table td span { + border-radius: 0px !important; + } + .p-datepicker table td { + width: 14.28%; + } + .p-datepicker table td span { + width: 100% !important; + } + .p-datepicker-group-container .p-datepicker-group:first-child .p-datepicker-calendar tbody { + border-right: 0; + } + .p-datepicker-multiple-month .p-datepicker-group-container { + display: block !important; + } + .p-datepicker { + position: fixed !important; + top: 0px !important; + display: block !important; + height: 100%; + overflow: auto; + padding: 0; + padding: 56px 0px !important; + padding-top: 0 !important; + border-radius: 0; + } +} diff --git a/src/scss/_checkBox.scss b/src/scss/_checkBox.scss new file mode 100644 index 0000000..2727603 --- /dev/null +++ b/src/scss/_checkBox.scss @@ -0,0 +1,47 @@ +.mdc-checkbox { + padding: 0 !important; +} +.mdc-checkbox__background { + color: #495057; + top: 0 !important; + left: 0 !important; + width: 20px !important; + height: 20px !important; + background: #ffffff; + border: 1px solid #ced4da !important; + transition: background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s; + border-radius: var(--border-radius) !important; +} +.mdc-checkbox:hover .mdc-checkbox__ripple, +.mdc-checkbox:active .mdc-checkbox__native-control~.mdc-checkbox__ripple { + background-color: transparent !important; +} +.mat-mdc-checkbox-ripple { + display: none; +} +.mat-mdc-checkbox .mat-internal-form-field { + gap: 5px; + color: unset !important; + letter-spacing: unset !important; + font-family: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important; +} +.mat-mdc-checkbox .mdc-form-field .mdc-label { + font-size: 14px; + margin-top: 2px; +} +.mdc-checkbox__native-control:enabled:checked~.mdc-checkbox__background, +.p-checkbox .p-checkbox-box.p-highlight { + background: var(--primary-theme) !important; + border-radius: var(--border-radius); +} +.mat-mdc-checkbox .mdc-checkbox__background svg { + height: 14px; + align-self: center; +} +.mat-mdc-checkbox .mdc-form-field label { + margin-bottom: 0 !important; +} +.mdc-checkbox .mdc-checkbox__native-control:focus~.mdc-checkbox__ripple { + opacity: unset !important; + background-color: unset !important; +} \ No newline at end of file diff --git a/src/scss/_comCalender.scss b/src/scss/_comCalender.scss new file mode 100644 index 0000000..3c6d589 --- /dev/null +++ b/src/scss/_comCalender.scss @@ -0,0 +1,92 @@ +.common_calendar { + .p-calendar { + display: initial !important; + width: 100%; + } + .p-datepicker-title{ + background: var(--primary-theme); + color: #fff !important; + padding: 6px 12px; + border-radius: 5px; + } + .p-datepicker-month{ + padding-right: 20px !important; + border-right: 2px solid var(--secondary-theme); + border-radius: 0; + color: #ffffff !important; + } + .p-datepicker-year { + padding-left: 12px !important; + color: #ffffff !important; + } + .p-datepicker table td > span { + width: 100% !important; + height: 100% !important; + border-radius: 0 !important; + display: block !important; + text-align: end; + padding: 11px !important; + } + .p-ink { + display: none; + } + .p-calendar .p-datepicker{ + width: 100% !important; + } + .p-datepicker table { + border: 1px solid #d3d3d3 !important; + } + .p-datepicker table td > span.p-highlight { + background-color: transparent !important; + } + .p-datepicker:not(.p-disabled) table td span:not(.p-highlight):not(.p-disabled):hover { + background-color: transparent !important; + } + .p-datepicker table td { + padding: 0 !important; + border: 1px solid #d6d6d6 !important; + } + .p-datepicker table th { + padding: 0.5rem; + border: 1px solid #d6d6d6; + padding-top: 20px; + padding-bottom: 20px; + } + .fs-30 { + font-size: 30px; + } + .w-59 { + width: 59%; + } + + .justify-center { + justify-content: center; + } + .calenderAdd .material-icons{ + font-size: 18px; + } + .calenderAdd .formLabel{ + font-size: 12px !important; + } + .spanLabel{ + width: 42%; + } + .w-77{ + width: 77%; + } +} +@media screen and (max-width:960px) { + .common_calendar .p-datepicker-inline{ + overflow-x: hidden !important; + } + .common_calendar .p-datepicker-calendar-container{ + overflow: auto; + } + .common_calendar .p-datepicker-header{ + border: 1px solid #e6e6e6 !important; + } + .common_calendar .p-calendar .p-datepicker{ + padding: 0 !important; + border: none !important; + } +} \ No newline at end of file diff --git a/src/scss/_common.scss b/src/scss/_common.scss new file mode 100644 index 0000000..24b8e14 --- /dev/null +++ b/src/scss/_common.scss @@ -0,0 +1,1744 @@ +// For Spacing +$spaceamounts: ( + 0, + 5, + 10, + 15, + 20, + 21, + 25, + 30, + 35, + 40, + 45, + 50, + 60, + 75, + 100 +); +$sides: ( + top, + bottom, + left, + right +); + +@each $space in $spaceamounts { + @each $side in $sides { + .m#{str-slice($side, 0, 1)}-#{$space} { + margin-#{$side}: #{$space}px !important; + } + + .p#{str-slice($side, 0, 1)}-#{$space} { + padding-#{$side}: #{$space}px !important; + } + } +} + +.ErrorWrapper .ng-select-container, +.ErrorWrapper .p-calendar .p-inputtext, +.ErrorWrapper .p-datepicker-trigger { + border: 1px solid red !important; +} + +.ErrorWrapper .p-datepicker-trigger { + border-left: none !important; +} + +.p-10 { + padding: 10px; +} + +.p-20 { + padding: 20px; +} + +.pb-10 { + padding-bottom: 10px; +} + +.m-10 { + margin: 10px; +} + +.m-15 { + margin: 0 15px !important; +} + +.mr-10 { + margin-right: 10px !important; +} + +.mt-10 { + margin-top: 10px !important; +} + +.mt-20 { + margin-top: 20px !important; +} + +.mt-2 { + margin-top: 2px !important; +} + +// For Flex +@mixin flex-aj($align: unset, $justify: unset) { + display: flex; + align-items: $align; + justify-content: $justify; +} + +.d-flex { + display: flex; +} + +.align-end { + align-items: end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between !important; +} + +.flex-between { + display: flex; + justify-content: space-between; +} + +.justify-flex { + display: flex; + justify-content: end !important; +} + +.flex-center { + display: flex; + align-items: center; +} + +.gap-10 { + gap: 10px; +} + +.align-center { + display: flex; + align-items: center !important; +} + +.flex-end { + display: flex; + align-items: end; +} + +.self-end { + align-self: flex-end; +} + +.self-center { + align-self: center; +} + +.ng-dropdown-header { + display: none !important; +} + +.AddChildOption { + border: 1px solid #dee2e6; + padding: 20px 20px 0; + margin-bottom: 20px; +} + +.btn-remove { + color: #fff !important; + background: red !important; + border: 1px red !important; + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + height: 30px; + font-size: 12px; + padding: 2px 10px; + border-radius: 4px; +} + +@mixin grid-gap($x: 0, $y: unset) { + display: grid; + + @if $y !=unset { + grid-gap: $x $y; + } + + @else { + grid-gap: $x; + } +} + +.app-subGrid2 { + grid-template-columns: repeat(2, 1fr); + @include grid-gap(10px); +} + +.d-block { + display: block; +} + +.align-start { + align-items: flex-start !important; +} + +.text-center { + text-align: center; +} + +.text-end { + text-align: end; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right; +} + +// table status +.status-red { + background: #ffcdd2 !important; + color: #c63737 !important; + font-size: 12px; + padding: 2px 8px; + border-radius: 5px; +} + +.status-green { + background: #c8e6c9 !important; + color: #256029 !important; + font-size: 12px; + padding: 2px 8px; + border-radius: 5px; +} + +// For Width +.w-5 { + width: 5%; +} + +.w-10 { + width: 10% !important; +} + +.w-15 { + width: 15% !important; +} + +.w-20 { + width: 20% !important; +} + +.w-25 { + width: 25% !important; +} + +.w-30 { + width: 30% !important; +} + +.w-40 { + width: 40% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-60 { + width: 60% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-85 { + width: 85% !important; +} + +.w-100 { + width: 100% !important; +} + +.min-width100 { + width: 70px !important; +} + +.min-width200 { + width: 200px !important; +} + +.wPx-150 { + width: 150px; +} + +.h-100 { + height: 100% !important; +} + +.f-20 { + font-size: 20px; +} + +.fw-600 { + font-weight: 600; +} + +.fw-400 { + font-weight: 400; +} + +.mat-mdc-menu-panel .p-fileupload .p-fileupload-buttonbar .p-button { + margin-right: 0; + background-color: transparent; + border: 0; + padding: 0; + width: 100%; + text-align: left; +} + +.mat-mdc-menu-panel .p-fileupload .p-fileupload-content { + padding-top: 0 !important; +} + +.mat-mdc-menu-panel .p-button-icon { + display: none; +} + +.mat-mdc-menu-panel .p-button-label { + color: #212121; + font-size: 14px; +} + +.bulkUpload .p-button-label { + font-family: sans-serif; +} + +.mat-mdc-menu-panel .mat-mdc-menu-item-text a { + color: #212121; +} + +// checkbox +@media screen and (max-width: 768px) { + .p-20 { + padding: 15px; + } + + .ng-dropdown-header { + display: block !important; + } + + .p-dialog { + width: 100% !important; + } + + .temp_mobileBack { + display: block !important; + background: var(--primary-theme) !important; + color: #fff; + box-shadow: 0 2px 5px #0000001a; + width: 100%; + } + + .mobileFixedHeader-P, + .temp_mobileHead { + display: flex !important; + align-items: center; + justify-content: space-between !important; + height: 56px; + padding: 0 15px; + } + + .temp_mobileBackButton { + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + background: #fff !important; + color: #fff; + border: 0; + border-radius: 50%; + margin: 0 !important; + } + + .temp_mobileBackButton .material-icons { + color: #000 !important; + font-size: 21px; + margin: 0 !important; + } + + .p-toast-top-right { + width: 94% !important; + } + + .temp_mobileTitle h4 { + margin: 0; + font-size: 18px; + font-weight: 400; + } + + .app-BkGrid2 { + display: flex; + flex-direction: column; + gap: 10px; + } + + .bookingMngmnt_gridWrap { + display: block; + } +} + +.astrick { + color: red; + position: absolute; + font-size: 14px; + margin-left: 3px; +} + +.commonSection { + overflow: auto; + border: 1px solid #dee2e6 !important; +} + +.commonSubSection { + padding: 20px; +} + +// .p-dialog Css // +.p-dialog { + max-height: unset !important; + margin-bottom: 20px !important; +} + +.p-dialog-content { + overflow-y: unset !important; +} + +.p-dialog-mask.p-component-overlay { + overflow-x: hidden !important; + overflow-y: auto !important; +} + +.p-dialog .p-dialog-header { + color: #fff; + background: var(--primary-theme); +} + +.p-dialog .p-dialog-header, +.p-dialog .p-dialog-footer { + padding: 1.2rem; +} + +.p-dialog .p-dialog-content { + padding: 1.5rem 1.2rem; +} + +.p-dialog .p-dialog-footer { + border-top: 1px solid #e6e6e6; +} + +.p-dialog .p-dialog-header .p-dialog-title { + font-weight: 400; + font-size: 18px; +} + +.p-dialog .p-dialog-header .p-icon-wrapper { + color: #fff; + justify-content: end; +} + +.p-dialog .p-dialog-header .p-dialog-header-close { + border: 0; + color: #fff; + background: transparent; + justify-content: flex-end; +} + +.p-dialog .p-dialog-header .p-dialog-header-icon:enabled:hover { + background: transparent; +} + +.p-dialog .p-dialog-header .p-dialog-header-icon:focus { + box-shadow: none; +} + +.p-dialog .p-dialog-header .p-dialog-header-close-icon { + font-size: 1.2rem; +} + +.SSExpireWarning .p-dialog .p-dialog-content { + padding: 40px; + border-radius: 8px; +} + +.SSExpire-Modal { + text-align: center; +} + +.ExpireHeader { + font-size: 20px; + font-weight: 500; + text-align: center; + margin: 15px 0; +} + +.btnExtend { + display: flex; + justify-content: center; + margin-top: 20px; +} + +.btnExtend .btn { + min-width: 170px; +} + +.passSuggest .PswdSuccess:before { + background-color: #3ed23e !important; +} + +.PswdSuccess::before { + background-color: #3ed23e !important; +} + +.PswdFail::before { + background: #ccc !important; +} + +.PswdSuccess::marker { + color: #3ed23e !important; +} + +// New Css // +.ng-card { + display: flex; + -webkit-box-flex: 1; + flex-grow: 1; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + box-shadow: 0px 0px 13px 0px rgb(82 63 105 / 5%); + background-color: #ffffff; + margin-bottom: 20px; + border-radius: 4px; +} + +.ng-cardHead { + display: flex; + align-items: center; + justify-content: space-between; + position: relative; + padding: 12px 20px; + border-bottom: 1px solid #ebedf2; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +.ng-cardLabel { + display: flex; + align-items: center; +} + +.ng-cardTitle { + margin: 0; + padding: 0; + color: var(--color-body-text); + font-size: 18px; + font-weight: 500 !important; + line-height: 36px; +} + +.ng-searchBody { + padding: 20px 20px; + border-radius: 4px; +} + +.ng-searchFooter { + padding: 0 20px 20px; + align-items: center; +} + +.ng-Cardfooter { + padding: 20px; + border-top: 1px solid #e6e6e6; + background-color: #fff; +} + +.dataTable { + padding: 20px; + border-top: 1px solid #ebedf2; + background-color: #ffffff; + position: relative; +} + +.btn-grey { + color: #3a3a3a !important; + background-color: #f2f3f8 !important; + border: 1px solid #e9ecef !important; + min-width: 40px !important; + padding: 6px 12px; +} + +.ng-backtext { + font-size: 18px; + color: #48465b; + font-weight: 500; + vertical-align: text-top; +} + +.ng-backsvg { + height: 18px !important; + overflow: hidden; + vertical-align: text-bottom; +} + +.ng-backbtn a { + display: inline-flex; + align-items: center; + text-decoration: none !important; +} + +.temp_mobileBack, +.temp_mobiletopBack { + display: none; +} + +.form-control:focus { + border-color: #ced4da; + outline: 0; + box-shadow: unset; +} + +input:focus-visible { + outline-offset: unset; + outline: transparent; +} + +// Booking Css // +.app-BkGrid2 { + grid-template-columns: 1fr 1fr; + display: grid; + grid-gap: 20px; +} + +.bookingBorderCard { + border: 1px solid #bfbfbf; + height: fit-content; +} + +.listView:not(:last-child) { + border-bottom: 1px solid #bfbfbf; +} + +.border-b { + border-bottom: 1px solid #e6e6e6; +} + +.treeTableLabel { + text-align: left; +} + +.listView { + display: flex; + justify-content: flex-start; + padding: 8px; + align-items: center; +} + +.listView h5 { + font-weight: 500; + font-size: 14px !important; + margin: 0; +} + +.app-text { + font-size: 14px; + color: var(--color-body-text); + margin: 0; +} + +.bookingListHotel { + margin: 0 !important; + font-size: 14px; + font-weight: 500; + color: #004a92 !important; + text-decoration: underline !important; + font-weight: 600 !important; + cursor: pointer; +} + +// Booking Css End // +// Tabs Css // +.p-tabview .p-tabview-nav { + padding: 20px; + background-color: #fff; +} + +.p-tabview .p-tabview-nav li { + margin-right: 10px !important; + border-radius: 4px; +} + +.p-tabview .p-tabview-nav li .p-tabview-nav-link { + border: 2px solid #005eb8; + border-color: #005eb8 !important; + padding: 14px 18px !important; + border-radius: 4px !important; + color: var(--black) !important; + border: 1px solid #005eb8 !important; + width: 100%; + height: 100%; +} + +.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link { + background-color: var(--primary-theme) !important; + border-color: var(--primary-theme) !important; + color: #fff !important; + padding: 14px 18px !important; + border-radius: 4px !important; + width: 100%; + height: 100%; +} + +.p-tabview-title { + font-size: 14px; +} + +.bookingMngmnt_gridWrap { + display: grid; + grid-template-columns: 1fr 1fr auto; + grid-gap: 20px; +} + +.bookingMngmnt_gridWrap .bookingMngmnt_border, +.bookingMngmnt_gridWrapBorder .app-comCol:nth-child(odd) { + border-right: 1px solid #bfbfbf; +} + +.app-mainGrid2 { + grid-template-columns: repeat(2, 1fr); + display: grid; + grid-gap: 20px; +} + +.app-mainGrid3 { + grid-template-columns: repeat(3, 1fr); + display: grid; + grid-gap: 20px; +} + +.app-comCol { + display: flex; + align-items: start !important; + flex-direction: column; + padding: 6px 0; +} + +.app-bgtext { + font-size: 14px; + font-weight: 500; + margin-top: 0; + margin-bottom: 0; +} + +.bookinglink span { + margin: 0 !important; + font-size: 0.844rem; + font-weight: 500; + color: #004a92 !important; + text-decoration: underline !important; + font-weight: 600 !important; + cursor: pointer; +} + +// Tabs End // +// End // +.MainDivBtn-2 a { + text-decoration: underline; + font-size: 0.8rem; +} + +.MainDivBtn-2 { + display: flex; + align-items: center; +} + +.customSticky .sticky { + position: sticky; + background: white; + font-weight: 500; +} + +.customSticky .sticky { + left: 0px; + z-index: 2; +} + +.sectionCpyOn { + display: grid; + grid-template-columns: 85% 15%; +} + +.sectionCpyOnUI { + display: flex; + align-items: start; +} + +.back-to-top-btn { + margin-left: 20px; + white-space: nowrap; +} + +.app-modalHead { + font-size: 18px; + font-weight: 600; +} + +.book-TableData { + font-size: 14px; +} + +// overview +.overview-Hotelcard { + display: grid; + gap: 20px; + grid-template-columns: 300px auto; + + img { + width: 100%; + height: 250px; + border-radius: 6px; + object-fit: cover; + } +} + +.overview-Hotelheading { + font-size: 18px; + font-weight: 600; + margin: 15px 0 0 +} + +.hotel-rating { + color: #ffca36; + margin: 5px 0; + + .material-icons { + font-size: 18px; + } +} + +.hotel-address { + font-size: 16px; + font-weight: 400; + margin: 0; +} + +.formInputBorder .formInput { + border: 0; + background-color: transparent; +} + +.formInputBorder .formInput:hover { + box-shadow: unset; +} + +.tableWrapper ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option { + text-align: left !important; +} + +.rowColorGreen { + background-color: #11995f; + color: white; + + .material-icons { + color: white; + } +} + +.rowColorRed { + background-color: #c44b5a; + + .material-icons { + color: white; + } +} + +.rowColorRed ::ng-deep.formInput { + color: white; +} + +.rowColorRed ::ng-deep.formInput { + color: white; +} + +.rowColorGreen, +.rowColorBlue, +::ng-deep .formInputBorder .formInput { + color: white; +} + +.rowColorBlue input { + color: #ffffff; +} + +.rowColorBlue .formInput[readonly] { + background-color: transparent; +} + +.rowColorBlue .formInput { + padding-left: 12px !important; +} + +.rowColorWhite .formInput { + color: black; +} + +.rowColorgray div .text-center { + color: white; +} + +.table-Btnflex { + display: flex; + justify-content: flex-end; + gap: 15px; + padding: 15px; +} + +.table-Btnflex button { + border: 1px solid #636665; + border-radius: 50%; + background-color: transparent; + padding: 3px; + height: 35px; + width: 35px; +} + +.table-Btnflex .material-icons { + font-size: 25px; +} + +.tableDate { + display: flex; + align-items: center; + flex-direction: column; +} + +.weekData { + font-size: 14px; + color: #fff; + background-color: #0d5fb6; + padding: 1px 8px; + width: 50px; + border-radius: 4px; +} + +.numData { + font-size: 22px; + font-weight: 400; +} + +.monthData { + font-size: 14px; + color: #acacac; +} + +.formBorderSpace { + border: 0; + height: 40px; +} + +.tableWrapper ::ng-deep .ng-select .ng-select-container { + color: white !important; + background-color: transparent !important; + border: 0 !important; +} + +.tableWrapper ::ng-deep .ng-select .ng-arrow-wrapper::after { + content: ""; + display: none; +} + +.overview-hover .btn-hover svg { + display: none; + position: absolute; + right: -8px; +} + +.overview-hover .btn-hover { + display: flex !important; + align-items: center; + justify-content: flex-start; + width: 15px; + background-color: transparent; + border: 0; + padding: 0; + cursor: pointer; + position: relative; +} + +.overview-hover { + position: relative; +} + +.btn-hover p { + margin: 0; + text-align: center; + color: white; + font-size: 14px; +} + +.hoverDropDown.show { + display: block !important; + position: absolute; + top: 100%; + background: #fff; + z-index: 100; + left: 0; +} + +.hoverDropDown.show button { + border: 2px solid #e6e6e6; + background-color: transparent; + padding: 10px; + width: 135px; + height: 46px; +} + +.hoverDropDown { + display: none; +} + +.overview-hover:hover .btn-hover svg { + display: block; +} + +::ng-deep .ng-select .ng-arrow-wrapper::after:hover { + font-family: "Material Icons"; + content: "\e5d4"; + font-weight: normal; + font-style: normal; + display: block !important; + font-size: 30px; +} + +.pointer { + cursor: pointer; +} + +.rowColorBlue { + background-color: #2c50b6; + color: white; +} + +.rowColorgray { + background-color: #C7C7C5; + color: black; +} + +.contractCard { + text-align: left; + padding: 5px 10px; +} + +.wPx-300 { + width: 295px !important; + padding-top: 10px; +} + +.wPx-300:nth-child(2) { + text-align: start; + margin-left: 25px; +} + +.min-width-97 { + min-width: 97px; +} + +.formBorderSpace:not(:first-child) .wPx-300 { + width: 200px !important; +} + +.expandAdd { + display: flex; + align-items: center; + margin: 3px 0 0; + gap: 8px; + cursor: pointer; + font-size: 12px; +} + +.tableWrapper th { + background-color: #f2f3f8; +} + +.tableWrapper .formInput { + // height: 0; +} + +.box-wrapper { + border: 1px solid #e6e6e6; + border-collapse: collapse; + border-radius: 5px; + margin: 20px 0; +} + +.box-wrapper ::ng-deep .card { + border-radius: 0 0 0.25rem 0.25rem !important; + border: 0 !important; +} + +.box-header { + padding: 10px 15px; + background-color: #f7f8fa; + border-bottom: 1px solid #e6e6e6; + ; + border-radius: 5px 5px 0 0; + font-size: 18px; + font-weight: 600; +} + +.overview-Pricingcalendar { + border: 1px solid #e6e6e6; + border-collapse: collapse; + border-radius: 5px; + margin: 20px 0; +} + +.card { + padding: 20px; + background-color: #fff; + overflow: auto; +} + +.arrow_wrap { + display: flex; + flex-direction: column; + justify-content: center; +} + +.arrow_wrap.material-icons { + line-height: 10px; + font-size: 20px; +} + +.arrow_wrap .material-icons { + line-height: 10px; + font-size: 20px; +} + +.border-wrap { + border: 0 !important; +} + +.bL-0 { + border-left: 0 !important; +} + +.bR-0 { + border-right: 0 !important; +} + +.room-wrap { + font-weight: 500; +} + +.sub-header { + text-align: start; + margin-left: 10px; +} + +input[type=number]::-webkit-outer-spin-button, +input[type=number]::-webkit-inner-spin-button { + -moz-appearance: textfield; + /* Ensure Firefox displays the arrows */ +} + +.soldOut { + display: flex; + white-space: nowrap; + align-items: center; + + .min-width100 { + color: #fff; + } +} + +.collapse-wrap { + width: 210px; +} + +.sticky { + position: sticky; + background: white; + left: 0px; + z-index: 2; +} + +@media screen and (max-width: 768px) { + .overview-Hotelcard { + display: block; + } + +} + +// end + +// header +.headerWrapper { + background: #fff; + border-bottom: 1px solid #eff0f6; + max-width: 100%; + padding: 10px 40px; + z-index: 999; + min-height: 70px; + position: relative; + height: 100%; + display: flex; + align-items: center; + justify-content: flex-end; +} + +.headerWrapper .h-100 { + height: 100%; +} + +.ng-aside-brand.ng-asidebar-active ::ng-deep .ng-asideToggle span svg { + transform: scaleX(1); +} + +.ng-aside-brand ::ng-deep .ng-asideToggle span svg { + transform: scaleX(-1); +} + +.logout_svg_d-f { + display: flex; + align-items: center; + grid-gap: 5px; +} + +.logout_svg_d-f p, +::ng-deep .mat-menu-item p { + font-size: 14px; + font-weight: 500; +} + +::ng-deep .mat-menu-item { + display: flex !important; + align-items: center; + grid-gap: 5px; +} + +.profile-svg { + background-color: var(--primary-theme); + display: flex; + align-items: center; + justify-content: center; + height: 35px; + border-radius: 50%; + width: 35px; +} + +@media screen and (max-width: 960px) { + .headerWrapper { + width: 100%; + justify-content: space-between; + padding: 0 16px; + } + + .headerWrapper img { + width: 180px; + object-fit: contain; + } + + .User_loginDetailMob .btn-icon { + display: block; + border-radius: 5px; + border: 0px solid #bfbfbf !important; + background: none !important; + } + + .User_DetalWrapper { + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; + top: 70px; + position: fixed; + right: 15px; + -webkit-box-pack: end; + -ms-flex-pack: end; + z-index: 1; + } + + .User_DetalWrapper .logout_DropdownLinks { + border: 1px solid #dbcdcd; + background: white; + border-radius: 8px; + -webkit-box-shadow: 0px 1px 9px -3px rgba(0, 0, 0, 0.1); + box-shadow: 0px 1px 9px -3px rgba(0, 0, 0, 0.1); + } + + .logout_svg_d-f { + border-bottom: 1px solid #bfbfbf; + } + + .MenuBtn { + display: flex; + align-items: center; + background: transparent; + border: transparent; + } + + .MenuBtn span { + font-size: 26px; + line-height: unset !important; + } +} + +.UserDetail button.mat-menu-item { + background: #76bcfa !important; +} + +.mat-menu-panel { + min-height: unset !important; +} + +.UserDetail .kt-header__topbar-welcome { + font-size: 12.6px; + font-weight: 500; + letter-spacing: 0.3px; +} + +.ng-header-button { + padding: 0 8px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-item-align: center; + align-self: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + height: 38px; + cursor: pointer; + border-radius: 4px; +} + +.UserDetail .menu-dropdown { + display: flex; + align-items: center; + gap: 3px; + + span { + display: flex; + letter-spacing: normal; + } +} + +.links_Item:first-child { + border-bottom: 1px solid #edf1f3; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.links_Item { + color: black; + font-size: 14px; + display: grid; + align-items: center; + grid-template-columns: 20px auto; + grid-gap: 3px; + // border-bottom-right-radius: 8px; + // border-bottom-left-radius: 8px; + cursor: pointer; + padding: .8rem; + + span { + display: flex; + } + + .material-icons { + font-size: 18px; + } +} + +.ErrorWrapper .ng-dropdown-panel.ng-select-bottom { + margin-top: 0 !important; +} + + +.links_Item:hover { + color: black; + background-color: var(--secondary-light); +} + +.LastLogin_links_Item { + gap: 3px; + display: flex; + white-space: nowrap; + + .material-icons { + font-size: 18px; + } +} + +::ng-deep .mat-mdc-menu-panel { + overflow: hidden !important; + border-radius: 8px !important; +} + +.mat-mdc-menu-content { + padding: 0 !important; +} + +.header-bar.logo { + opacity: 0; +} + +.header-bar { + opacity: 1; +} + +.header-bar { + cursor: pointer; + display: flex; + justify-content: center; +} + +.header-bar img { + max-width: 170px; + object-fit: contain; + max-height: 130px; +} + +// End +// footer +.ng-footer { + padding: 15px; + background: #ffffff; + max-width: 100%; +} + +.ng-footerBody { + display: flex; + justify-content: space-between; + align-content: center; +} + +.ng-footerCopy { + margin: 0px; +} + +.ng-footerItems { + list-style: none; + display: flex; + padding: 0; + margin: 0; +} + +.ng-footerItems li { + padding-right: 10px; +} + +//end +//verify email +.custom-container { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + font-family: "Segoe UI", sans-serif; +} + +.custom-card { + width: 400px; + background-color: #ffffff; + box-shadow: 0 0 10px #33333330; + padding: 40px 20px; + padding-bottom: 15px; + border-radius: 8px; +} + +.custom-card.cardDenied { + border-bottom: 5px #ed5565 solid; +} + +.custom-card.cardExpired { + border-bottom: 5px #ff5252 solid; +} + +.custom-card.cardDeactive { + border-bottom: 5px #4bae4f solid; +} + +.card-content { + display: flex; + align-items: center; + flex-direction: column; + text-align: center; +} + +img { + border-style: none; +} + +.thanks-text { + margin-top: 5px; + margin-bottom: 0; + +} + +.approve-text { + margin-bottom: 10px; + margin-top: 0; +} + +.thanks-text, +.approve-text { + font-size: 1.5rem; + font-weight: 500; +} + +.card-content p { + font-weight: 500; + color: var(--color-body-text); + font-size: 14px; +} + +@media screen and (max-width: 960px) { + .custom-card { + width: 350px; + height: 280px; + padding: 20px; + display: flex; + align-items: center; + justify-content: center; + } + + .thanks-text, + .approve-text { + font-size: 20px; + } + + .card-content svg, + .card-content img { + margin-bottom: 15px; + } + + +} + +//end +//unauthorized +.error-404 { + background-color: #fff; + height: 100%; +} + +.errorWrap { + display: flex; + align-items: center; + justify-content: center; + height: 80vh; +} + +.errorContent { + text-align: center; +} + +.errorContent h1 { + font-size: 8rem; + font-weight: bolder; + color: #0c6cbf; +} + +.errorContent h3 { + margin: 0 auto; + font-weight: bolder; + width: 76%; +} + +.errorContent h5 { + margin-top: 15px; + color: #878787; + font-weight: 400; +} + +@media (max-width: 960px) { + .errorWrap { + flex-direction: column; + } + + .errorSvG svg { + width: 100%; + height: 245px; + } + + .errorContent h1 { + font-size: 7rem; + } + + .errorContent h3 { + font-size: 22px; + width: 93%; + } + .m-mb15 { + margin-bottom: 15px; + } + + .d-flex-col { + flex-direction: column; + gap: 10px; + } + + .f-width { + width: 100% !important; + } + .text-left { + text-align: left !important; + } +} + +//end +//loader +// .progress-loader { +// height: 100%; +// } + +.loading-spinner { + background-color: rgb(0 0 0 / 44%); + position: fixed; + width: 100%; + top: 0px; + left: 0px; + height: 100vh; + align-items: center; + justify-content: center; + display: grid; + z-index: 999999; +} + +.loading-spinner img { + align-self: flex-end; + z-index: 999; +} + +.loading-message { + text-align: center; + align-self: start; + color: white; +} + +/** +* ============================================== +* Dot Pulse +* ============================================== +*/ +.dot-pulse { + position: relative; + left: -9999px; + width: 10px; + height: 10px; + border-radius: 5px; + background-color: #fff; + color: white; + box-shadow: 9999px 0 0 -5px #10263d; + animation: dotPulse 1.5s infinite linear; + animation-delay: .25s; +} + +.dot-pulse::before, +.dot-pulse::after { + content: ''; + display: inline-block; + position: absolute; + top: 0; + width: 10px; + height: 10px; + border-radius: 5px; + background-color: #fff; + color: white; +} + +.dot-pulse::before { + box-shadow: 9984px 0 0 -5px #fff; + animation: dotPulseBefore 1.5s infinite linear; + animation-delay: 0s; +} + +.dot-pulse::after { + box-shadow: 10014px 0 0 -5px #fff; + animation: dotPulseAfter 1.5s infinite linear; + animation-delay: .5s; +} + +@keyframes dotPulseBefore { + 0% { + box-shadow: 9984px 0 0 -5px #fff; + } + + 30% { + box-shadow: 9984px 0 0 2px #fff; + } + + 60%, + 100% { + box-shadow: 9984px 0 0 -5px #fff; + } +} + +@keyframes dotPulse { + 0% { + box-shadow: 9999px 0 0 -5px #fff; + } + + 30% { + box-shadow: 9999px 0 0 2px #fff; + } + + 60%, + 100% { + box-shadow: 9999px 0 0 -5px #fff; + } +} + +@keyframes dotPulseAfter { + 0% { + box-shadow: 10014px 0 0 -5px #fff; + } + + 30% { + box-shadow: 10014px 0 0 2px #fff; + } + + 60%, + 100% { + box-shadow: 10014px 0 0 -5px #fff; + } +} + +.outboundCard { + border: 1px solid #cccccc; + border-radius: 4px; + padding: 15px; + margin-bottom: 20px; +} + +.outboundCardDuplicate { + display: flex; + justify-content: flex-end; + margin-bottom: 15px; + gap: 10px; +} + +//end \ No newline at end of file diff --git a/src/scss/_dataTable.scss b/src/scss/_dataTable.scss new file mode 100644 index 0000000..cce51ec --- /dev/null +++ b/src/scss/_dataTable.scss @@ -0,0 +1,379 @@ +.card { + padding: 20px; + background-color: #fff; + border: 0; + overflow: auto; +} + +.p-paginator .p-dropdown { + margin: 0; +} + +.p-datatable { + + .p-datatable-header, + .p-paginator, + .p-toolbar { + padding: 0; + border: 0; + background-color: #ffffff; + padding-top: 25px !important; + } + + .p-datatable-thead>tr>th { + text-align: center; + font-size: 14px; + position: relative; + color: #fff !important; + background: var(--primary-theme) !important; + + &:focus { + box-shadow: none !important; + } + + .p-sort-icon { + .p-sortable-column-icon { + height: 10px; + color: #fff !important; + } + } + } + + .p-datatable-tbody>tr>td { + font-size: 14px; + text-align: center; + padding: 1rem .5rem; + } + + .p-paginator-current { + margin-right: auto; + } +} + +// table status +.product-badge { + border-radius: 4px; + padding: 2px 8px; + font-weight: 600; + font-size: 12px; +} + +.product-badge.status-instock { + background: #c8e6c9; + color: #256029; +} + +.product-badge.status-lowstock { + background: #feedaf; + color: #8a5340; +} + +.product-badge.status-outofstock { + background: #ffcdd2; + color: #c63737; +} + +.text-success { + color: #62bc55; +} + +.text-danger { + color: red; +} + +// table paginator +.p-paginator .p-inputwrapper { + position: absolute; + left: 0; + top: 0; +} + +.p-paginator { + + .p-paginator-last, + .p-paginator-next, + .p-paginator-first, + .p-paginator-prev { + background-color: #ebe9f2; + min-width: 30px !important; + height: 30px !important; + } + + .p-paginator-current { + padding: 0; + } +} + +.actionButton { + .mat-icon-button { + border: 1px solid #c1c1c1; + border-radius: 5px; + } + + .mat-icon-button:hover { + background-color: #f2f3f8 !important; + color: var(--primary-theme); + border: 0 !important; + } + + .mat-icon-button { + width: 35px !important; + height: 30px !important; + line-height: 23px !important; + } + + .material-icons { + font-size: 22px !important; + } +} + +.p-datatable.p-datatable-hoverable-rows .p-datatable-tbody>tr:not(.p-highlight):hover { + background: none !important; + color: inherit !important; +} + +.p-datatable .p-datatable-tbody>tr:focus { + outline: none !important; +} + +.p-dropdown-clear-icon { + display: none !important; +} + +.p-paginator { + & .p-paginator-page { + min-width: 30px !important; + height: 30px !important; + + &.p-highlight { + background: var(--primary-theme) !important; + border-color: var(--primary-theme) !important; + color: var(--surface-section) !important; + } + + &:focus { + box-shadow: none; + } + } +} + +.product-badge.status-active { + background: #e8fff3 !important; + color: #50cd89 !important; + padding: 4px 8px !important; +} + +.product-badge.status-inactive { + background: #ffebeb; + color: #f1416c; +} + +.p-paginator .p-dropdown .p-inputtext { + border: 0 !important; +} + +.p-toolbar .p-toolbar-group-right { + margin-left: auto; +} + +.p-datatable-responsive-scroll>.p-datatable-wrapper { + // min-width: 90pc; +} + +/* Track */ +::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 10px; +} + +/* Handle */ +::-webkit-scrollbar-thumb { + background: var(--primary-theme); + border-radius: 10px; +} + +/* Handle on hover */ +// ::-webkit-scrollbar-thumb:hover { +// background: var(--primary-theme); +// } +@media screen and (max-width: 768px) { + .card { + padding: 15px; + } + + .p-toolbar-group-right { + width: 100%; + display: block !important; + margin-top: 20px; + } + + .p-datatable-wrapper { + overflow: auto; + } + + .p-paginator-current { + width: 100%; + justify-content: start !important; + } + + .p-input-icon-left { + display: flex !important; + } + + .p-inputtext { + width: 100% !important; + } + + .p-datatable-table { + min-width: 50pc !important; + } +} + +.ResultNotFound { + height: 42px; +} + +.ResultNotFound td { + position: absolute !important; + width: 100%; + text-align: center; +} + +.p-datatable-wrapper { + margin-top: 20px; + padding-bottom: 10px; +} + +.p-datatable-wrapper::-webkit-scrollbar-thumb { + background: var(--primary-theme); +} + +::-webkit-scrollbar-thumb { + background: var(--primary-theme); + border-radius: 10px; +} + +.p-datatable-wrapper::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +.scroll-host::-webkit-scrollbar { + width: 7px; +} + +.scroll-host::-webkit-scrollbar-thumb { + height: 20px; + background: var(--primary-theme); +} + +.scroll-host::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 0; +} + +.p-datatable-wrapper::-webkit-scrollbar { + height: 10px; + width: 10px; +} + +// update cancel policy +.formInputBorder .formInput:hover { + box-shadow: unset; +} + +.wPx-200 { + width: 130px !important; +} + +.wPx-90 { + max-width: 90px !important; +} + +.customSticky .sticky, +.customSticky .sticky2 { + position: sticky; + background: white; + font-weight: 500; +} + +.customSticky .sticky { + left: 0px; +} + +.customSticky .sticky2 { + left: 97px; + z-index: 2; +} + +.commonSection { + width: 90%; +} + +.sectionCpyOn { + display: grid; + grid-template-columns: 78% 20%; + gap: 15px; +} + +.tableWrapper ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option { + text-align: left !important; +} + +@media screen and (max-width: 960px) { + .sectionCpyOn { + display: flex; + flex-direction: column-reverse; + gap: 10px; + } +} + +// end +// update allocation +.formInputBorder .formInput:hover { + box-shadow: unset; +} + +.wPx-200 { + width: 150px !important; + margin: auto; +} + +.commonSection { + width: 90%; +} + +.sectionCpyOn { + display: grid; + grid-template-columns: 80% 20%; + gap: 10px; +} + +.tableWrapper ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option { + text-align: left !important; +} + +.rowColorGreen { + background-color: #4caf50; + color: white; +} + +.rowColorRed { + background-color: #d14d4d; + color: white; +} + +.rowColorGreen input, +.rowColorRed input { + color: white !important; +} + +.rowColorGreen .formInput[readonly], +.rowColorRed .formInput[readonly] { + color: black !important; +} + +// end \ No newline at end of file diff --git a/src/scss/_dropzone.scss b/src/scss/_dropzone.scss new file mode 100644 index 0000000..cb088ab --- /dev/null +++ b/src/scss/_dropzone.scss @@ -0,0 +1,368 @@ +.customDropzone .p-fileupload-files .ng-star-inserted:nth-child(1) { + display: flex; + align-items: center; +} + +.customDropzone .p-fileupload-row>div:last-child button { + top: 5px !important; + right: 6px; +} + +// dropzone +.customDropzoneSingal .p-progressbar { + display: none; +} + +.customDropzoneSingal .p-fileupload-row>div:nth-child(2), +.customDropzoneSingal .p-fileupload-row>div:nth-child(3) { + display: none !important; +} + +.customDropzoneSingal .p-fileupload-row { + position: relative; +} + +.customDropzoneSingal .p-fileupload-row>div:first-child { + height: 120px; + width: 120px; + flex: none; +} + +.customMultiDropzone .p-fileupload-content { + display: none; +} + +.customDropzone .p-fileupload .p-fileupload-row>div { + padding: 1rem 0 !important; +} + +.customDropzoneSingal .p-fileupload-row>div:first-child img { + height: 110px; + width: 110px; + border-radius: 8px; +} + +.customDropzoneSingal .p-fileupload-row>div:last-child button { + position: absolute; + // left: 110px; + width: 20px; + height: 20px; + top: 25px; + right: 22px; + border-radius: 50%; +} + +.customDropzoneSingal .p-fileupload-content { + padding: 0 !important; + border: 0 !important; +} + +.customDropzoneSingal .p-fileupload .p-fileupload-buttonbar { + background: transparent; + border: 1px solid transparent; + padding: 0; + // padding-top: 20px; +} + +.customDropzoneSingal .p-fileupload-row>div:last-child button .p-button-icon { + font-size: 12px; +} + +.customDropzoneSingal .p-fileupload-files .ng-star-inserted { + padding-top: 9px; + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; +} + +.p-fileupload .p-fileupload-row>div img { + width: 120px !important; +} + +.customDropzone .p-progressbar { + display: none; +} + +.customDropzone .p-fileupload-row>div:nth-child(2), +.customDropzone .p-fileupload-row>div:nth-child(3) { + display: none !important; +} + +.customDropzone .p-fileupload-row { + position: relative; +} + +.customDropzone .p-fileupload-row>div:first-child { + height: 120px; + width: 120px; + flex: none; +} + +.customDropzone .p-fileupload-row>div:first-child img { + height: 110px; + width: 110px; + border-radius: 8px; +} + +.customDropzone .p-fileupload-row>div:last-child button { + position: absolute; + // left: 110px; + width: 20px; + height: 20px; + top: 25px; + border-radius: 50%; +} + +.customDropzone .p-fileupload-content { + padding: 0 !important; + border: 0 !important; +} + +// .customDropzone .p-fileupload-content .p-element { +// // display: none; +// } +.customDropzone .p-fileupload .p-fileupload-buttonbar { + background: transparent; + border: 1px solid transparent; + padding: 0; + // padding-top: 20px; +} + +.customDropzone .p-fileupload-row>div:last-child button .p-button-icon { + font-size: 12px; +} + +// .customDropzone .p-fileupload-files .ng-star-inserted {} +.customDropzone .ng-star { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; +} + +.p-fileupload .p-fileupload-content { + border: 0; + padding: 0; +} + +.p-fileupload .p-fileupload-buttonbar { + background-color: unset; + padding: 0; + border: 0; +} + +.customDropzone .p-fileupload .p-fileupload-buttonbar, +.p-fileupload .p-fileupload-content { + background: transparent !important; + padding: 0 !important; + padding-top: 0.5rem !important; + border: 0 !important; +} + +.customDropzone .p-fileupload-row { + position: relative; + margin-top: 5px; + gap: 10px; +} + +.customDropzone .p-fileupload-row>div:first-child { + width: 110px !important; + flex: none !important; + padding: 0 !important; + margin: 0 !important; + margin-right: 10px !important; +} + +.customDropzone .p-fileupload-row>div:first-child img { + height: 100px !important; + width: 110px !important; + border-radius: 8px !important; + border: 1px solid #cccccc !important; + margin-right: 5px !important; + object-fit: fill !important; + object-position: top !important; +} + +.customDropzone .p-button { + background-color: #f2f3f8 !important; + border: 1px solid #ccc !important; +} + +.customDropzone .p-button-label { + font-size: 16px; + line-height: 1.3; +} + +.customDropzone .pi.pi-plus { + font-size: 0.8rem; +} + +.customDropzone .p-button.p-fileupload-choose { + border: none; + padding: 0.5rem 0.6rem; + height: 40px !important; + background: var(--primary-theme) !important; +} + +.customDropzone .p-fileupload-row>div:last-child button .p-button-icon { + font-size: 12px; + color: #000; + position: absolute; + left: 3px; + top: 3px; +} + +.customDropzone .p-fileupload-choose.p-button:focus { + box-shadow: none; +} + +.customDropzone .ng-label { + margin-bottom: 2px; +} + +.customDropzone .p-fileupload-row>div:first-child { + min-height: 55px !important; + margin: 0 !important; +} + +.customDropzone .p-fileupload-row>div:last-child button { + left: 39px !important; + width: 16px !important; + height: 10px !important; +} + +.customDropzone .p-fileupload-row>div:last-child button { + position: absolute !important; + left: 90px !important; + width: 20px !important; + height: 20px !important; + top: 0 !important; + border-top-right-radius: 7px !important; +} + +.customDropzone .p-fileupload-content { + padding: 0 !important; + border: 0 !important; +} + +.customDropzone .singleImage .p-fileupload-row>div:first-child { + padding: 0 !important; +} + +.customDropzone .p-fileupload .p-fileupload-row>div { + padding: 0px !important; + margin: 1rem 0 !important; +} + +.customDropzone .p-fileupload-row>div:nth-child(2), +.customDropzone .p-fileupload-row>div:nth-child(3), +.customDropzone .p-fileupload-buttonbar .p-button:last-child, +.customMultiDropzone .p-fileupload-files>.ng-star-inserted, +.customDropzone .p-progressbar { + display: none !important; +} +.customDropzone.customUpload .p-fileupload-buttonbar .p-button:last-child { + display: unset !important; +} +.customDropzone { + .p-icon-wrapper { + color: #fff; + font-size: 12px !important; + } + .p-icon-wrapper svg { + height: 14px; + width: 14px; + } +} +.customDropzone .p-fileupload .p-fileupload-content { + background: transparent; + padding: 0; + border: none; + color: inherit; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.customDropzone .fileDropzone { + height: 120px !important; + width: 120px !important; + flex: none; + padding: 0.5rem 0 !important; +} + +.customDropzone .fileDropzone .p-fileupload-files { + overflow: auto; +} + +/* Note */ +.customDropzone .shortNote { + font-size: 12px; + display: inline-block; + margin-top: 5px; + color: #212529; +} + +.customDropzone .shortNote span, +.AgencyshortNote span { + font-weight: 700; +} + +.customDropzone .AgencyshortNote { + font-size: 12px; + display: inline-block; + margin-top: 5px; + color: #212529; +} + +.customDropzone .uploadDoc { + display: flex; + align-items: end; + width: 50%; +} + +.customDropzone .uploadDoc .ng-Label { + font-size: 16px; +} + +/* Theme Setting Dropzone */ +.customDropzone .theme-fileUpload .p-fileupload .p-fileupload-content { + background: transparent; + padding: 0; + border: none; + color: inherit; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.customDropzone .theme-fileUpload .p-fileupload-files { + border: 1px solid #dee2e6; + text-align: center; + margin-top: 10px; + border-radius: 4px; +} +.customUpload { + .p-button { + background-color: var(--primary-theme); + } + .p-icon-wrapper { + color: #fff; + font-size: 12px !important; + } + .p-icon-wrapper svg { + height: 14px; + width: 14px; + } +} +.room_Amenities { + display: flex; + align-items: center; +} + +.w-40 { + width: 40%; +} + +.w-60 { + width: 60%; +} + +.room_AmenitiesBox { + white-space: nowrap; +} \ No newline at end of file diff --git a/src/scss/_input.scss b/src/scss/_input.scss new file mode 100644 index 0000000..98bc168 --- /dev/null +++ b/src/scss/_input.scss @@ -0,0 +1,111 @@ +.formLabel { + display: block; + font-size: 14px; + margin-bottom: 5px; + text-align: start; + white-space: nowrap; +} +.ng-label { + display: block; + font-size: 15px; +} +.formInput.loginPassword{ + padding: 1rem 2.3rem; +} +.formInput { + padding: 8px 10px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 14px; + outline: none; + width: 100%; + height: 40px; + color: var(--text-color); + font-family: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} +.p-inputtext:enabled:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: unset !important; +} + +.p-inputtext:enabled:hover, +.p-inputtext:enabled:focus, +.p-inputtext { + border: 1px solid #ccc; +} +textarea.formInput { + width: 100% ; + height: auto; +} +.formInput:hover { + box-shadow: 0 1px 0 rgb(0 0 0 / 6%); +} +.formCheck { + font-size: 14px; +} +.phoneBox { + display: grid; + grid-template-columns: 35% 65%; +} +.phoneBox .ng-select.ng-select-single .ng-select-container { + border-radius: 4px 0 0 4px !important; + border-right: 0 !important; +} +.phoneBox .formPhone { + border-radius: 0 4px 4px 0 !important; +} +.errorInput .ng-select-container { + border: 1px solid red !important; +} +.errorInput .ng-select-container { + border: 1px solid red !important; +} +.formInput.errorInput { + border: 1px solid red !important; +} + .p-toolbar-group-right { + .p-input-icon-left>.p-inputtext { + padding-left: 2rem !important; + } +} + .p-inputtext { + padding: 6.5px 10px !important; +} + +// ng select +.ng-clear-wrapper { + display: none !important; +} +// placeholder styles +::placeholder { + color: #999; + font-size: 14px; +} +:-ms-input-placeholder { + color: #999; + /* Internet Explorer 10-11 */ + font-size: 14px; +} +::-ms-input-placeholder { + color: #999; + /* Microsoft Edge */ + font-size: 14px; +} + .ng-select.ng-select-focused:not(.ng-select-opened) .ng-select-container { + box-shadow: none !important; +} +.border-left { + border-radius: 5px 0px 0px 5px !important; +} +.border-right { + border-radius: 0px 5px 5px 0px !important; +} + .ng-value-container input { + font-size: 14px !important; +} +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{ + white-space: nowrap; + overflow: hidden; + width: 85%; +} \ No newline at end of file diff --git a/src/scss/_login.scss b/src/scss/_login.scss new file mode 100644 index 0000000..c5820fb --- /dev/null +++ b/src/scss/_login.scss @@ -0,0 +1,340 @@ +.app-loginWrap, +.app-ForgotWrap { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-size: cover !important; + background: url(https://aosedge.b-cdn.net/Static/bannerimage2.jpg); + background-repeat: no-repeat; + background-position: center; +} +.app-loginBody { + display: flex; + align-items: center; + justify-content: space-between; + height: 100%; + width: 100%; + position: relative; +} +.overlay { + background-color: #00000054; + position: fixed; + top: 0; + bottom: 0; + width: 100%; + height: 100%; + right: 0; +} +.app-loginContent { + width: 450px; + padding: 40px 40px; + background-color: #ffffff; + border-radius: 8px; +} +.login-textWrap { + color: #fff; + max-width: 380px; +} +.login-head { + font-size: 35px; + margin-bottom: 0; + font-weight: 600; +} +.loginHead { + margin-bottom: 25px; +} +.loginHead h3, +.temp_loginPassHeading { + font-size: 24px; + font-weight: 700; + margin-bottom: 0px; + margin-top: 0; +} +.loginHead p { + margin: 3px 0 0; + text-align: left; + font-size: 16px; + font-weight: 400; +} +.login-text { + font-size: 16px; +} +.temp_loginOtpTitle { + font-size: 16px; + font-weight: 500; + margin-bottom: 0; +} +.input-wrap { + position: relative; +} +.loginF_icons { + position: absolute; + left: 13px; + z-index: 999; + height: 100%; +} +.eyeICon { + top: 0; + right: 0; + bottom: 0; + margin: 10px; + position: absolute; + color: #6c757d; + cursor: pointer; + display: flex; + align-items: center; +} +.input-wrap .formInput { + width: 100%; + height: 42.4px; + outline: none; + font-size: 16px; + padding: 1rem 2.3rem; + border-radius: var(--border-radius); + -webkit-background-clip: text !important; +} +.forgetPass { + margin: 0 !important; + font-size: 0.844rem; + font-weight: 500; + color: #004a92 !important; + text-decoration: none !important; + font-weight: 600 !important; + cursor: pointer; +} +.app-loginLogo { + margin-bottom: 30px; +} +.app-loginLogo img { + max-width: 150px; +} +.loginNote h4 { + font-size: 14px; + font-weight: 500; + text-align: center; + margin-top: 30px; + margin-bottom: 0; + line-height: 1.5; +} +.loginNote .contactUs { + color: #004a92; + font-weight: 500; + cursor: pointer; +} +.app-loginContent .ng-backbtn { + margin-bottom: 1rem; + cursor: pointer; +} +.ng-backbtn a { + display: inline-flex; + margin: 2px 0; + align-items: center; + text-decoration: none !important; +} +.app-loginContent .ng-backbtn .ng-backsvg { + height: 14px !important; + margin-right: 4px; + margin-top: 2px; +} +.app-loginContent .ng-backtext { + font-size: 16px !important; + font-weight: 400; +} +.loginFooter { + margin-top: 30px; +} +.loginFooter .btn, +.verifyBtn .btn, +.profileReset_pwdBtn .btn { + height: 46px; + cursor: pointer; + border-radius: var(--border-radius); +} +.app-loginOtpWrap .codeText { + font-size: 14px; + font-weight: 500; + color: var(--color-body-text); +} +.codeText span:first-child { + font-size: 14px; + font-weight: 400; +} +.temp_loginResendOtp { + text-align: left; + margin: 15px 0; +} +.app-loginOtpWrap .ng-otp-input-wrapper { + border: 1px solid #cccccc; + border-radius: 8px; + display: flex; + padding: 0 10px; + justify-content: center; +} +.app-loginOtpWrap .ng-otp-input-wrapper .otp-input { + width: 28px; + height: 48px; + user-select: none; + font-size: 18px !important; + border: 0 !important; + font-weight: 500; + color: var(--color-body-text); + margin: 0 !important; + padding-bottom: 5px; +} +.app-loginOtpWrap .ng-otp-input-wrapper .otp-input:focus-visible { + outline: 0; + border: 0 !important; +} +.resendOTP { + margin: 10px 0; + font-size: 14px; + font-weight: 500; +} +@media screen and (max-width: 960px) { + .login-textWrap { + display: none; + } + .app-loginContent { + width: 100%; + padding: 30px 20px; + } + .app-loginBody { + padding: 0 15px; + max-width: 100%; + min-height: 100vh; + } +} +@media screen and (min-width: 1301px) { + .app-loginBody { + max-width: 75%; + min-height: 100vh; + } +} +@media screen and (min-width: 960px) and (max-width: 1300px) { + .app-loginBody { + max-width: 80%; + min-height: 100vh; + } +} +//forget your pass +.app-ForgotWrap { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + } + + .profileReset_pwdWrapper { + max-width: 440px; + border-radius: var(--border-radius); + box-shadow: #63636333 0 2px 8px; + background-color: #fff; + margin: 5rem auto; + padding: 2.5rem; + padding-top: 1.8rem; + } + + .loginTxt { + font-size: 14px; + } + + .resetHead h4 { + font-size: 24px; + font-weight: 700; + margin: 0 0 15px 0; + } + + .conditiontrue_wrapper { + display: grid; + grid-template-columns: 1fr 1fr; + } + + .conditiontrue_wrapper ul { + padding-left: 0 !important; + list-style: none; + } + + .PswdCriteria { + display: flex; + align-items: center; + font-size: 14px; + } + + .conditiontrue_wrapper li::before { + border-radius: var(--border-radius); + background: #ccc; + content: ""; + display: inline-block; + width: 6px; + height: 6px; + margin-right: 10px; + } + + .profileReset_pwdBtn { + padding-top: 14px; + } + + .profileReset_pwdBtn .btn { + height: 46px; + border-radius: var(--border-radius); + } + + .formControlWrapper { + position: relative; + } + .custom-card { + width: 400px; + background-color: #ffffff; + box-shadow: 0 0 10px #33333330; + padding: 40px 20px; + padding-bottom: 15px; + border-radius: 8px; + } + .custom-card.cardDenied { + border-bottom: 5px #ed5565 solid; + } + .card-content { + display: flex; + align-items: center; + flex-direction: column; + text-align: center; + } + .loginNote{ + margin: 5px 0 0 0; + font-size: 18px; + font-weight: 500; + } + .contactUs{ + margin: 15px 0 0 0; + font-size: 14px; + font-weight: 500; + } + @media screen and (max-width: 960px) { + .profileReset_pwdWrapper { + width: 350px; + padding: 20px; + } + } + + .passSuggest .PswdSuccess:before { + background-color: #3ed23e !important; + } + + .PswdSuccess::before { + background-color: #3ed23e !important; + } + + .PswdFail::before { + background: #ccc !important; + } + + .PswdSuccess::marker { + color: #3ed23e !important; + } + //end \ No newline at end of file diff --git a/src/scss/_rowCol.scss b/src/scss/_rowCol.scss new file mode 100644 index 0000000..0612657 --- /dev/null +++ b/src/scss/_rowCol.scss @@ -0,0 +1,749 @@ +.row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; + } + + .no-gutters { + margin-right: 0; + margin-left: 0; + } + + .no-gutters > .col, + .no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; + } + + .col, + .col-1, + .col-10, + .col-11, + .col-12, + .col-2, + .col-3, + .col-4, + .col-5, + .col-6, + .col-7, + .col-8, + .col-9, + .col-auto, + .col-lg, + .col-lg-1, + .col-lg-10, + .col-lg-11, + .col-lg-12, + .col-lg-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-auto, + .col-md, + .col-md-1, + .col-md-10, + .col-md-11, + .col-md-12, + .col-md-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-auto, + .col-sm, + .col-sm-1, + .col-sm-10, + .col-sm-11, + .col-sm-12, + .col-sm-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-auto, + .col-xl, + .col-xl-1, + .col-xl-10, + .col-xl-11, + .col-xl-12, + .col-xl-2, + .col-xl-3, + .col-xl-4, + .col-xl-5, + .col-xl-6, + .col-xl-7, + .col-xl-8, + .col-xl-9, + .col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; + } + + .col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + + .col-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + + .col-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + + .col-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + + .col-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + + .col-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + + .col-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + + .col-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + + .col-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .offset-1 { + margin-left: 8.333333%; + } + + .offset-2 { + margin-left: 16.666667%; + } + + .offset-3 { + margin-left: 25%; + } + + .offset-4 { + margin-left: 33.333333%; + } + + .offset-5 { + margin-left: 41.666667%; + } + + .offset-6 { + margin-left: 50%; + } + + .offset-7 { + margin-left: 58.333333%; + } + + .offset-8 { + margin-left: 66.666667%; + } + + .offset-9 { + margin-left: 75%; + } + + .offset-10 { + margin-left: 83.333333%; + } + + .offset-11 { + margin-left: 91.666667%; + } + + @media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-sm-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-sm-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-sm-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-sm-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-sm-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-sm-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-sm-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-sm-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-sm-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-sm-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-sm-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-sm-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-sm-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.333333%; + } + .offset-sm-2 { + margin-left: 16.666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.333333%; + } + .offset-sm-5 { + margin-left: 41.666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.333333%; + } + .offset-sm-8 { + margin-left: 66.666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.333333%; + } + .offset-sm-11 { + margin-left: 91.666667%; + } + } + + @media (min-width: 1024px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-md-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-md-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-md-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-md-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-md-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-md-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-md-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-md-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-md-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-md-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-md-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-md-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-md-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.333333%; + } + .offset-md-2 { + margin-left: 16.666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.333333%; + } + .offset-md-5 { + margin-left: 41.666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.333333%; + } + .offset-md-8 { + margin-left: 66.666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.333333%; + } + .offset-md-11 { + margin-left: 91.666667%; + } + } + + @media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-lg-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-lg-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-lg-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-lg-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-lg-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-lg-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-lg-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-lg-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-lg-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-lg-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-lg-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-lg-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-lg-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.333333%; + } + .offset-lg-2 { + margin-left: 16.666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.333333%; + } + .offset-lg-5 { + margin-left: 41.666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.333333%; + } + .offset-lg-8 { + margin-left: 66.666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.333333%; + } + .offset-lg-11 { + margin-left: 91.666667%; + } + } + + @media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-xl-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-xl-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-xl-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-xl-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-xl-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-xl-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-xl-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-xl-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-xl-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-xl-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-xl-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-xl-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-xl-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.333333%; + } + .offset-xl-2 { + margin-left: 16.666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.333333%; + } + .offset-xl-5 { + margin-left: 41.666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.333333%; + } + .offset-xl-8 { + margin-left: 66.666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.333333%; + } + .offset-xl-11 { + margin-left: 91.666667%; + } + } \ No newline at end of file diff --git a/src/scss/_select.scss b/src/scss/_select.scss new file mode 100644 index 0000000..cae149a --- /dev/null +++ b/src/scss/_select.scss @@ -0,0 +1,148 @@ +.select-mobileHeader { + display: none; +} +.select-search { + padding: 5px 0; + position: relative; + .material-icons { + display: none; + } + input { + position: relative !important; + padding: 10px; + border: 1px #eee solid !important; + border-radius: 4px !important; + width: 100%; + outline: none; + } +} +.ng-hideHead .ng-dropdown-header { + display: none; +} + +@media screen and (max-width: 768px) { + .select-mobileHeader { + display: flex !important; + background: var(--primary-theme); + color: #fff; + box-shadow: 0px 0.2rem 0.5rem 0 rgb(0 0 0 / 10%); + position: fixed; + top: 0; + width: 100%; + height: 56px; + z-index: 1; + align-items: center; + } + .select-mobileBack { + height: 45px; + width: 46px; + display: flex; + align-items: center; + justify-content: center; + background: var(--primary-theme); + color: #fff; + border: 0; + .material-icons { + color: #fff !important; + margin: 0rem !important; + } + } + .ng-dropdown-panel .ng-dropdown-header { + display: block; + } + .ng-hideHead .ng-dropdown-header { + display: block; + } + .select-search { + padding: 15px; + .material-icons { + display: block; + position: absolute !important; + top: 23px !important; + left: 25px !important; + background: transparent !important; + color: #9e9e9e !important; + margin: 0 !important; + padding: 0 !important; + z-index: 2 !important; + width: 29px !important; + } + input { + padding-left: 45px !important; + } + } + .select-mobileTitle { + font-size: 16px !important; + font-weight: 600; + letter-spacing: 0.2px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + .ng-dropdown-panel { + display: block; + position: fixed !important; + background-color: #fff; + border: 0 !important; + height: 100%; + width: 100% !important; + right: 0 !important; + left: 0 !important; + top: 0 !important; + } + .ng-dropdown-panel .ng-dropdown-header { + padding: 0 !important; + } + .ng-dropdown-panel-items { + max-height: 100% !important; + } + + .ng-dropdown-panel.ng-select-top + .ng-dropdown-panel-items + .ng-option { + padding: 10px 12px; + } +} + .ng-select, + .ng-option { + font-size: 14px !important; +} + .ng-select.ng-select-multiple + .ng-select-container + .ng-value-container + .ng-value + .ng-value-icon.left { + border-left: 1px solid #b8dbff !important; + border-right: none !important; +} + .ng-value { + display: flex; + align-items: center; + flex-direction: row-reverse; + padding-bottom: 3px; +} + .ng-select-focused { + box-shadow: none !important; +} + .ng-select .ng-select-container { + color: var(--text-color); + min-height: 38px !important; +} +.ng-select.ng-select-single .ng-select-container { + min-height: 40px !important; +} + .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder, + .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input { + top: 8px !important; +} + .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder { + padding-bottom: 0; +} + + .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value { + padding-top: 2px; + display: block; +} + .ng-select.ng-select-focused:not(.ng-select-opened)>.ng-select-container{ + box-shadow: none !important; +} diff --git a/src/scss/_sidebar.scss b/src/scss/_sidebar.scss new file mode 100644 index 0000000..a98e4e0 --- /dev/null +++ b/src/scss/_sidebar.scss @@ -0,0 +1,274 @@ +.aside { + background-color: #fff; + height: 100vh; +} +.ng-brand-logo { + cursor: pointer; + display: flex; + justify-content: center; + width: 85%; + h2 { + margin: 0; + color: var(--primary-theme); + } +} +.ng-asidebar-inactive .ng-asideToggle { + position: absolute; + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} +.ng-asidebar-inactive .aside-logo { + opacity: 0; + visibility: hidden; +} +.ng-aside-brand { + min-height: 70px; + display: flex; + align-items: center; + width: 80px; + padding: 10px 15px; + border-bottom: 1px solid #eff0f6; + transition: all 0.6s ease; +} +.ng-brand-logo img { + max-width: 150px; + object-fit: contain; + max-height: 100px; +} +.ng-aside-brand.ng-asidebar-active .ng-asideToggle span svg { + transform: scaleX(1); +} +.ng-aside-brand .ng-asideToggle span svg { + transform: scaleX(-1); +} +.ng-aside-brand { + justify-content: center; +} +.ng-aside-brand.ng-asidebar-active { + justify-content: space-between; + width: 100%; +} +.app-asidebar { + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 98; + background-color: #fff; + transition: all 0.6s ease; +} +@media screen and (max-width: 960px) { + .ng-aside-brand { + position: absolute; + left: 23px; + top: 0; + } + .app-asidebar { + position: absolute; + width: 100%; + } +} +.Overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); +} +//base component +.app-main { + height: 100%; +} +.app-mainContent { + padding: 25px; + background-color: #f2f3f8; +} +.app-mainBody { + height: 100%; + padding-left: 265px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.app-extra-space { + -webkit-box-flex: 1; + -ms-flex: 1 0 auto; + flex: 1 0 auto; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + max-width: 100%; + background-color: #f2f3f8; +} +.app-header { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 999; + transition: all 0.6s ease; +} +.app-asidebar { + position: fixed; + top: 0; + bottom: 0; + z-index: 98; + max-width: 100%; + -webkit-transition: all 0.3s ease; + transition: all 0.6s ease; + width: 80px; +} +.ng-app-main-active .app-asidebar { + width: 280px; +} +.app-header { + left: 80px; +} +.ng-app-main-active .app-header { + left: 280px; +} +.app-mainBody { + padding-left: 80px; +} +.ng-app-main-active .app-mainBody { + padding-left: 280px; +} +@media screen and (max-width: 960px) { + .app-main.ng-app-main-active .app-asidebar { + width: 100%; + } + .app-main .app-asidebar { + width: 0; + } + .app-asidebar { + top: 60px; + } + .ng-app-main-active .app-mainBody { + padding: 0; + } + .app-header { + z-index: 2; + } + .app-mainBody { + padding: 0; + } + .app-header { + left: 0 !important; + } + .ng-app-main-active .app-header { + left: 0 !important; + } + .app-mainContent { + padding: 0; + padding-top: 30px !important; + padding-bottom: 30px !important; + } + .ng-AsideBar.DvSide .menu > li a { + display: none; + } +} + +//end +ul.menu, +.submenu { + list-style-type: none; + padding: 0; + margin: 0; +} +.submenu2 { + padding-left: 27px; +} +.ng-AsideBar .menu .p-panelmenu-panel a { + gap: 10px; + display: flex; + min-height: 46px; + padding: 9px 15px; + align-items: center; + text-decoration: none; + cursor: pointer; +} +.ng-AsideBar .menu > li a .pi-chevron-up, +.ng-AsideBar .menu > li a .pi-chevron-down { + right: 13px; + color: #717b90; + display: block; + font-size: 10px; + position: absolute; + display: flex; + align-items: center; +} +.submenu > li a { + min-height: unset !important; + span { + color: #717b90; + font-size: 15px !important; + font-weight: 400 !important; + padding-right: 20px; + text-transform: capitalize !important; + } +} +.submenu>li { + position: relative; +} +.submenu>li::before { + content: ""; + position: absolute; + top: 16px; + bottom: 0; + left: 9px; + background-color: #717b90; + width: 5px; + z-index: 1; + height: 5px; + border-radius: 50%; +} +.ng-AsideBar .menu:first-child .parent-menu-active a { + color: #fff; + background: var(--primary-theme); +} +.SidebarMenulink::before{ + background-color: var(--primary-theme) !important; +} +.SidebarMenulink a span { + color: var(--primary-theme) !important; +} +.ng-AsideBar .menu:first-child a { + font-size: 15px; + font-weight: 500; + color: #717b90; + text-transform: capitalize !important; +} +.ng-AsideBar .parent-menu-active .submenu li a { + background: transparent !important; + margin-bottom: 0 !important; +} +.ng-AsideBar .menu:first-child .parent-menu-active a .pi-chevron-up { + color: #fff; +} +.ng-AsideBar.DvSide { + .menu > li a { + padding: 12px; + justify-content: center; + span,i { + display: none; + } + } + .submenu { + display: none; + } +} +.ng-AsideBar .parent-menu-active a .asidebarIcons { + filter: invert(1) grayscale(1) brightness(3); +} \ No newline at end of file diff --git a/src/scss/_table.scss b/src/scss/_table.scss new file mode 100644 index 0000000..b9984c3 --- /dev/null +++ b/src/scss/_table.scss @@ -0,0 +1,93 @@ +.tableWrapper { + padding-bottom: 15px; + overflow: auto; + table { + width: 100%; + } + table, + th, + td { + border: 1px solid #e6e6e6; + border-collapse: collapse; + padding: 10px; + text-align: center; + font-size: 14px; + } + th { + font-weight: 500; + } +} + +.actionButtonSticky .p-datatable .p-datatable-thead > tr > th:last-child, +.actionButtonSticky .p-datatable .p-datatable-tbody > tr > td:last-child { + position: sticky; + right: 0; +} +.treeTableUser .p-treetable .p-treetable-tbody>tr, .treeTableUser .p-treetable .p-treetable-thead>tr { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr; +} +.actionButtonSticky .p-datatable .p-datatable-tbody > tr > td:last-child { + background-color: white !important; +} + +.app-tableBtn { + width: 15%; + padding: 20px; + padding-top: 0; +} +@media screen and (max-width: 960px) { + .tableText { + width: 153px !important; + } + .inputWrapper { + width: 200px !important; + } + .tableRadioBtn { + width: 140px !important; + } + .tableDropDown { + width: 140px !important; + } + .tableWrapper { + table{ + min-width: 50pc !important; + } + } +} +@media screen and (max-width: 960px) { + .app-tableBtn .btn-primary { + width: 118px; + } +} +.tableWrapper tr { + white-space: nowrap; +} +.flightTableWrapper { + display: flex; + align-items: center; + overflow: auto; +} +.Bk_Mg-Tbl thead th, +.Bk_Mg-Tbl thead td { + font-size: 14px; + font-weight: 500; + border-bottom-width: 1px; + padding: 10px; + text-align: center; + vertical-align: middle; +} +.Bk_Mg-Tbl tbody td { + padding: 10px; + color: #212529; + font-size: 14px; + text-align: center; + border-collapse: collapse; +} +.Bk_Mg-Tbl .thead-light th, +.Notes_Table .p-datatable .p-datatable-thead>tr>th { + color: #595d6e !important; + background-color: #ecedf2 !important; + border-color: #d3d3d3 !important; + white-space: nowrap !important; +} \ No newline at end of file diff --git a/src/scss/_tabs.scss b/src/scss/_tabs.scss new file mode 100644 index 0000000..ce51089 --- /dev/null +++ b/src/scss/_tabs.scss @@ -0,0 +1,438 @@ +.p-tabview .p-tabview-nav { + display: grid !important; + grid-template-columns: repeat(7, 1fr); + grid-gap: 10px; +} + +.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link { + background: var(--primary-theme); + border-color: var(--primary-theme); + color: #ffffff; + padding: 10px; + justify-content: center; +} + +.p-tabview .p-tabview-nav li .p-tabview-nav-link { + border: none; + border: 1px solid var(--primary-theme); + border-radius: 5px; + padding: 10px; + justify-content: center; +} + +.p-tabview-nav { + padding: 20px !important; + border-radius: 5px; +} + +.p-tabview .p-tabview-nav li .p-tabview-nav-link:not(.p-disabled):focus { + box-shadow: none; +} + +.p-tabview-panels { + padding: 0 !important; + border-radius: 4px; +} + +.ng-tab .p-tabview .p-tabview-panels { + padding: 20px !important; +} + +.app-SubSedTabs { + .p-tabview-nav { + padding: 0 !important; + padding-bottom: 20px !important; + border-radius: 0; + border-bottom: 0 !important; + } + + .p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link { + border-radius: 5px 5px 0px 0px; + padding: 15px; + } + + .p-tabview .p-tabview-nav li.p-highlight { + position: relative; + } + + .p-tabview .p-tabview-nav { + grid-gap: 0 !important; + } + + .p-tabview .p-tabview-nav li.p-highlight::after { + content: ""; + position: absolute; + bottom: unset; + left: 45%; + width: 0; + height: 0; + border-left: 15px solid transparent; + border-right: 15px solid transparent; + border-top: 15px solid var(--primary-theme); + } + + .p-tabview .p-tabview-nav li .p-tabview-nav-link { + border: none !important; + padding: 15px; + } +} + +@media screen and (max-width: 768px) { + :host { + .p-tabview-nav-content { + margin: 0px; + margin-top: 10px; + height: 62px; + } + + .p-tabview-nav { + padding: 10px !important; + padding-bottom: 15px !important; + border-radius: 0 !important; + } + + .mat-tab-label { + width: 100%; + } + + .mat-tab-label-container { + overflow: auto; + } + + .mat-tab-header-pagination-controls-enabled .mat-tab-header-pagination { + display: none; + } + + .mat-tab-label { + opacity: 2 !important; + width: 100%; + } + + ::-webkit-scrollbar { + width: 0px; + background: transparent; + } + } + + .p-tabview .p-tabview-nav { + overflow: auto; + padding: 0 !important; + padding-bottom: 5px !important; + } + + .p-tabview-nav-content { + padding: 20px; + background-color: #fff; + } + + .app-SubSedTabs { + .p-tabview-nav { + padding: 0 !important; + padding-bottom: 30px !important; + border-bottom: 1px solid #dcdada !important; + border-radius: 0; + } + + .p-tabview .p-tabview-nav { + display: grid !important; + grid-template-columns: 1fr 1fr !important; + grid-gap: 0 !important; + } + } +} + +.app-SubTabs ::ng-deep .p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link, +.app-SubTabs ::ng-deep .p-tabview-nav { + border-radius: 0; +} + +.app-SubTabs ::ng-deep.p-tabview-nav::-webkit-scrollbar { + display: none; +} + +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav li .p-tabview-nav-link { + border-radius: 0.5rem !important; +} + +.app-SubTabs .p-tabview .p-tabview-nav { + border-radius: 0; +} + +.infoSeason { + position: relative; +} + +.infoSeason .material-icons { + top: 25px; + right: -55px; + font-size: 30px; + position: absolute; + cursor: pointer; +} + +.rangeDate { + margin-bottom: 10px; + + p { + margin: 10px 0; + font-size: 14px; + margin-bottom: 3px; + } +} + +.grid-column-end { + grid-column-end: 6; +} + +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link, +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav li .p-tabview-nav-link { + padding: 0 !important; + height: auto; +} + +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav .p-tabview-nav-link .error-tab.ErrorWrapper { + border: 1px solid red; +} + +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link .error-tab.ErrorWrapper { + border: 0 !important; +} + +.error-tab { + text-align: center; + border: 1px solid var(--primary-theme); + border-radius: 0.4rem; + padding: 15px !important; + text-align: center; + width: 300px; +} + +.app-SubTabs .p-tabview .p-tabview-nav li .p-tabview-nav-link { + padding: 0 !important; + border: unset !important; + height: unset; +} + +.app-SubTabs ::ng-deep .p-tabview .p-tabview-nav { + grid-gap: 0.7rem !important; + padding-left: 0.7rem !important; + overflow: auto; +} + +.app-SubTabs ::ng-deep.p-tabview .p-tabview-nav li.p-highlight::after { + bottom: unset; + left: 45%; +} + +.can_policyIcon { + display: flex; + align-items: center; +} + +.cancel_policy ::ng-deep .formLabel { + display: flex !important; + align-items: center; +} + +.cancel_policy .material-icons { + font-size: 20px; + position: absolute; +} + +@media screen and (max-width: 768px) { + .app-SubTabs ::ng-deep.p-tabview-nav-content { + height: auto; + margin-top: 0; + } +} + +.app-Grid3-5 { + grid-column-end: 5; + grid-column-start: 3; +} + +.subHeading { + font-size: 16px; + font-weight: 500; + margin-bottom: 10px; +} + +.tableMainWrap { + padding-bottom: 15px; + overflow: auto; +} + +.tableMainWrap th { + font-weight: 500; +} + +.tableMainWrap table, +.tableMainWrap th, +.tableMainWrap td { + border: 1px solid #e6e6e6; + border-collapse: collapse; + padding: 10px; + text-align: center; + font-size: 14px; +} +.w-100{ + width: 100%; +} +.text-left{ + text-align: left; +} +.border-0 { + border: 0 !important; +} +.border-top-0 { + border-top: 0 !important; +} +.border-left-0 { + border-left: 0 !important; +} +.border-right-0 { + border-right: 0 !important; +} +.border-bottom-0 { + border-bottom: 0 !important; +} +.border-bottom{ + border-bottom: 1px solid #e6e6e6; +} +.noBorderLastChild th:last-child, .noBorderLastChild td:last-child{ + border-right: 0 !important; +} +.border-right-2 { + border-right: 2px solid #e6e6e6 !important; +} +.customSticky .sticky { + position: sticky; + left: 0px; + background: white; + font-weight: 500; +} + +// .formInputBorder .formInput { +// border: 0; +// height: unset; +// padding: 0; +// } + +.formInputBorder .formInput:hover { + box-shadow: unset; +} + +.readonlyInput { + background-color: transparent !important; +} + +.sectionCpyOnUI { + display: flex; + justify-content: flex-start; + align-items: start; +} + +.flightTableWrapper { + display: flex; + align-items: center; +} + +.commonSection { + overflow: auto; + border: 0; +} + +.no-data-found { + margin: 0 20px 20px; + padding: 20px; + text-align: center; + background-color: var(--secondary-light); + border-radius: 8px; + font-size: 16px; + font-weight: 500; +} + +@media screen and (max-width: 960px) { + .sectionCpyOnUI { + flex-direction: column; + gap: 10px; + overflow: auto; + + .back-to-top-btn { + margin-left: 0 !important; + } + } + + .sectionCpyOnUI .commonSection { + width: 100%; + } +} + +.hotel-tab .p-tabview-nav { + list-style: none; + margin: 0; + padding: 0; +} + +.hotel-tab .p-tabview .p-tabview-nav li .p-tabview-nav-link { + justify-content: center; + width: 100%; + display: flex !important; + padding: 10px !important; + +} + +.hotel-tab .p-tabview .p-tabview-nav li .p-tabview-nav-link.active { + background-color: var(--primary-theme) !important; + color: #ffffff !important; +} + +.hotel-tab .p-tabview-nav li { + cursor: pointer; +} + +.hotel-tab .menubtn { + border: 1px solid var(--primary-theme); + border-radius: 5px; + padding: 10px; + justify-content: center; + width: 100%; + display: flex; + background: #ffffff; + color: #6c757d; + font-weight: 600; +} + +.hotel-tab .tab { + display: none; +} + +.hotel-tab .tab.active { + display: block; +} + +.hotel-tab ::ng-deep .mat-menu-panel { + min-width: 185px !important; +} + +button.mat-menu-item.active { + background-color: var(--primary-theme) !important; + color: #ffffff; +} + +.hotel-tab ::ng-deep .p-tabview-nav-content .p-tabview-nav li a span { + white-space: nowrap; +} + +.hotel-tab ::-webkit-scrollbar-thumb { + display: none; +} + +.mat-mdc-menu-item:not([disabled]).active { + background-color: var(--primary-theme) !important; + color: #ffffff; +} + +.hotel-tab .mat-mdc-menu-item { + padding: 0 1.8rem; +} \ No newline at end of file diff --git a/src/scss/default.scss b/src/scss/default.scss new file mode 100644 index 0000000..c56000b --- /dev/null +++ b/src/scss/default.scss @@ -0,0 +1,162 @@ +@import "./badge"; +@import "./calendar"; +@import "./checkBox"; +@import "./comCalender"; +@import "./common"; +@import "./dataTable"; +@import "./dropzone"; +@import "./input"; +@import "./login"; +@import "./select"; +@import "./buttons"; +@import "./table"; +@import "./rowCol"; +@import "./tabs"; +@import "./rowCol"; +@import "./sidebar"; + +.mdc-checkbox .mdc-checkbox__native-control{ + display: none !important; + } + .treeSubCheckbox { + display: flex; + align-items: end; + line-height: 1; + gap: 13px; + } + ::ng-deep .p-checkbox .p-checkbox-box{ + border: 1px solid #ced4da !important; + } + .searchInput { + ::ng-deep .ng-dropdown-header { + padding: 0 !important; + } +} + +::ng-deep .p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box.p-highlight:hover { + border-color: var(--primary-theme) !important; + background: var(--primary-theme) !important; + color: #ffffff !important; +} + +::ng-deep .p-checkbox .p-checkbox-box.p-highlight { + border-color: var(--primary-theme) !important; + background: var(--primary-theme) !important; +} +.eyeICon { + top: 0; + right: 0; + bottom: 0; + margin: 10px; + position: absolute; + color: #6c757d; + cursor: pointer; + display: flex; + align-items: center; +} +.passSuggest { + display: grid; + grid-template-columns: 1fr 1fr; + white-space: nowrap; + margin: 0; + padding-left: 15px; + margin-bottom: 15px; +} +.borderBottom { + border-bottom: 0 !important; + padding-bottom: 0 !important; +} +.showSelected { + display: flex; + align-items: center; + gap: 10px; + justify-content: flex-end; +} +.selectedShow { + display: flex; + align-items: center; + gap: 5px; +} +.hotelSelectionTable .p-dialog-mask { + background-color: rgba(0, 0, 0, 0.4) !important; +} +.hotelSelectionTable .tableWrapper { + padding-bottom: 0 !important; +} +.hotelSelectionTable .p-dialog .p-dialog-content { + padding: 2rem; + min-width: 800px; +} +.hotelSelectionT .p-toolbar-group-right { + display: flex; + align-items: center; + gap: 10px; +} +.generalSetting_Card { + border: 1px solid #dee2e6 !important; + padding: 20px; +} +.passSuggestDescription li, +.passSuggest li { + font-size: 11px; +} +.passSuggest .PswdSuccess:before { + background-color: #3ed23e !important; +} +.PswdSuccess::before { + background-color: #3ed23e !important; +} +.PswdFail::before { + background: #ccc !important; +} +.PswdSuccess::marker { + color: #3ed23e !important; +} +.infoSeason { + position: relative; +} +.infoSeason .material-icons.infoIcon { + top: 25px; + right: -55px; + font-size: 30px; + position: absolute; + cursor: pointer; +} +.date_rangeBtn{ + margin-top: 22px; +} +.phoneCodeWrapper { + display: grid; + grid-template-columns: 32% 68%; + position: relative; +} +.phoneCodeWrapper .ng-select.ng-select-single .ng-select-container { + border-radius: 4px 0 0 4px !important; + border-right: 0 !important; +} +.phoneCodeWrapper .MobileInputTxt { + border-radius: 0 4px 4px 0 !important; +} +.phoneCodeWrapper .MbTxt_radius { + border-radius: 4px 0 0 4px !important; + border-right: 0; +} +a { + color: var(--primary-theme); +} +.rate-tabs .p-tabview .p-tabview-nav { + overflow: auto; + } + .selectWrapper{ + position: absolute; + right: 0; + a{ + color: var(--primary-theme); + } + } +@media screen and (max-width: 960px) { + .infoSeason .material-icons.infoIcon{ + top: 65px; + right: unset; + } +} \ No newline at end of file diff --git a/src/styles.scss b/src/styles.scss new file mode 100644 index 0000000..186ceed --- /dev/null +++ b/src/styles.scss @@ -0,0 +1,231 @@ +@import "~@ng-select/ng-select/themes/default.theme.css"; +html, +body { + margin: 0; + padding: 0; + height: 100%; + box-sizing: border-box; + background-color: #f2f3f8; + color: var(--text-color); +} + +body { + font-family: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, + "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} +:root { + --primary-theme: #003143; + --secondary-light: #dbebfb; + --text-color: #48465b; + --error-border: #fa0808; + --error-color: #fa0808; + --error-backgound: #fa0808; +} +.asidebarIcons { + height: 25px !important; + width: 25px !important; +} + +.Services { + background-image: url("https://aosedge.b-cdn.net/assets/ExAsideIcons/services.svg") !important; +} + +.UserConfig { + background-image: url("https://aosedge.b-cdn.net/assets/ExAsideIcons/organization.svg") !important; +} + +.BookingManagement { + background-image: url("https://aosedge.b-cdn.net/assets/ExAsideIcons/crm.svg") !important; +} + +.disabled { + pointer-events: none; + cursor: default; +} + +.errorspan { + color: var(--error-color); + font-size: 14px; +} + + +.readonlyInput { + font-size: 14px !important; + background: #f2f3f8 !important; +} + +.booking-history-status-fail { + background: #fce7e9; + color: #e24c4b !important; + border-radius: 4px; + font-weight: 600; + font-size: 12px; + padding: 4px 8px !important; +} + +.booking-history-status-success { + background: #e8fff3 !important; + color: #50cd89 !important; + border-radius: 4px; + font-weight: 600; + font-size: 12px; + padding: 4px 8px !important; +} + +.booking-history-status { + color: black; + padding: 4px 12px; + border-radius: 20px; +} +.btn { + min-width: 64px; + padding: 0 16px; + text-align: center; + min-height: 40px; + font-size: 16px; + border-radius: var(--border-radius); +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +input[type="number"] { + -moz-appearance: textfield; +} + +::ng-deep .ng-dropdown-header { + display: none !important; +} +::ng-deep .p-fileupload .p-fileupload-buttonbar .p-fileupload-choose{ + background-color: var(--primary-theme) !important; +} +.treeTableUser .p-datatable-wrapper .p-datatable-thead tr { + display: grid; + grid-template-columns: 1.3fr 1fr 1fr 1fr 1fr 1fr; + padding: 0 5px; +} +.treeTableUser .p-treetable .p-treetable-thead > tr > th { + text-align: left; + padding: 1rem; + font-size: 14px; + font-weight: 600; + color: #495057; + background: #f8f9fa; + transition: box-shadow .2s; +} +.px-0 { + padding-left: 0; + padding-right: 0; +} +.formInput[readonly] { + background-color: #e9ecef; + opacity: 1; +} +.phoneCodeWrapper { + display: grid; + grid-template-columns: 30% 70%; +} +.text-nowrap { + white-space: nowrap; +} +.resultNotFound { + height: 42px; +} +.resultNotFound td { + position: absolute !important; + width: 100% !important; + text-align: center !important; +} +.passwordCriteria { + display: grid; + grid-template-columns: 1fr 1fr; + padding-left: 17px; +} +.passwordCriteria li { + font-size: 12px; +} +.status { + border-radius: 4px; + padding: 2px 8px; + font-weight: 500; + font-size: 12px; + text-align: center; +} +.status-success { + background: #e8f6e6; + color: #62bc55; +} +.status-failed { + background: #fce7e9; + color: #e24c4b; +} +.ng-asideToggle { + cursor: pointer; +} +.mat-mdc-menu-item-text { + font-size: 14px !important; +} +.app-SubTabs.rate-tabs .p-tabview .p-tabview-panels { + background: transparent; +} +.formControlWrapper { + position: relative; + margin-bottom: 20px; +} +.p-toast-message-error .p-toast-message-icon .p-icon-wrapper { + width: 25px; + height: 25px; + color: #73000c; + margin-top: 6px; +} +.p-toast-message-success .p-toast-message-icon .p-icon-wrapper { + width: 23px; + height: 23px; + color: #224a23; + margin-top: 4px; +} +.p-toast-message-error .p-toast .p-toast-message .p-toast-message-content .p-toast-message-text { + margin: 0 0 0 0.8rem !important; +} +.p-toast-message-success.p-toast .p-toast-message .p-toast-message-content .p-toast-message-text { + margin: 0 0 0 0.8rem !important; +} +.p-toast-message-error .p-toast-icon-close .p-icon-wrapper { + color: #73000c; + margin-top: 10px; +} +.p-toast-message-success .p-toast-icon-close .p-icon-wrapper { + color: #224a23; + margin-top: 10px; +} +.p-toast .p-toast-message .p-toast-icon-close:hover { + background: transparent !important; +} + +@media screen and (max-width: 960px) { + ::ng-deep .ng-dropdown-header { + display: block !important; + } + + ::ng-deep .ng-dropdown-panel.ng-select-top { + width: 100% !important; + } +} +@media screen and (min-width: 1301px) { + .app-loginBody { + max-width: 75%; + min-height: 100vh; + } +} +.ErrorWrapper .formInput, .ErrorWrapper .ng-select-container, .error-tab.ErrorWrapper{ + border: 1px solid var(--error-border) !important; + border-radius: 4px !important; +} + +::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input{ + font-size: 14px !important; +} \ No newline at end of file diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..598d11e --- /dev/null +++ b/src/test.ts @@ -0,0 +1,26 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context(path: string, deep?: boolean, filter?: RegExp): { + keys(): string[]; + (id: string): T; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); + +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..82d91dc --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..93bc333 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,35 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": false, + "noImplicitOverride": false, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "skipLibCheck": true, + "target": "ES2022", + "module": "ES2022", + "lib": [ + "ES2022", + "Es2022.String", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + "strictNullChecks": false, + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000..092345b --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,18 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/uat.Dockerfile b/uat.Dockerfile new file mode 100644 index 0000000..26ba8dd --- /dev/null +++ b/uat.Dockerfile @@ -0,0 +1,16 @@ +FROM node:20.11.1 as builder + +WORKDIR /usr/src/app +COPY . /usr/src/app + +RUN npm install && npm run build-uat + +FROM nginx:1.14.2-alpine + +COPY nginx.conf /etc/nginx/nginx.conf +COPY --from=builder /usr/src/app/dist/ExtraNet /usr/share/nginx/html + +EXPOSE 80 +EXPOSE 443 + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file