From dcb2d98503caefc5d06dec8c79150cf032828a87 Mon Sep 17 00:00:00 2001 From: yaschalew Date: Fri, 10 Jul 2026 10:37:01 +0300 Subject: [PATCH 1/9] fix --- .../css/ethiopian-date-picker-overrides.css | 279 ++ .../common/css/flora.calendars.picker.css | 208 ++ .../common/css/humanity.calendars.picker.css | 197 ++ .../common/css/jquery.calendars.picker.css | 215 ++ .../common/css/redmond.calendars.picker.css | 199 ++ .../css/smoothness.calendars.picker.css | 200 ++ .../css/ui-black-tie.calendars.picker.css | 18 + .../css/ui-blitzer.calendars.picker.css | 18 + .../css/ui-cupertino.calendars.picker.css | 18 + .../css/ui-dark-hive.calendars.picker.css | 18 + .../css/ui-dot-luv.calendars.picker.css | 18 + .../css/ui-eggplant.calendars.picker.css | 18 + .../css/ui-excite-bike.calendars.picker.css | 18 + .../common/css/ui-flick.calendars.picker.css | 18 + .../css/ui-hot-sneaks.calendars.picker.css | 18 + .../shared/common/css/ui.calendars.picker.css | 107 + .../common/form/fields/AmharicDatePicker.tsx | 457 ++++ .../shared/common/form/fields/DateField.tsx | 233 ++ .../common/form/fields/DateTimeField.tsx | 242 ++ .../form/fields/EthiopianDatePicker.tsx | 0 .../shared/common/form/fields/FormFields.tsx | 806 ++++++ .../shared/common/img/calendar-blue.gif | Bin 0 -> 969 bytes .../shared/common/img/calendar-green.gif | Bin 0 -> 934 bytes .../shared/common/img/calendar.gif | Bin 0 -> 269 bytes .../shared/common/img/view.png | Bin 0 -> 10259 bytes .../shared/common/img/view2.png | Bin 0 -> 25362 bytes .../shared/common/img/view3.png | Bin 0 -> 14991 bytes .../shared/common/img/view4.png | Bin 0 -> 14043 bytes .../shared/common/jquery-global.ts | 7 + .../js/jquery.calendars.ethiopian-am.ts | 46 + .../common/js/jquery.calendars.ethiopian.js | 171 ++ .../js/jquery.calendars.ethiopian.min.js | 2 + .../js/jquery.calendars.ethiopian.min.map | 1 + .../shared/common/js/jquery.calendars.js | 982 ++++++++ .../common/js/jquery.calendars.picker.js | 1946 ++++++++++++++ .../shared/common/js/jquery.calendars.plus.js | 463 ++++ .../shared/common/js/jquery.plugin.js | 389 +++ .../shared/common/localizedName.ts | 21 + .../shared/common/ui/FayidaInput.tsx | 29 + .../shared/common/ui/LoadingOverlay.tsx | 20 + .../shared/common/ui/SliderUI.tsx | 53 + .../shared/common/ui/Text.tsx | 25 + .../shared/common/ui/accordion.tsx | 64 + .../shared/common/ui/alert-dialog.tsx | 155 ++ .../shared/common/ui/alert.tsx | 58 + .../shared/common/ui/avatar.tsx | 53 + .../shared/common/ui/badge.tsx | 62 + .../shared/common/ui/breadcrumb.tsx | 109 + .../shared/common/ui/button.tsx | 161 ++ .../shared/common/ui/calendar.tsx | 74 + .../shared/common/ui/card.tsx | 75 + .../shared/common/ui/chart.tsx | 355 +++ .../shared/common/ui/checkbox.tsx | 60 + .../shared/common/ui/collapsible.tsx | 31 + .../shared/common/ui/command.tsx | 206 ++ .../shared/common/ui/context-menu.tsx | 250 ++ .../common/ui/dataTableColumnHeader.tsx | 66 + .../shared/common/ui/dataTablePagination.tsx | 108 + .../shared/common/ui/dataTablePagination2.tsx | 133 + .../shared/common/ui/dialog.tsx | 134 + .../shared/common/ui/drawer.tsx | 48 + .../shared/common/ui/dropdown-menu.tsx | 255 ++ .../common/ui/fileUploader/empty-card.tsx | 39 + .../common/ui/fileUploader/fileUpload.tsx | 430 ++++ .../ui/fileUploader/hooks/use-callback-ref.ts | 22 + .../hooks/use-controllable-state.ts | 66 + .../ui/fileUploader/hooks/use-file-upload.ts | 77 + .../ui/fileUploader/reusableFileUploader.tsx | 75 + .../common/ui/fileUploader/types/index.ts | 0 .../ui/fileUploader/upload-files-card.tsx | 58 + .../shared/common/ui/fileUploader/utils.ts | 45 + .../shared/common/ui/form.tsx | 166 ++ .../shared/common/ui/habesha-date-picker.tsx | 239 ++ .../shared/common/ui/hover-card.tsx | 40 + .../shared/common/ui/input.tsx | 25 + .../shared/common/ui/label.tsx | 24 + .../shared/common/ui/multi-select.tsx | 427 ++++ .../shared/common/ui/navigation-menu.tsx | 168 ++ .../shared/common/ui/pagination.tsx | 127 + .../shared/common/ui/popover.tsx | 46 + .../shared/common/ui/progress.tsx | 29 + .../shared/common/ui/radio-group.tsx | 43 + .../shared/common/ui/resizable.tsx | 54 + .../shared/common/ui/scroll-area.tsx | 56 + .../shared/common/ui/select.tsx | 183 ++ .../shared/common/ui/separator.tsx | 28 + .../shared/common/ui/sheet.tsx | 137 + .../shared/common/ui/sidebar.tsx | 727 ++++++ .../shared/common/ui/single-select.tsx | 154 ++ .../shared/common/ui/skeleton.tsx | 13 + .../shared/common/ui/sonner.tsx | 27 + .../shared/common/ui/sppiner.tsx | 49 + .../shared/common/ui/star-rating.tsx | 152 ++ .../shared/common/ui/switch.tsx | 28 + .../shared/common/ui/table.tsx | 114 + .../shared/common/ui/table/AdvancedTable.tsx | 232 ++ .../ui/table/DataTableFacetedFilter.tsx | 149 ++ .../common/ui/table/DataTablePagination.tsx | 178 ++ .../ui/table/DataTablePaginationFinal.tsx | 260 ++ .../common/ui/table/DataTableToolbar.tsx | 109 + .../common/ui/table/DataTableViewOptions.tsx | 86 + .../common/ui/table/getColumnToggleLabel.ts | 26 + .../shared/common/ui/tabs.tsx | 64 + .../shared/common/ui/textarea.tsx | 19 + .../shared/common/ui/toast.tsx | 127 + .../shared/common/ui/toaster.tsx | 33 + .../shared/common/ui/toggle-group.tsx | 37 + .../shared/common/ui/tooltip.tsx | 61 + .../shared/common/ui/treeSelect.tsx | 1093 ++++++++ .../shared/common/ui/use-toast.ts | 189 ++ .../shared/common/ui/year-picker.tsx | 198 ++ .../shared/common/utils/ethiopianTimeZone.ts | 164 ++ .../components/FaydaCallbackDispatcher.tsx | 20 + .../shared/components/SetPassword.tsx | 344 +++ .../shared/components/SmartOfficeLoader.tsx | 37 + .../shared/components/User/ChangePassword.tsx | 9 + .../shared/components/User/Profile.tsx | 9 + .../components/activity-log/activity-card.tsx | 282 +++ .../activity-log/activity-filters.tsx | 260 ++ .../activity-log/activity-stats.tsx | 125 + .../components/activity-log/export-modal.tsx | 219 ++ .../audit-log/AuditLogDetailPanel.tsx | 177 ++ .../components/audit-log/AuditLogDisplay.tsx | 224 ++ .../components/etrade/EtradeLicensePicker.tsx | 72 + .../components/filters/CombinedFilterBar.tsx | 369 +++ .../components/login/ChangePassword.tsx | 240 ++ .../components/login/ForgotPassword.tsx | 174 ++ .../shared/components/login/Login.tsx | 349 +++ .../shared/components/login/OTPModal.tsx | 286 +++ .../shared/components/login/ResetPassword.tsx | 250 ++ .../components/ui/DashboardDropdown.tsx | 58 + .../components/ui/DynamicBreadcrumb.tsx | 163 ++ .../shared/config/app.config.ts | 13 + .../shared/config/env.ts | 124 + .../shared/context/AuthContext.tsx | 118 + .../shared/context/BreadcrumbContext.tsx | 91 + .../shared/context/PermissionContext.tsx | 34 + .../shared/context/UnitContext.tsx | 28 + .../shared/context/UserContext.tsx | 15 + .../dto/External-Portal/External-PortalDto.ts | 149 ++ .../shared/dto/organization/orgAdminsDto.ts | 41 + .../dto/organization/organizationDto.ts | 48 + .../shared/dto/user/meDto.ts | 211 ++ .../shared/dto/user/usersDto.ts | 56 + .../shared/hooks/useAdvancedDashboardHook.ts | 41 + .../shared/hooks/useAlertSetup.ts | 14 + .../shared/hooks/useAuditLogs.ts | 82 + .../shared/hooks/useAuthUser.ts | 548 ++++ .../shared/hooks/useCombinedFilters.ts | 63 + .../shared/hooks/useDarkMode.ts | 29 + .../shared/hooks/useDelegationMonitor.ts | 133 + .../shared/hooks/useErrorHandler.ts | 252 ++ .../shared/hooks/useExportUserData.ts | 85 + .../shared/hooks/useExternalPortalSession.ts | 31 + .../shared/hooks/useHas.ts | 22 + .../shared/hooks/useNotification.ts | 218 ++ .../shared/hooks/useOrganizationReport.ts | 229 ++ .../hooks/usePersistedColumnVisibility.ts | 27 + .../shared/hooks/usePositionConfigurations.ts | 107 + .../shared/hooks/usePrefixSuffix.ts | 308 +++ .../hooks/useReferenceNumberPrefixes.ts | 121 + .../shared/hooks/useReminder.ts | 200 ++ .../shared/hooks/useSession.ts | 77 + .../shared/hooks/useUnitConfiguration.ts | 13 + .../shared/hooks/useUnitReport.ts | 21 + .../shared/hooks/withRoles.tsx | 43 + .../shared/i18n/uiLanguages.ts | 42 + .../new-user-management-ui/shared/lib/api.ts | 23 + .../shared/lib/sanitize.ts | 15 + .../shared/lib/tinyMceConfig.ts | 7 + .../shared/lib/utils.ts | 57 + .../shared/navigation/footerItems.ts | 48 + .../shared/navigation/navigationItems.ts | 121 + .../shared/navigation/navigationtabs.tsx | 262 ++ .../shared/navigation/sidebarToggle.tsx | 29 + .../shared/pages/audit-log/audit-log-page.tsx | 994 ++++++++ .../shared/pages/audit-log/audit-log.types.ts | 53 + .../shared/pages/audit-log/audit-log.utils.ts | 331 +++ .../shared/routes/routeConfig.ts | 23 + .../shared/routes/useActiveModule.ts | 12 + .../shared/services/Recordservice.ts | 0 .../shared/services/audit/audit.api.ts | 107 + .../shared/services/audit/audit.http.ts | 33 + .../shared/services/authService.ts | 346 +++ .../shared/services/axiosInstance.ts | 108 + .../shared/services/chronicleInstance.ts | 110 + .../shared/services/complaintService.ts | 44 + .../shared/services/exportService.ts | 245 ++ .../shared/services/fileService.ts | 190 ++ .../services/http/http-client-factory.ts | 101 + .../shared/services/notificationService.ts | 38 + .../shared/services/objectiveInstance.ts | 114 + .../services/organizationConfigService.ts | 160 ++ .../shared/services/organizationsService.ts | 210 ++ .../shared/services/performanceInstance.ts | 101 + .../services/positionConfigurationService.ts | 209 ++ .../shared/services/presignedAxios.ts | 16 + .../shared/services/recordAxiosInstance.ts | 108 + .../shared/services/sessionExpiry.ts | 50 + .../shared/services/unifiedUploadService.ts | 167 ++ .../services/unitConfigurationService.ts | 215 ++ .../validation/BufferContentValidator.ts | 260 ++ .../validation/ClientSideValidator.ts | 270 ++ .../validation/EmbeddedContentValidator.ts | 288 +++ .../validation/FileUploadValidator.ts | 287 +++ .../services/validation/MagicByteDetector.ts | 153 ++ .../shared/services/validation/README.md | 114 + .../validation/SVGContentValidator.ts | 152 ++ .../services/validation/SecurityLogger.ts | 165 ++ .../services/validation/XSSUploadValidator.ts | 149 ++ .../__tests__/BufferContentValidator.test.ts | 178 ++ .../__tests__/ClientSideValidator.test.ts | 183 ++ .../__tests__/FileUploadValidator.test.ts | 249 ++ .../__tests__/SecurityLogger.test.ts | 185 ++ .../services/validation/errorMessages.ts | 107 + .../shared/services/validation/index.ts | 39 + .../shared/services/validation/types.ts | 129 + .../services/validation/uploadContexts.ts | 272 ++ .../shared/utils/authPersistence.ts | 49 + .../shared/utils/chartExportUtils.ts | 172 ++ .../shared/utils/columnVisibilityStorage.ts | 32 + .../shared/utils/faydaAuthSession.ts | 148 ++ .../shared/utils/faydaOidc.ts | 125 + .../shared/utils/filterParams.ts | 11 + .../utils/get-final-allowed-file-types.ts | 86 + .../shared/utils/habeshaCalendar.ts | 263 ++ .../shared/utils/max-file-size.ts | 4 + .../shared/utils/permissionHelper.ts | 15 + .../shared/utils/refreshTokenHandler.ts | 7 + .../super-admin/app/store.ts | 11 + .../super-admin/assets/react.svg | 1 + .../dashboard/components/ActivityTimeline.tsx | 44 + .../dashboard/components/HeaderBar.tsx | 15 + .../dashboard/components/OrgTable.tsx | 72 + .../dashboard/components/StatCard.tsx | 53 + .../components/dashboard/dashboardSlice.ts | 26 + .../dashboard/services/useDashboardStats.ts | 34 + .../dashboard/types/dashboardStatsDto.ts | 10 + .../externalUsers/ExternalUsersColumnDefn.tsx | 129 + .../externalUsers/PendingExternalUsers.tsx | 142 ++ .../externalUsers/ResponseActions.tsx | 137 + .../externalUsers/UpdateProfile.tsx | 332 +++ .../externalUsers/UserStatusToggleConfirm.tsx | 124 + .../externalUsers/ViewDocuments.tsx | 378 +++ .../organizationAdmins/AssignAdminDialog.tsx | 481 ++++ .../AssignOrgAdminDialog.tsx | 277 ++ .../OrganizationAdminList.tsx | 243 ++ .../organizationAdmins/OrganizationAdmins.tsx | 134 + .../OrganizationAdminsActions.tsx | 80 + .../OrganizationAdminsColumnDefn.tsx | 77 + .../organizationAdmins/RemoveAdminConfirm.tsx | 59 + .../organizationAdmins/StatusCell.tsx | 50 + .../organizations/AdminRegistrationForm.tsx | 272 ++ .../organizations/DeleteOrganizationPopup.tsx | 62 + .../organizations/EditOrganizationForm.tsx | 53 + .../ManageOrganizationDrawer.tsx | 597 +++++ .../organizations/NewOrganizationForm.tsx | 29 + .../organizations/OrganizationDetail.tsx | 153 ++ .../organizations/Organizations.tsx | 263 ++ .../organizations/OrganizationsActions.tsx | 169 ++ .../organizations/OrganizationsColumnDefn.tsx | 122 + .../organizations/VisibilityCell.tsx | 126 + ...rganizationActivateOrDeactivationPopup.tsx | 69 + .../organizations/common/OrganizationForm.tsx | 324 +++ .../settings/PasswordSettingsForm.tsx | 441 ++++ .../components/sites/SiteFormModal.tsx | 213 ++ .../components/sites/SiteViewModal.tsx | 104 + .../components/sites/SitesColumnDefn.tsx | 143 ++ .../components/sites/SitesPage.tsx | 363 +++ .../templates/components/TemplateCard.tsx | 151 ++ .../templates/components/TemplateEditor.tsx | 132 + .../templates/components/TemplateForm.tsx | 195 ++ .../templates/components/TemplateTable.tsx | 402 +++ .../templates/components/templates.tsx | 23 + .../templates/service/useTemplate.ts | 105 + .../components/templates/template.tsx | 17 + .../templates/types/templateTypes.ts | 12 + .../super-admin/dto/ExternalUsersDto.ts | 37 + .../super-admin/dto/SitesDto.ts | 33 + .../super-admin/dto/SuperAdminDto.ts | 51 + .../super-admin/hooks/use-mobile.ts | 19 + .../super-admin/hooks/useArchivedUsers.ts | 15 + .../super-admin/hooks/useConfig.ts | 167 ++ .../super-admin/hooks/useDashboardData.ts | 194 ++ .../super-admin/hooks/useDepartments.ts | 253 ++ .../super-admin/hooks/useEmployees.ts | 341 +++ .../super-admin/hooks/useExternalUsers.ts | 106 + .../super-admin/hooks/useMigratedData.ts | 14 + .../hooks/useOrganizationAdmins.ts | 186 ++ .../super-admin/hooks/useOrganizationTypes.ts | 83 + .../super-admin/hooks/useOrganizations.ts | 251 ++ .../super-admin/hooks/usePasswordSettings.ts | 68 + .../super-admin/hooks/usePositions.ts | 284 +++ .../super-admin/hooks/useRemark.ts | 19 + .../super-admin/hooks/useSites.ts | 185 ++ .../super-admin/hooks/useUnitInformation.ts | 23 + .../super-admin/hooks/useUnits.ts | 230 ++ .../super-admin/hooks/useUserRoles.ts | 121 + .../super-admin/hooks/useUsers.ts | 25 + .../super-admin/lib/dateFormatter.ts | 5 + .../super-admin/lib/utils.ts | 28 + .../super-admin/services/api/dashboardApi.ts | 90 + .../services/api/delegationTemplate.ts | 68 + .../services/api/organizationAdminService.ts | 112 + .../services/api/organizationTypesService.ts | 30 + .../services/api/passwordSettingsService.ts | 72 + .../super-admin/services/api/sitesService.ts | 69 + .../services/api/userRoleService.ts | 103 + .../super-admin/services/api/userService.ts | 103 + .../TemplateSample/CollapsibleSection.tsx | 34 + .../TemplateSample/StyleSettingsPage.tsx | 2239 +++++++++++++++++ .../TemplateSample/TemplateLivePreview.tsx | 520 ++++ .../TemplateSample/TemplateSampleForm.tsx | 1758 +++++++++++++ .../TemplateSampleForm.utils.ts | 105 + .../TemplateSample/TemplateSampleList.tsx | 90 + .../TemplateSample/TemplateSamplePage.tsx | 146 ++ .../TemplateSamplePreviewPage.tsx | 108 + .../components/FontSettingsEditor.tsx | 91 + .../components/LayoutConfigEditor.tsx | 789 ++++++ .../LetterAssetsPlacementCanvas.tsx | 647 +++++ .../components/LetterLabelFieldEditor.tsx | 127 + .../components/ListStyleImageField.tsx | 240 ++ .../components/PageMarginEditor.tsx | 111 + .../components/ResetAllDefaultsModal.tsx | 74 + .../components/SettingHistoryModal.tsx | 167 ++ .../components/SettingsPanel.tsx | 252 ++ .../components/StyleNavigationMenu.tsx | 72 + .../components/StyleSettingsEditor.tsx | 864 +++++++ .../components/UnsavedChangesModal.tsx | 60 + .../components/layout-position.ts | 179 ++ .../components/styleSettingsUi.tsx | 353 +++ .../hooks/useListBulletResources.ts | 20 + .../hooks/useTemplateFormData.ts | 68 + .../hooks/useTemplateSettings.ts | 75 + .../TemplateSample/utils/cssConversion.ts | 153 ++ .../utils/letter-page-dimensions.ts | 132 + .../utils/letterLabelsConstants.ts | 243 ++ .../utils/styleSettingsConstants.ts | 196 ++ .../utils/templateResourceConstants.ts | 88 + .../utils/templateSamplePayloadUtils.ts | 183 ++ .../utils/templateSettingConstants.ts | 64 + .../utils/templateSettingsPayload.ts | 214 ++ .../components/AllRecordsTable.tsx | 62 + .../all-records/hooks/useAllRecords.ts | 19 + .../pages/AllRecordDetailsPage.tsx | 73 + .../all-records/pages/AllRecordsPage.tsx | 79 + .../all-records/services/allRecordsService.ts | 27 + .../user-management/all-records/types.ts | 27 + .../user-management/bulkUpload/bulkUpload.tsx | 1226 +++++++++ .../bulkUpload/bulkUploadParserLog.ts | 203 ++ .../MigratedDataColumnDefn.tsx | 98 + .../MigratedRecords/MigratedRecordList.tsx | 137 + .../MigratedRecords/ViewMigratedDataPage.tsx | 41 + .../components/content/AllPendingUsers.tsx | 221 ++ .../content/ArchivedUserColumnDefn.tsx | 85 + .../ArchivedUsers/ActivateArchivedUser.tsx | 78 + .../ArchivedUsers/ArchivedUserActions.tsx | 104 + .../components/content/CommonRemarks.tsx | 268 ++ .../components/content/ContentManagement.tsx | 508 ++++ .../components/content/HeaderAndFooter.tsx | 468 ++++ .../LetterTemplates/LetterTemplateForm.tsx | 377 +++ .../LetterTemplates/LetterTemplatesCard.tsx | 154 ++ .../LetterTemplates/LetterTemplatesTable.tsx | 701 ++++++ .../content/PrefixAndSuffixCard.tsx | 653 +++++ .../components/content/PrefixModal.tsx | 409 +++ .../content/PrefixSuffix/PrefixAndSuffix.tsx | 0 .../content/PrefixSuffix/PrefixSuffixForm.tsx | 0 .../PrefixSuffix/PrefixSuffixTable.tsx | 0 .../hooks/usePrefixSuffixMutations.ts | 0 .../components/content/PrefixSuffixTable.tsx | 246 ++ .../content/RecentActivitiesCard.tsx | 223 ++ .../components/content/RecordTagSelector.tsx | 351 +++ .../components/content/SealCard.tsx | 375 +++ .../content/TagBasedReferenceNumbers.tsx | 578 +++++ .../record-tags/RecordTagActionsCell.tsx | 126 + .../content/record-tags/RecordTagForm.tsx | 153 ++ .../content/record-tags/RecordTags.tsx | 89 + .../content/record-tags/RecordTagsColumn.tsx | 48 + .../components/content/useDebounce.ts | 36 + .../position-management/ActionsColumn.tsx | 94 + .../CreatePositionForm.tsx | 455 ++++ .../DeletePositionTypes.tsx | 71 + .../position-management/EditPositionForm.tsx | 160 ++ .../position-management/NotificationBell.tsx | 18 + .../position-management/PermissionSearch.tsx | 152 ++ .../position-management/PositionLists.tsx | 276 ++ .../PositionTypeActions.tsx | 393 +++ .../PositionTypeColumnDefn.tsx | 74 + .../PostionTypeMigration.tsx | 422 ++++ .../UserPositionApprovalActions.tsx | 40 + .../UserPositionApprovalCards.tsx | 45 + .../UserPositionApprovalColumns.tsx | 69 + .../UserPositionApprovalDecisionDialog.tsx | 82 + .../UserPositionApprovalList.tsx | 191 ++ .../userPositionApprovalUtils.ts | 6 + .../dto/applications/applicationDto.ts | 17 + .../dto/employees/employees.ts | 105 + .../dto/permissions/permissonDto.ts | 17 + .../dto/positions/positionDto.ts | 16 + .../dto/positions/positionType.ts | 19 + .../dto/recordTags/recordTags.type.ts | 27 + .../dto/teamMember/teamMember.ts | 32 + .../user-management/dto/unit/unitDto.ts | 14 + .../user-management/hooks/useApplications.ts | 72 + .../user-management/hooks/useArchived.ts | 155 ++ .../useEmployeePositionChangeRequests.ts | 103 + .../hooks/useEmployeePostions.ts | 185 ++ .../user-management/hooks/useEmployees.ts | 98 + .../hooks/useLetterTemplates.ts | 138 + .../hooks/useOrgAdminOrganizations.ts | 84 + .../hooks/useOrgUnitTotalCount.ts | 68 + .../hooks/useOrganizationEmployeeSearch.ts | 141 ++ .../user-management/hooks/useOrganizations.ts | 61 + .../hooks/usePermissionManager.ts | 101 + .../user-management/hooks/usePosition.ts | 199 ++ .../user-management/hooks/usePositionTypes.ts | 224 ++ .../user-management/hooks/usePostionType.ts | 99 + .../hooks/usePrefixSuffixes.ts | 207 ++ .../hooks/useRecordTagPrefixes.ts | 106 + .../user-management/hooks/useRecordTags.ts | 134 + .../user-management/hooks/useSeal.ts | 153 ++ .../user-management/hooks/useUnit.ts | 198 ++ .../hooks/useUserPositionApprovals.ts | 51 + .../pages/UserPositionApprovalPage.tsx | 7 + .../MigratedDataManagementPage.tsx | 6 + .../pages/position-management/create.tsx | 25 + .../pages/position-management/edit.tsx | 27 + .../pages/position-management/index.tsx | 13 + .../types/templateTypes.ts | 231 ++ .../services/api/applicationService.ts | 47 + .../services/api/auditService.ts | 76 + .../employeePositionChangeRequestService.ts | 160 ++ .../services/api/employeePositionsService.ts | 151 ++ .../services/api/employeesService.ts | 96 + .../services/api/headerFooterService.ts | 223 ++ .../services/api/letterTemplateService.ts | 85 + .../services/api/listBulletResources.ts | 39 + .../services/api/permissionService.ts | 46 + .../services/api/positionService.ts | 165 ++ .../api/positionTypeConfigurationService.ts | 88 + .../api/positionTypePermissionService.ts | 42 + .../services/api/positionTypesService.ts | 105 + .../services/api/prefixSuffixService.ts | 393 +++ .../services/api/recordTagsService.ts | 47 + .../services/api/sealService.ts | 122 + .../services/api/templateApiUtils.ts | 62 + .../services/api/templateService.ts | 382 +++ .../services/api/unitService.ts | 137 + .../services/api/uploadBulkService.ts | 40 + .../api/userPositionApprovalService.ts | 74 + .../userManagement/TeamMembers.tsx | 745 ++++++ .../userManagement/UserManagementTree.tsx | 1170 +++++++++ .../userManagement/ViewUsers.tsx | 164 ++ .../actions/DepartmentActions.tsx | 127 + .../actions/OrganizationActions.tsx | 73 + .../userManagement/actions/UnitActions.tsx | 131 + .../userManagement/components/Breadcrumb.tsx | 45 + .../components/OrganizationEmployeeSearch.tsx | 255 ++ .../components/UnitSelectionModal.tsx | 146 ++ .../dialogs/AddAssignUserDialog.tsx | 46 + .../dialogs/AddDepartmentDialog.tsx | 41 + .../dialogs/AddFromSubCityDialog.tsx | 39 + .../dialogs/AddSubDepartmentDialog.tsx | 47 + .../userManagement/dialogs/AddUnitDialog.tsx | 39 + .../userManagement/dialogs/AddUserDialog.tsx | 34 + .../dialogs/AddUserUnderDepartmentDialog.tsx | 46 + .../dialogs/DeactivateTeamMemberDialog.tsx | 76 + .../dialogs/DeleteDepartmentDialog.tsx | 95 + .../dialogs/DeleteTeamMemberDialog.tsx | 74 + .../dialogs/DeleteUnitDialog.tsx | 68 + .../dialogs/EditDepartmentDialog.tsx | 42 + .../userManagement/dialogs/EditUnitDialog.tsx | 62 + .../dialogs/EmployeePositionsDialog.tsx | 216 ++ .../dialogs/ManageUnitAdminDialog.tsx | 251 ++ .../dialogs/MoveDepartmentDialog.tsx | 43 + .../dialogs/PendingUsersCard.tsx | 82 + .../dialogs/PermanentDeleteUnitDialog.tsx | 122 + .../dialogs/ViewUsersDialog.tsx | 34 + .../forms/AddDepartmentForm.tsx | 181 ++ .../forms/AddFromSubCityForm.tsx | 373 +++ .../forms/AddSubDepartmentForm.tsx | 202 ++ .../userManagement/forms/AddUnitForm.tsx | 251 ++ .../userManagement/forms/AddUserForm.tsx | 152 ++ .../forms/AddUserUnderDepartmentForm.tsx | 230 ++ .../userManagement/forms/AssignUserForm.tsx | 362 +++ .../forms/EditDepartmentForm.tsx | 232 ++ .../userManagement/forms/EditUnitForm.tsx | 124 + .../forms/MoveDepartmentForm.tsx | 213 ++ .../handlers/useActionHandlers.ts | 265 ++ .../handlers/useSelectionHandlers.ts | 91 + .../hooks/useDepartmentsData.ts | 53 + .../userManagement/hooks/useEmployeesData.ts | 31 + .../hooks/useOrganizationsData.ts | 22 + .../hooks/usePendingUsersHook.ts | 83 + .../userManagement/hooks/usePositionsData.ts | 46 + .../userManagement/hooks/useUnitsData.ts | 90 + .../userManagement/lists/DepartmentList.tsx | 248 ++ .../userManagement/lists/OrganizationList.tsx | 128 + .../userManagement/lists/UnitList.tsx | 138 + .../user-management/userManagement/types.ts | 19 + .../web-Management/Branding/Branding.tsx | 1017 ++++++++ .../web-Management/ContactUs/AddContactUs.tsx | 71 + .../web-Management/ContactUs/ContactUs.tsx | 88 + .../ContactUs/ContactUsColumn.tsx | 105 + .../ContactUs/EditContactUs.tsx | 109 + .../web-Management/ContactUs/Form.tsx | 114 + .../web-Management/Goals/AddGoal.tsx | 84 + .../web-Management/Goals/EditGoal.tsx | 117 + .../web-Management/Goals/Form.tsx | 121 + .../web-Management/Goals/GoalColumn.tsx | 106 + .../web-Management/Goals/Goals.tsx | 86 + .../web-Management/Goals/ViewGoal.tsx | 106 + .../LeadershipMessage/AddMessage.tsx | 99 + .../LeadershipMessage/EditMessage.tsx | 144 ++ .../web-Management/LeadershipMessage/Form.tsx | 159 ++ .../LeadershipMessage/MessageColumn.tsx | 105 + .../LeadershipMessage/Messages.tsx | 87 + .../LeadershipMessage/ViewDeputy.tsx | 92 + .../LeadershipMessage/ViewMessage.tsx | 137 + .../web-Management/Modules/AddModules.tsx | 75 + .../web-Management/Modules/EditModules.tsx | 111 + .../web-Management/Modules/Form.tsx | 97 + .../web-Management/Modules/Modules.tsx | 85 + .../web-Management/Modules/ModulesColumn.tsx | 121 + .../web-Management/News/AddNews.tsx | 356 +++ .../web-Management/News/EditNews.tsx | 419 +++ .../web-Management/News/News.tsx | 143 ++ .../web-Management/News/NewsColumn.tsx | 130 + .../web-Management/News/ViewNews.tsx | 0 .../NewsCategory/AddNewsCategory.tsx | 92 + .../NewsCategory/EditNewsCategory.tsx | 129 + .../web-Management/NewsCategory/Form.tsx | 142 ++ .../NewsCategory/NewsCategory.tsx | 144 ++ .../NewsCategory/NewsCategoryColumn.tsx | 153 ++ .../SocialMedia/AddSocialMedia.tsx | 77 + .../SocialMedia/EditSocialMedia.tsx | 108 + .../web-Management/SocialMedia/Form.tsx | 134 + .../SocialMedia/SocialMedia.tsx | 85 + .../SocialMedia/SocialMediaColumn.tsx | 106 + .../TemplateConfigurationPage.tsx | 33 + .../TemplateConfiguration/TemplateForm.tsx | 517 ++++ .../TemplateConfiguration/TemplateList.tsx | 316 +++ .../types/templateTypes.ts | 53 + .../TemplateSettingValueForm.tsx | 338 +++ .../TemplateSettingValueList.tsx | 348 +++ .../TemplateSettingValuePage.tsx | 33 + .../hooks/useTemplateSettingValues.ts | 103 + .../services/templateSettingValueService.ts | 209 ++ .../types/templateSettingValueTypes.ts | 21 + .../web-Management/Theme/AddTheme.tsx | 181 ++ .../web-Management/Theme/EditTheme.tsx | 210 ++ .../web-Management/Theme/Theme.tsx | 85 + .../web-Management/Theme/ThemeColumn.tsx | 59 + .../web-Management/Vision/AddVision.tsx | 74 + .../web-Management/Vision/EditVision.tsx | 111 + .../web-Management/Vision/Form.tsx | 86 + .../web-Management/Vision/ViewVision.tsx | 51 + .../web-Management/Vision/Vision.tsx | 85 + .../web-Management/Vision/VisionColumn.tsx | 106 + .../web-Management/components/FormFeild.tsx | 30 + .../components/FormInputBox.tsx | 344 +++ .../web-Management/hooks/useBranding.ts | 71 + .../web-Management/hooks/useContactUs.ts | 92 + .../web-Management/hooks/useGoal.ts | 132 + .../web-Management/hooks/useMessage.ts | 139 + .../web-Management/hooks/useModules.ts | 92 + .../web-Management/hooks/useNews.ts | 135 + .../web-Management/hooks/useNewsCategory.ts | 144 ++ .../web-Management/hooks/useSocialMedia.ts | 94 + .../web-Management/hooks/useTemplates.ts | 113 + .../web-Management/hooks/useTheme.ts | 106 + .../web-Management/hooks/useVision.ts | 92 + .../web-Management/services/brandService.ts | 67 + .../services/contactUsService.ts | 46 + .../web-Management/services/goalService.ts | 106 + .../web-Management/services/messageService.ts | 102 + .../web-Management/services/modulesService.ts | 46 + .../web-Management/services/newsCategory.ts | 109 + .../services/newsCategoryService.ts | 81 + .../web-Management/services/newsService.ts | 107 + .../services/socialMediaService.ts | 46 + .../services/templateService.ts | 191 ++ .../web-Management/services/themeService.ts | 81 + .../web-Management/services/visionService.ts | 46 + .../web-Management/types/brandTypes.ts | 104 + .../web-Management/types/contactUs.ts | 41 + .../web-Management/types/goalType.ts | 55 + .../web-Management/types/messageTypes.ts | 62 + .../web-Management/types/modulesType.ts | 44 + .../web-Management/types/newsCategoryType.ts | 58 + .../web-Management/types/newsTypes.ts | 60 + .../web-Management/types/socialMediaType.ts | 42 + .../web-Management/types/themeTypes.ts | 38 + .../web-Management/types/visionType.ts | 41 + .../web-Management/webManagement.tsx | 465 ++++ 595 files changed, 90792 insertions(+) create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ethiopian-date-picker-overrides.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/flora.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/humanity.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/jquery.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/redmond.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/smoothness.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-black-tie.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-blitzer.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-cupertino.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dark-hive.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dot-luv.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-eggplant.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-excite-bike.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-flick.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-hot-sneaks.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui.calendars.picker.css create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/AmharicDatePicker.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateField.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateTimeField.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/EthiopianDatePicker.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/FormFields.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-blue.gif create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-green.gif create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar.gif create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view.png create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view2.png create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view3.png create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view4.png create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/jquery-global.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian-am.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.map create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.picker.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.plus.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.plugin.js create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/localizedName.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/FayidaInput.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/LoadingOverlay.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/SliderUI.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/Text.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/accordion.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert-dialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/avatar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/badge.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/breadcrumb.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/button.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/calendar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/card.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/chart.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/checkbox.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/collapsible.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/command.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/context-menu.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/dataTableColumnHeader.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/dataTablePagination.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/dataTablePagination2.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/dialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/drawer.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/dropdown-menu.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/empty-card.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/fileUpload.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/hooks/use-callback-ref.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/hooks/use-controllable-state.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/hooks/use-file-upload.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/reusableFileUploader.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/types/index.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/upload-files-card.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/fileUploader/utils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/habesha-date-picker.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/hover-card.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/input.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/label.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/multi-select.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/navigation-menu.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/pagination.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/popover.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/progress.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/radio-group.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/resizable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/scroll-area.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/select.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/separator.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/sheet.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/sidebar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/single-select.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/skeleton.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/sonner.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/sppiner.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/star-rating.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/switch.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/AdvancedTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/DataTableFacetedFilter.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/DataTablePagination.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/DataTablePaginationFinal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/DataTableToolbar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/DataTableViewOptions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/table/getColumnToggleLabel.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/tabs.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/textarea.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/toast.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/toaster.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/toggle-group.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/tooltip.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/treeSelect.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/use-toast.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/year-picker.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/utils/ethiopianTimeZone.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/FaydaCallbackDispatcher.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/SetPassword.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/SmartOfficeLoader.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/User/ChangePassword.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/User/Profile.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/activity-log/activity-card.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/activity-log/activity-filters.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/activity-log/activity-stats.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/activity-log/export-modal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/audit-log/AuditLogDetailPanel.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/audit-log/AuditLogDisplay.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/etrade/EtradeLicensePicker.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/filters/CombinedFilterBar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/login/ChangePassword.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/login/ForgotPassword.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/login/Login.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/login/OTPModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/login/ResetPassword.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/ui/DashboardDropdown.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/components/ui/DynamicBreadcrumb.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/config/app.config.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/config/env.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/context/AuthContext.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/context/BreadcrumbContext.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/context/PermissionContext.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/context/UnitContext.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/context/UserContext.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/dto/External-Portal/External-PortalDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/dto/organization/orgAdminsDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/dto/organization/organizationDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/dto/user/meDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/dto/user/usersDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useAdvancedDashboardHook.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useAlertSetup.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useAuditLogs.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useAuthUser.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useCombinedFilters.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useDarkMode.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useDelegationMonitor.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useErrorHandler.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useExportUserData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useExternalPortalSession.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useHas.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useNotification.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useOrganizationReport.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/usePersistedColumnVisibility.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/usePositionConfigurations.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/usePrefixSuffix.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useReferenceNumberPrefixes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useReminder.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useSession.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useUnitConfiguration.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/useUnitReport.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/hooks/withRoles.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/i18n/uiLanguages.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/lib/api.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/lib/sanitize.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/lib/tinyMceConfig.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/lib/utils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/navigation/footerItems.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/navigation/navigationItems.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/navigation/navigationtabs.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/navigation/sidebarToggle.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/pages/audit-log/audit-log-page.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/pages/audit-log/audit-log.types.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/pages/audit-log/audit-log.utils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/routes/routeConfig.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/routes/useActiveModule.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/Recordservice.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/audit/audit.api.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/audit/audit.http.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/authService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/axiosInstance.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/chronicleInstance.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/complaintService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/exportService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/fileService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/http/http-client-factory.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/notificationService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/objectiveInstance.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/organizationConfigService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/organizationsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/performanceInstance.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/positionConfigurationService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/presignedAxios.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/recordAxiosInstance.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/sessionExpiry.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/unifiedUploadService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/unitConfigurationService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/BufferContentValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/ClientSideValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/EmbeddedContentValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/FileUploadValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/MagicByteDetector.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/README.md create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/SVGContentValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/SecurityLogger.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/XSSUploadValidator.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/__tests__/BufferContentValidator.test.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/__tests__/ClientSideValidator.test.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/__tests__/FileUploadValidator.test.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/__tests__/SecurityLogger.test.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/errorMessages.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/index.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/types.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/services/validation/uploadContexts.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/authPersistence.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/chartExportUtils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/columnVisibilityStorage.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/faydaAuthSession.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/faydaOidc.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/filterParams.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/get-final-allowed-file-types.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/habeshaCalendar.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/max-file-size.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/permissionHelper.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/utils/refreshTokenHandler.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/app/store.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/assets/react.svg create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/components/ActivityTimeline.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/components/HeaderBar.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/components/OrgTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/components/StatCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/dashboardSlice.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/services/useDashboardStats.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/dashboard/types/dashboardStatsDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/ExternalUsersColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/PendingExternalUsers.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/ResponseActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/UpdateProfile.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/UserStatusToggleConfirm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/externalUsers/ViewDocuments.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/AssignAdminDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/AssignOrgAdminDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/OrganizationAdminList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/OrganizationAdmins.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/OrganizationAdminsActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/OrganizationAdminsColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/RemoveAdminConfirm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizationAdmins/StatusCell.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/AdminRegistrationForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/DeleteOrganizationPopup.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/EditOrganizationForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/ManageOrganizationDrawer.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/NewOrganizationForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/OrganizationDetail.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/Organizations.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/OrganizationsActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/OrganizationsColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/VisibilityCell.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/common/OrganizationActivateOrDeactivationPopup.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/organizations/common/OrganizationForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/settings/PasswordSettingsForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/sites/SiteFormModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/sites/SiteViewModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/sites/SitesColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/sites/SitesPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/components/TemplateCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/components/TemplateEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/components/TemplateForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/components/TemplateTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/components/templates.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/service/useTemplate.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/template.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/components/templates/types/templateTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/dto/ExternalUsersDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/dto/SitesDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/dto/SuperAdminDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/use-mobile.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useArchivedUsers.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useConfig.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useDashboardData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useDepartments.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useEmployees.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useExternalUsers.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useMigratedData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useOrganizationAdmins.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useOrganizationTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useOrganizations.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/usePasswordSettings.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/usePositions.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useRemark.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useSites.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useUnitInformation.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useUnits.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useUserRoles.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/hooks/useUsers.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/lib/dateFormatter.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/lib/utils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/dashboardApi.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/delegationTemplate.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/organizationAdminService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/organizationTypesService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/passwordSettingsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/sitesService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/userRoleService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/super-admin/services/api/userService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/CollapsibleSection.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/StyleSettingsPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateLivePreview.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateSampleForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateSampleForm.utils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateSampleList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateSamplePage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/TemplateSamplePreviewPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/FontSettingsEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/LayoutConfigEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/LetterAssetsPlacementCanvas.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/LetterLabelFieldEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/ListStyleImageField.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/PageMarginEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/ResetAllDefaultsModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/SettingHistoryModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/SettingsPanel.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/StyleNavigationMenu.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/StyleSettingsEditor.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/UnsavedChangesModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/layout-position.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/components/styleSettingsUi.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/hooks/useListBulletResources.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/hooks/useTemplateFormData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/hooks/useTemplateSettings.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/cssConversion.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/letter-page-dimensions.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/letterLabelsConstants.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/styleSettingsConstants.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/templateResourceConstants.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/templateSamplePayloadUtils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/templateSettingConstants.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/TemplateSample/utils/templateSettingsPayload.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/components/AllRecordsTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/hooks/useAllRecords.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/pages/AllRecordDetailsPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/pages/AllRecordsPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/services/allRecordsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/all-records/types.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/bulkUpload/bulkUpload.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/bulkUpload/bulkUploadParserLog.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/MigratedRecords/MigratedDataColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/MigratedRecords/MigratedRecordList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/MigratedRecords/ViewMigratedDataPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/AllPendingUsers.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/ArchivedUserColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/ArchivedUsers/ActivateArchivedUser.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/ArchivedUsers/ArchivedUserActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/CommonRemarks.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/ContentManagement.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/HeaderAndFooter.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/LetterTemplates/LetterTemplateForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/LetterTemplates/LetterTemplatesCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/LetterTemplates/LetterTemplatesTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixAndSuffixCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixSuffix/PrefixAndSuffix.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixSuffix/PrefixSuffixForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixSuffix/PrefixSuffixTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixSuffix/hooks/usePrefixSuffixMutations.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/PrefixSuffixTable.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/RecentActivitiesCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/RecordTagSelector.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/SealCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/TagBasedReferenceNumbers.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/record-tags/RecordTagActionsCell.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/record-tags/RecordTagForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/record-tags/RecordTags.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/record-tags/RecordTagsColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/content/useDebounce.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/ActionsColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/CreatePositionForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/DeletePositionTypes.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/EditPositionForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/NotificationBell.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/PermissionSearch.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/PositionLists.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/PositionTypeActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/PositionTypeColumnDefn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/position-management/PostionTypeMigration.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/UserPositionApprovalActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/UserPositionApprovalCards.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/UserPositionApprovalColumns.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/UserPositionApprovalDecisionDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/UserPositionApprovalList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/components/user-position-approvals/userPositionApprovalUtils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/applications/applicationDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/employees/employees.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/permissions/permissonDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/positions/positionDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/positions/positionType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/recordTags/recordTags.type.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/teamMember/teamMember.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/dto/unit/unitDto.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useApplications.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useArchived.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useEmployeePositionChangeRequests.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useEmployeePostions.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useEmployees.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useLetterTemplates.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useOrgAdminOrganizations.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useOrgUnitTotalCount.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useOrganizationEmployeeSearch.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useOrganizations.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/usePermissionManager.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/usePosition.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/usePositionTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/usePostionType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/usePrefixSuffixes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useRecordTagPrefixes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useRecordTags.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useSeal.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useUnit.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/hooks/useUserPositionApprovals.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/pages/UserPositionApprovalPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/pages/position-management/MigratedDataManagementPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/pages/position-management/create.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/pages/position-management/edit.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/pages/position-management/index.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/TemplateConfiguration/types/templateTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/applicationService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/auditService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/employeePositionChangeRequestService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/employeePositionsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/employeesService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/headerFooterService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/letterTemplateService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/listBulletResources.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/permissionService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/positionService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/positionTypeConfigurationService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/positionTypePermissionService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/positionTypesService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/prefixSuffixService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/recordTagsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/sealService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/templateApiUtils.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/templateService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/unitService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/uploadBulkService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/services/api/userPositionApprovalService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/TeamMembers.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/UserManagementTree.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/ViewUsers.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/actions/DepartmentActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/actions/OrganizationActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/actions/UnitActions.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/components/Breadcrumb.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/components/OrganizationEmployeeSearch.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/components/UnitSelectionModal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddAssignUserDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddFromSubCityDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddSubDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddUnitDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddUserDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/AddUserUnderDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/DeactivateTeamMemberDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/DeleteDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/DeleteTeamMemberDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/DeleteUnitDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/EditDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/EditUnitDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/EmployeePositionsDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/ManageUnitAdminDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/MoveDepartmentDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/PendingUsersCard.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/PermanentDeleteUnitDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/dialogs/ViewUsersDialog.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddDepartmentForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddFromSubCityForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddSubDepartmentForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddUnitForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddUserForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AddUserUnderDepartmentForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/AssignUserForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/EditDepartmentForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/EditUnitForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/forms/MoveDepartmentForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/handlers/useActionHandlers.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/handlers/useSelectionHandlers.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/useDepartmentsData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/useEmployeesData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/useOrganizationsData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/usePendingUsersHook.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/usePositionsData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/hooks/useUnitsData.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/lists/DepartmentList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/lists/OrganizationList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/lists/UnitList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/userManagement/types.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Branding/Branding.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/ContactUs/AddContactUs.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/ContactUs/ContactUs.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/ContactUs/ContactUsColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/ContactUs/EditContactUs.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/ContactUs/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/AddGoal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/EditGoal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/GoalColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/Goals.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Goals/ViewGoal.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/AddMessage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/EditMessage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/MessageColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/Messages.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/ViewDeputy.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/LeadershipMessage/ViewMessage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Modules/AddModules.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Modules/EditModules.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Modules/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Modules/Modules.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Modules/ModulesColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/News/AddNews.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/News/EditNews.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/News/News.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/News/NewsColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/News/ViewNews.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/NewsCategory/AddNewsCategory.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/NewsCategory/EditNewsCategory.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/NewsCategory/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/NewsCategory/NewsCategory.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/NewsCategory/NewsCategoryColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/SocialMedia/AddSocialMedia.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/SocialMedia/EditSocialMedia.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/SocialMedia/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/SocialMedia/SocialMedia.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/SocialMedia/SocialMediaColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateConfiguration/TemplateConfigurationPage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateConfiguration/TemplateForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateConfiguration/TemplateList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateConfiguration/types/templateTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/TemplateSettingValueForm.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/TemplateSettingValueList.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/TemplateSettingValuePage.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/hooks/useTemplateSettingValues.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/services/templateSettingValueService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/TemplateSettingValues/types/templateSettingValueTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Theme/AddTheme.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Theme/EditTheme.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Theme/Theme.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Theme/ThemeColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/AddVision.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/EditVision.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/Form.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/ViewVision.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/Vision.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/Vision/VisionColumn.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/components/FormFeild.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/components/FormInputBox.tsx create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useBranding.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useContactUs.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useGoal.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useMessage.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useModules.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useNews.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useNewsCategory.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useSocialMedia.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useTemplates.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useTheme.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/hooks/useVision.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/brandService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/contactUsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/goalService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/messageService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/modulesService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/newsCategory.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/newsCategoryService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/newsService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/socialMediaService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/templateService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/themeService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/services/visionService.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/brandTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/contactUs.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/goalType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/messageTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/modulesType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/newsCategoryType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/newsTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/socialMediaType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/themeTypes.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/types/visionType.ts create mode 100644 apps/edr-freight-web/backoffice/src/new-user-management-ui/user-management/web-Management/webManagement.tsx diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ethiopian-date-picker-overrides.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ethiopian-date-picker-overrides.css new file mode 100644 index 000000000..e6b4d28d6 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ethiopian-date-picker-overrides.css @@ -0,0 +1,279 @@ +.ethiopian-picker-surface .calendars { + width: 100% !important; + border: 0; + border-radius: 0.5rem; + color: rgb(31 41 55); + font-family: inherit; + font-size: 0.875rem; + box-shadow: none; +} + +.ethiopian-picker-surface .calendars-nav, +.ethiopian-picker-surface .calendars-ctrl { + background: transparent; + border-bottom: 1px solid rgb(229 231 235); + padding: 0.35rem 0.4rem; +} + +.ethiopian-picker-surface .calendars-month { + width: 100%; + border: 0; +} + +.ethiopian-picker-surface .calendars-month-header, +.ethiopian-picker-surface .calendars-month-header select, +.ethiopian-picker-surface .calendars-month-header input { + height: 2.1rem; + background: transparent; + color: rgb(17 24 39); + font-weight: 600; +} + +.ethiopian-picker-surface .calendars-month th, +.ethiopian-picker-surface .calendars-month td { + border: 0; + padding: 0.2rem; +} + +.ethiopian-picker-surface .calendars-month th { + color: rgb(107 114 128); + font-weight: 500; + font-size: 0.75rem; +} + +.ethiopian-picker-surface .calendars-month a, +.ethiopian-picker-surface .calendars-month span { + border-radius: 0.35rem; + background: transparent; + color: rgb(17 24 39); + padding: 0.38rem 0; +} + +.ethiopian-picker-surface .calendars-month a:hover { + background: rgb(220 252 231); + color: rgb(22 101 52); +} + +.ethiopian-picker-surface .calendars-month td .calendars-today { + background: rgb(220 252 231); + color: rgb(22 101 52); +} + +.ethiopian-picker-surface .calendars-month td .calendars-selected { + background: rgb(34 197 94); + color: rgb(255 255 255); +} + +.ethiopian-picker-surface .calendars-month td .calendars-other-month { + color: rgb(156 163 175); +} + +.ethiopian-picker-surface .calendars-nav .calendars-cmd-prev, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-next, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump, +.calendars-popup .calendars-nav .calendars-cmd-prev, +.calendars-popup .calendars-nav .calendars-cmd-next, +.calendars-popup .calendars-nav .calendars-cmd-prevJump, +.calendars-popup .calendars-nav .calendars-cmd-nextJump { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 2rem; + height: 2rem; + border: 1px solid rgb(187 247 208); + border-radius: 0.5rem; + background: rgb(240 253 244); + color: rgb(21 128 61); + line-height: 1; + transition: all 0.2s ease; +} + +.ethiopian-picker-surface .calendars-nav .calendars-cmd-prev:hover, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-next:hover, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump:hover, +.ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump:hover, +.calendars-popup .calendars-nav .calendars-cmd-prev:hover, +.calendars-popup .calendars-nav .calendars-cmd-next:hover, +.calendars-popup .calendars-nav .calendars-cmd-prevJump:hover, +.calendars-popup .calendars-nav .calendars-cmd-nextJump:hover { + background: rgb(34 197 94); + border-color: rgb(34 197 94); + color: rgb(255 255 255); +} + +.ethiopian-picker-surface .calendars-nav, +.calendars-popup .calendars-nav { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; +} + +.ethiopian-picker-surface .calendars-nav .calendars-cmd, +.calendars-popup .calendars-nav .calendars-cmd { + float: none; + width: auto; + padding-left: 0; + padding-right: 0; +} + +.ethiopian-picker-surface .calendars-nav .calendars-cmd-today, +.calendars-popup .calendars-nav .calendars-cmd-today { + flex: 1; + border-radius: 0.5rem; + color: rgb(21 128 61); + font-weight: 600; + text-align: center; +} + +.ethiopian-picker-surface .calendars-nav .calendars-cmd.calendars-disabled, +.calendars-popup .calendars-nav .calendars-cmd.calendars-disabled { + opacity: 0.45; + cursor: not-allowed; +} + +.dark .ethiopian-picker-surface .calendars, +[data-theme="dark"] .ethiopian-picker-surface .calendars, +.dark .calendars-popup .calendars, +[data-theme="dark"] .calendars-popup .calendars { + background: rgb(17 24 39); + color: rgb(229 231 235); + border-color: rgb(55 65 81); +} + +.dark .ethiopian-picker-surface .calendars-nav, +.dark .ethiopian-picker-surface .calendars-ctrl, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav, +[data-theme="dark"] .ethiopian-picker-surface .calendars-ctrl, +.dark .calendars-popup .calendars-nav, +.dark .calendars-popup .calendars-ctrl, +[data-theme="dark"] .calendars-popup .calendars-nav, +[data-theme="dark"] .calendars-popup .calendars-ctrl { + background: rgb(17 24 39); + border-color: rgb(55 65 81); +} + +.dark .ethiopian-picker-surface .calendars-month-header, +.dark .ethiopian-picker-surface .calendars-month-header select, +.dark .ethiopian-picker-surface .calendars-month-header input, +.dark .ethiopian-picker-surface .calendars-month a, +.dark .ethiopian-picker-surface .calendars-month span, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month-header, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month-header select, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month-header input, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month a, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month span, +.dark .calendars-popup .calendars-month-header, +.dark .calendars-popup .calendars-month-header select, +.dark .calendars-popup .calendars-month-header input, +.dark .calendars-popup .calendars-month a, +.dark .calendars-popup .calendars-month span, +[data-theme="dark"] .calendars-popup .calendars-month-header, +[data-theme="dark"] .calendars-popup .calendars-month-header select, +[data-theme="dark"] .calendars-popup .calendars-month-header input, +[data-theme="dark"] .calendars-popup .calendars-month a, +[data-theme="dark"] .calendars-popup .calendars-month span { + color: rgb(229 231 235); +} + +.dark .ethiopian-picker-surface .calendars-month th, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month th, +.dark .calendars-popup .calendars-month th, +[data-theme="dark"] .calendars-popup .calendars-month th { + color: rgb(156 163 175); +} + +.dark .ethiopian-picker-surface .calendars-month a:hover, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month a:hover, +.dark .calendars-popup .calendars-month a:hover, +[data-theme="dark"] .calendars-popup .calendars-month a:hover { + background: rgb(20 83 45); + color: rgb(187 247 208); +} + +.dark .ethiopian-picker-surface .calendars-month td .calendars-today, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month td .calendars-today, +.dark .calendars-popup .calendars-month td .calendars-today, +[data-theme="dark"] .calendars-popup .calendars-month td .calendars-today { + background: rgb(20 83 45); + color: rgb(187 247 208); +} + +.dark .ethiopian-picker-surface .calendars-month td .calendars-highlight, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month td .calendars-highlight, +.dark .calendars-popup .calendars-month td .calendars-highlight, +[data-theme="dark"] .calendars-popup .calendars-month td .calendars-highlight { + background: rgb(22 101 52); +} + +.dark .ethiopian-picker-surface .calendars-month td .calendars-selected, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month td .calendars-selected, +.dark .calendars-popup .calendars-month td .calendars-selected, +[data-theme="dark"] .calendars-popup .calendars-month td .calendars-selected { + background: rgb(34 197 94); + color: rgb(5 46 22); +} + +.dark .ethiopian-picker-surface .calendars-month td .calendars-other-month, +[data-theme="dark"] .ethiopian-picker-surface .calendars-month td .calendars-other-month, +.dark .calendars-popup .calendars-month td .calendars-other-month, +[data-theme="dark"] .calendars-popup .calendars-month td .calendars-other-month { + color: rgb(107 114 128); +} + +.dark .ethiopian-picker-surface .calendars a.calendars-disabled, +[data-theme="dark"] .ethiopian-picker-surface .calendars a.calendars-disabled, +.dark .calendars-popup .calendars a.calendars-disabled, +[data-theme="dark"] .calendars-popup .calendars a.calendars-disabled { + color: rgb(75 85 99); +} + +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-prev, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-next, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-prev, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-next, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump, +.dark .calendars-popup .calendars-nav .calendars-cmd-prev, +.dark .calendars-popup .calendars-nav .calendars-cmd-next, +.dark .calendars-popup .calendars-nav .calendars-cmd-prevJump, +.dark .calendars-popup .calendars-nav .calendars-cmd-nextJump, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-prev, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-next, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-prevJump, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-nextJump { + background: rgb(21 128 61 / 0.22); + border-color: rgb(34 197 94 / 0.45); + color: rgb(187 247 208); +} + +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-prev:hover, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-next:hover, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump:hover, +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump:hover, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-prev:hover, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-next:hover, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-prevJump:hover, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-nextJump:hover, +.dark .calendars-popup .calendars-nav .calendars-cmd-prev:hover, +.dark .calendars-popup .calendars-nav .calendars-cmd-next:hover, +.dark .calendars-popup .calendars-nav .calendars-cmd-prevJump:hover, +.dark .calendars-popup .calendars-nav .calendars-cmd-nextJump:hover, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-prev:hover, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-next:hover, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-prevJump:hover, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-nextJump:hover { + background: rgb(34 197 94); + border-color: rgb(34 197 94); + color: rgb(5 46 22); +} + +.dark .ethiopian-picker-surface .calendars-nav .calendars-cmd-today, +[data-theme="dark"] .ethiopian-picker-surface .calendars-nav .calendars-cmd-today, +.dark .calendars-popup .calendars-nav .calendars-cmd-today, +[data-theme="dark"] .calendars-popup .calendars-nav .calendars-cmd-today { + color: rgb(187 247 208); +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/flora.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/flora.calendars.picker.css new file mode 100644 index 000000000..3a359e149 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/flora.calendars.picker.css @@ -0,0 +1,208 @@ +/* Flora styling for jQuery Calendars Picker v2.0.0. */ +.calendars { + background-color: #e0f4d7; + color: #000; + border: 1px solid #f90; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-family: Arial,Helvetica,Sans-serif; + font-size: 90%; +} +.calendars-rtl { + direction: rtl; +} +.calendars-popup { + z-index: 1000; +} +.calendars-disable { + position: absolute; + z-index: 100; + background-color: white; + opacity: 0.5; + filter: alpha(opacity=50); +} +.calendars a { + color: #000; + text-decoration: none; +} +.calendars a.calendars-disabled { + color: #888; + cursor: auto; +} +.calendars button { + margin: 0.25em; + padding: 0.125em 0em; + background-color: #fc8; + border: none; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-weight: bold; +} +.calendars-nav, .calendars-ctrl { + float: left; + width: 100%; + background-color: #e0f4d7; + color: #fff; + font-size: 90%; + font-weight: bold; +} +.datepick-ctrl { + background-color: #f90; +} +.calendars-cmd { + width: 30%; +} +.calendars-cmd:hover { + background-color: #b1db87; +} +.calendars-ctrl .calendars-cmd:hover { + background-color: #fa4; +} +.calendars-cmd-prevJump, .calendars-cmd-nextJump { + width: 8%; +} +a.calendars-cmd { + height: 1.5em; +} +button.calendars-cmd { + text-align: center; +} +.calendars-cmd-prev, .calendars-cmd-prevJump, .calendars-cmd-clear { + float: left; + padding-left: 2%; +} +.calendars-cmd-current, .calendars-cmd-today { + float: left; + width: 35%; + text-align: center; +} +.calendars-cmd-next, .calendars-cmd-nextJump, .calendars-cmd-close { + float: right; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-prev, .calendars-rtl .calendars-cmd-prevJump, +.calendars-rtl .calendars-cmd-clear { + float: right; + padding-left: 0%; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-current, .calendars-rtl .calendars-cmd-today { + float: right; +} +.calendars-rtl .calendars-cmd-next, .calendars-rtl .calendars-cmd-nextJump, +.calendars-rtl .calendars-cmd-close { + float: left; + padding-left: 2%; + padding-right: 0%; + text-align: left; +} +.calendars-month-nav { + float: left; + background-color: #b1db87; + text-align: center; +} +.calendars-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.calendars-month-nav span { + color: #888; +} +.calendars-month-row { + clear: left; +} +.calendars-month { + float: left; + width: 15em; + border: 1px solid #83c948; + text-align: center; +} +.calendars-month-header, .calendars-month-header select, .calendars-month-header input { + height: 1.5em; + background-color: #83c948; + color: #fff; + font-weight: bold; +} +.calendars-month-header select, .calendars-month-header input { + height: 1.4em; + border: none; +} +.calendars-month-header input { + position: absolute; + display: none; +} +.calendars-month table { + width: 100%; + border-collapse: collapse; +} +.calendars-month thead { + border-bottom: 1px solid #aaa; +} +.calendars-month th, .calendars-month td { + margin: 0em; + padding: 0em; + font-weight: normal; + text-align: center; +} +.calendars-month th { + border: 1px solid #b1db87; +} +.calendars-month th, .calendars-month th a { + background-color: #b1db87; + color: #000; + border: 1px solid #b1db87; +} +.calendars-month td { + background-color: #fff; + color: #666; + border: 1px solid #b1db87; +} +.calendars-month td.calendars-week * { + background-color: #b1db87; + color: #666; + border: none; +} +.calendars-month a { + display: block; + width: 100%; + padding: 0.125em 0em; + text-decoration: none; +} +.calendars-month span { + display: block; + width: 100%; + padding: 0.125em 0em; +} +.calendars-month td span { + color: #888; +} +.calendars-month td .calendars-other-month { + background-color: #e0f4d7; +} +.calendars-month td .calendars-weekend { + background-color: #e0f4d7; +} +.calendars-month td .calendars-today { + background-color: #b1db87; +} +.calendars-month td .calendars-highlight { + background-color: #fc8; +} +.calendars-month td .calendars-selected { + background-color: #f90; + color: #fff; +} +.calendars-status { + clear: both; + background-color: #b1db87; + text-align: center; +} +.calendars-clear-fix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/humanity.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/humanity.calendars.picker.css new file mode 100644 index 000000000..cb69417a4 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/humanity.calendars.picker.css @@ -0,0 +1,197 @@ +/* Humanity styling for jQuery Calendars Picker v2.0.0. */ +.calendars { + background-color: #f4f0ec; + color: #1e1b1c; + border: 1px solid #cb842e; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-family: Arial,Helvetica,Sans-serif; + font-size: 90%; +} +.calendars-rtl { + direction: rtl; +} +.calendars-popup { + z-index: 1000; +} +.calendars-disable { + position: absolute; + z-index: 100; + background-color: white; + opacity: 0.5; + filter: alpha(opacity=50); +} +.calendars a { + color: #1e1b1c; + text-decoration: none; +} +.calendars a.calendars-disabled { + color: #888; + cursor: auto; +} +.calendars button { + margin: 0.25em; + padding: 0.125em 0em; + background-color: #ede4d4; + border: none; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-weight: bold; +} +.calendars-nav, .calendars-ctrl { + float: left; + width: 100%; + background-color: #ede4d4; + font-size: 90%; + font-weight: bold; +} +.calendars-ctrl { + background-color: #cb842e; +} +.calendars-cmd { + width: 30%; +} +.calendars-cmd:hover { + background-color: #f4f0ec; +} +.calendars-cmd-prevJump, .calendars-cmd-nextJump { + width: 8%; +} +a.calendars-cmd { + height: 1.5em; +} +button.calendars-cmd { + text-align: center; +} +.calendars-cmd-prev, .calendars-cmd-prevJump, .calendars-cmd-clear { + float: left; + padding-left: 2%; +} +.calendars-cmd-current, .calendars-cmd-today { + float: left; + width: 35%; + text-align: center; +} +.calendars-cmd-next, .calendars-cmd-nextJump, .calendars-cmd-close { + float: right; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-prev, .calendars-rtl .calendars-cmd-prevJump, +.calendars-rtl .calendars-cmd-clear { + float: right; + padding-left: 0%; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-current, .calendars-rtl .calendars-cmd-today { + float: right; +} +.calendars-rtl .calendars-cmd-next, .calendars-rtl .calendars-cmd-nextJump, +.calendars-rtl .calendars-cmd-close { + float: left; + padding-left: 2%; + padding-right: 0%; + text-align: left; +} +.calendars-month-nav { + float: left; + text-align: center; +} +.calendars-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.calendars-month-nav span { + color: #888; +} +.calendars-month-row { + clear: left; +} +.calendars-month { + float: left; + width: 17em; + border: 1px solid #e0cfc2; + text-align: center; +} +.calendars-month-header, .calendars-month-header select, .calendars-month-header input { + height: 1.5em; + background-color: #cb842e; + color: #fff; + font-weight: bold; +} +.calendars-month-header select, .calendars-month-header input { + height: 1.4em; + border: none; +} +.calendars-month-header input { + position: absolute; + display: none; +} +.calendars-month table { + width: 100%; + border: 2px solid transparent; + border-collapse: collapse; +} +.calendars-month th, .calendars-month td { + margin: 0em; + padding: 0.125em; + font-weight: normal; + text-align: center; +} +.calendars-month td.calendars-week, +.calendars-month td.calendars-week * { + background-color: #cb842e; + color: #fff; + border: 1px solid #cb842e; +} +.calendars-month a { + display: block; + width: 100%; + padding: 0.125em 0em; + background-color: #ede4d4; + color: #000; + border: 1px solid #cdc3b7; + text-decoration: none; +} +.calendars-month span { + display: block; + margin-top: 0.25em; +} +.calendars-month a { + background-color: #ede4d4; + color: #444; + border: 1px solid #cdc3b7; + text-decoration: none; +} +.calendars-month td span { + color: #888; +} +.calendars-month td .calendars-other-month { + background-color: #f4f0ec; +} +.calendars-month td .calendars-today { + background-color: #f5f5b5; + border: 1px solid #d9bb73; +} +.calendars-month td .calendars-highlight { + background-color: #f5f0e5; + color: #1e1b1c; + border: 1px solid #f5ad66; +} +.calendars-month td .calendars-selected { + background-color: #cb842e; + color: #fff; + border: 1px solid #cb842e; +} +.calendars-status { + clear: both; + text-align: center; +} +.calendars-clear-fix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/jquery.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/jquery.calendars.picker.css new file mode 100644 index 000000000..8b8ff6223 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/jquery.calendars.picker.css @@ -0,0 +1,215 @@ +/* Default styling for jQuery Calendars Picker v2.0.0. */ +.calendars { + background-color: #fff; + color: #000; + border: 1px solid #444; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-family: Arial,Helvetica,Sans-serif; + font-size: 90%; +} +.calendars-rtl { + direction: rtl; +} +.calendars-popup { + z-index: 1000; +} +.calendars-disable { + position: absolute; + z-index: 100; + background-color: white; + opacity: 0.5; + filter: alpha(opacity=50); +} +.calendars a { + color: #fff; + text-decoration: none; +} +.calendars a.calendars-disabled { + color: #888; + cursor: auto; +} +.calendars button { + margin: 0.25em; + padding: 0.125em 0em; + background-color: #fcc; + border: none; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-weight: bold; +} +.calendars-nav, .calendars-ctrl { + float: left; + width: 100%; + background-color: #000; + color: #fff; + font-size: 90%; + font-weight: bold; +} +.calendars-ctrl { + background-color: #600; +} +.calendars-cmd { + width: 30%; +} +.calendars-cmd:hover { + background-color: #777; +} +.calendars-ctrl .calendars-cmd:hover { + background-color: #f08080; +} +.calendars-cmd-prevJump, .calendars-cmd-nextJump { + width: 8%; +} +a.calendars-cmd { + height: 1.5em; +} +button.calendars-cmd { + text-align: center; +} +.calendars-cmd-prev, .calendars-cmd-prevJump, .calendars-cmd-clear { + float: left; + padding-left: 2%; +} +.calendars-cmd-current, .calendars-cmd-today { + float: left; + width: 35%; + text-align: center; +} +.calendars-cmd-next, .calendars-cmd-nextJump, .calendars-cmd-close { + float: right; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-prev, .calendars-rtl .calendars-cmd-prevJump, +.calendars-rtl .calendars-cmd-clear { + float: right; + padding-left: 0%; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-current, .calendars-rtl .calendars-cmd-today { + float: right; +} +.calendars-rtl .calendars-cmd-next, .calendars-rtl .calendars-cmd-nextJump, +.calendars-rtl .calendars-cmd-close { + float: left; + padding-left: 2%; + padding-right: 0%; + text-align: left; +} +.calendars-month-nav { + float: left; + background-color: #777; + text-align: center; +} +.calendars-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.calendars-month-nav span { + color: #888; +} +.calendars-month-row { + clear: left; +} +.calendars-month { + float: left; + width: 15em; + border: 1px solid #444; + text-align: center; +} +.calendars-month-header, .calendars-month-header select, .calendars-month-header input { + height: 1.5em; + background-color: #444; + color: #fff; + font-weight: bold; +} +.calendars-month-header select, .calendars-month-header input { + height: 1.4em; + border: none; +} +.calendars-month-header input { + position: absolute; + display: none; +} +.calendars-month table { + width: 100%; + border-collapse: collapse; +} +.calendars-month thead { + border-bottom: 1px solid #aaa; +} +.calendars-month th, .calendars-month td { + margin: 0em; + padding: 0em; + font-weight: normal; + text-align: center; +} +.calendars-month th { + border: 1px solid #777; +} +.calendars-month th, .calendars-month th a { + background-color: #777; + color: #fff; +} +.calendars-month td { + background-color: #eee; + border: 1px solid #aaa; +} +.calendars-month td.calendars-week { + border: 1px solid #777; +} +.calendars-month td.calendars-week * { + background-color: #777; + color: #fff; + border: none; +} +.calendars-month a { + display: block; + width: 100%; + padding: 0.125em 0em; + background-color: #eee; + color: #000; + text-decoration: none; +} +.calendars-month span { + display: block; + width: 100%; + padding: 0.125em 0em; +} +.calendars-month td span { + color: #888; +} +.calendars-month td .calendars-other-month { + background-color: #fff; +} +.calendars-month td .calendars-weekend { + background-color: #ddd; +} +.calendars-month td .calendars-today { + background-color: #f0c0c0; +} +.calendars-month td .calendars-highlight { + background-color: #f08080; +} +.calendars-month td .calendars-selected { + background-color: #777; + color: #fff; +} +.calendars-month th.calendars-week { + background-color: #777; + color: #fff; +} +.calendars-status { + clear: both; + background-color: #ddd; + text-align: center; +} +.calendars-clear-fix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/redmond.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/redmond.calendars.picker.css new file mode 100644 index 000000000..c105ace5e --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/redmond.calendars.picker.css @@ -0,0 +1,199 @@ +/* Redmond styling for jQuery Calendars Picker v2.0.0. */ +.calendars { + background-color: #fff; + color: #222; + border: 1px solid #4297d7; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-family: Arial,Helvetica,Sans-serif; + font-size: 90%; +} +.calendars-rtl { + direction: rtl; +} +.calendars-popup { + z-index: 1000; +} +.calendars-disable { + position: absolute; + z-index: 100; + background-color: white; + opacity: 0.5; + filter: alpha(opacity=50); +} +.calendars a { + color: #222; + text-decoration: none; +} +.calendars a.calendars-disabled { + color: #888; + cursor: auto; +} +.calendars button { + margin: 0.25em; + padding: 0.125em 0em; + background-color: #5c9ccc; + color: #fff; + border: none; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-weight: bold; +} +.calendars-nav, .calendars-ctrl { + float: left; + width: 100%; + background-color: #fff; + font-size: 90%; + font-weight: bold; +} +.calendars-ctrl { + background-color: #d0e5f5; +} +.calendars-cmd { + width: 30%; +} +.calendars-cmd:hover { + background-color: #dfeffc; +} +button.calendars-cmd:hover { + background-color: #79b7e7; +} +.calendars-cmd-prevJump, .calendars-cmd-nextJump { + width: 8%; +} +a.calendars-cmd { + height: 1.5em; +} +button.calendars-cmd { + text-align: center; +} +.calendars-cmd-prev, .calendars-cmd-prevJump, .calendars-cmd-clear { + float: left; + padding-left: 2%; +} +.calendars-cmd-current, .calendars-cmd-today { + float: left; + width: 35%; + text-align: center; +} +.calendars-cmd-next, .calendars-cmd-nextJump, .calendars-cmd-close { + float: right; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-prev, .calendars-rtl .calendars-cmd-prevJump, +.calendars-rtl .calendars-cmd-clear { + float: right; + padding-left: 0%; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-current, .calendars-rtl .calendars-cmd-today { + float: right; +} +.calendars-rtl .calendars-cmd-next, .calendars-rtl .calendars-cmd-nextJump, +.calendars-rtl .calendars-cmd-close { + float: left; + padding-left: 2%; + padding-right: 0%; + text-align: left; +} +.calendars-month-nav { + float: left; + text-align: center; +} +.calendars-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.calendars-month-nav span { + color: #888; +} +.calendars-month-row { + clear: left; +} +.calendars-month { + float: left; + width: 15em; + border: 1px solid #5c9ccc; + text-align: center; +} +.calendars-month-header, .calendars-month-header select, .calendars-month-header input { + height: 1.5em; + background-color: #5c9ccc; + color: #fff; + font-weight: bold; +} +.calendars-month-header select, .calendars-month-header input { + height: 1.4em; + border: none; +} +.calendars-month-header input { + position: absolute; + display: none; +} +.calendars-month table { + width: 100%; + border-collapse: collapse; +} +.calendars-month thead { + border-bottom: 1px solid #aaa; +} +.calendars-month th, .calendars-month td { + margin: 0em; + padding: 0em; + font-weight: normal; + text-align: center; +} +.calendars-month th { + border: 1px solid #fff; + border-bottom: 1px solid #c5dbec; +} +.calendars-month td { + border: 1px solid #c5dbec; +} +.calendars-month td.calendars-week * { + background-color: #d0e5f5; + color: #222; + border: none; +} +.calendars-month a { + display: block; + width: 100%; + padding: 0.125em 0em; + background-color: #dfeffc; + color: #000; + text-decoration: none; +} +.calendars-month span { + display: block; + width: 100%; + padding: 0.125em 0em; +} +.calendars-month td span { + color: #888; +} +.calendars-month td .calendars-other-month { + background-color: #fff; +} +.calendars-month td .calendars-today { + background-color: #fad42e; +} +.calendars-month td .calendars-highlight { + background-color: #79b7e7; +} +.calendars-month td .calendars-selected { + background-color: #4297d7; + color: #fff; +} +.calendars-status { + clear: both; + text-align: center; +} +.calendars-clear-fix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/smoothness.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/smoothness.calendars.picker.css new file mode 100644 index 000000000..8ffa6387d --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/smoothness.calendars.picker.css @@ -0,0 +1,200 @@ +/* Smoothness styling for jQuery Calendars Picker v2.0.0. */ +.calendars { + background-color: #fff; + color: #222; + border: 1px solid #aaa; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-family: Arial,Helvetica,Sans-serif; + font-size: 90%; +} +.calendars-rtl { + direction: rtl; +} +.calendars-popup { + z-index: 1000; +} +.calendars-disable { + position: absolute; + z-index: 100; + background-color: white; + opacity: 0.5; + filter: alpha(opacity=50); +} +.calendars a { + color: #222; + text-decoration: none; +} +.calendars a.calendars-disabled { + color: #888; + cursor: auto; +} +.calendars button { + margin: 0.25em; + padding: 0.125em 0em; + background-color: #fcc; + border: none; + -moz-border-radius: 0.25em; + -webkit-border-radius: 0.25em; + border-radius: 0.25em; + font-weight: bold; +} +.calendars-nav, .calendars-ctrl { + float: left; + width: 100%; + background-color: #fff; + font-size: 90%; + font-weight: bold; +} +.calendars-ctrl { + background-color: #fee6e3; +} +.calendars-cmd { + width: 30%; +} +.calendars-cmd:hover { + background-color: #e0e0e0; +} +.calendars-ctrl .calendars-cmd:hover { + background-color: #f08080; +} +.calendars-cmd-prevJump, .calendars-cmd-nextJump { + width: 8%; +} +a.calendars-cmd { + height: 1.5em; +} +button.calendars-cmd { + text-align: center; +} +.calendars-cmd-prev, .calendars-cmd-prevJump, .calendars-cmd-clear { + float: left; + padding-left: 2%; +} +.calendars-cmd-current, .calendars-cmd-today { + float: left; + width: 35%; + text-align: center; +} +.calendars-cmd-next, .calendars-cmd-nextJump, .calendars-cmd-close { + float: right; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-prev, .calendars-rtl .calendars-cmd-prevJump, +.calendars-rtl .calendars-cmd-clear { + float: right; + padding-left: 0%; + padding-right: 2%; + text-align: right; +} +.calendars-rtl .calendars-cmd-current, .calendars-rtl .calendars-cmd-today { + float: right; +} +.calendars-rtl .calendars-cmd-next, .calendars-rtl .calendars-cmd-nextJump, +.calendars-rtl .calendars-cmd-close { + float: left; + padding-left: 2%; + padding-right: 0%; + text-align: left; +} +.calendars-month-nav { + float: left; + text-align: center; +} +.calendars-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.calendars-month-nav span { + color: #888; +} +.calendars-month-row { + clear: left; +} +.calendars-month { + float: left; + width: 15em; + border: 1px solid #aaa; + text-align: center; +} +.calendars-month-header, .calendars-month-header select, .calendars-month-header input { + height: 1.5em; + background-color: #e0e0e0; + color: #222; + font-weight: bold; +} +.calendars-month-header select, .calendars-month-header input { + height: 1.4em; + border: none; +} +.calendars-month-header input { + position: absolute; + display: none; +} +.calendars-month table { + width: 100%; + border-collapse: collapse; +} +.calendars-month thead { + border-bottom: 1px solid #aaa; +} +.calendars-month th, .calendars-month td { + margin: 0em; + padding: 0em; + font-weight: normal; + text-align: center; +} +.calendars-month thead tr { + border: 1px solid #aaa; +} +.calendars-month td { + background-color: #eee; + border: 1px solid #aaa; +} +.calendars-month td.calendars-week * { + background-color: #e0e0e0; + color: #222; + border: none; +} +.calendars-month a { + display: block; + width: 100%; + padding: 0.125em 0em; + background-color: #eee; + color: #000; + text-decoration: none; +} +.calendars-month span { + display: block; + width: 100%; + padding: 0.125em 0em; +} +.calendars-month td span { + color: #888; +} +.calendars-month td .calendars-other-month { + background-color: #fff; +} +.calendars-month td .calendars-weekend { + background-color: #ddd; +} +.calendars-month td .calendars-today { + background-color: #fbf9ee; +} +.calendars-month td .calendars-highlight { + background-color: #dadada; +} +.calendars-month td .calendars-selected { + background-color: #fcc; +} +.calendars-status { + clear: both; + text-align: center; +} +.calendars-clear-fix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-black-tie.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-black-tie.calendars.picker.css new file mode 100644 index 000000000..8b2662bda --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-black-tie.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Blacktie override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #eeeeee; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #1c1c1c; /* Set (.ui-state-hover) colours from theme here */ + color: #ffffff; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #333333; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #363636; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-blitzer.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-blitzer.calendars.picker.css new file mode 100644 index 000000000..8ba0b1bcf --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-blitzer.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Blitzer override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #ffffff; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #f6f6f6; /* Set (.ui-state-hover) colours from theme here */ + color: #111111; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #cc0000; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #555555; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-cupertino.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-cupertino.calendars.picker.css new file mode 100644 index 000000000..422d05500 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-cupertino.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Cupertino override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #222222; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #f0f0f0; /* Set (.ui-state-hover) colours from theme here */ + color: #0b5b98; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #e7eef3; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #363636; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dark-hive.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dark-hive.calendars.picker.css new file mode 100644 index 000000000..9e8ed89de --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dark-hive.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Dark Hive override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #ffffff; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #003147; /* Set (.ui-state-hover) colours from theme here */ + color: #ffffff;; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #444444; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #eeeeee; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dot-luv.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dot-luv.calendars.picker.css new file mode 100644 index 000000000..565ede68f --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-dot-luv.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller DotLuv override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #f6f6f6; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #00498f; /* Set (.ui-state-hover) colours from theme here */ + color: #ffffff; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #0b3e6f; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #ffffff; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-eggplant.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-eggplant.calendars.picker.css new file mode 100644 index 000000000..d2b61da9b --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-eggplant.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Eggplant override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #ffffff; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #eae6ea; /* Set (.ui-state-hover) colours from theme here */ + color: #734d99; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #30273a; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #fafafa; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-excite-bike.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-excite-bike.calendars.picker.css new file mode 100644 index 000000000..4791e44bc --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-excite-bike.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller ExciteBike override style sheet for jQuery dCalendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #e69700; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #2293f7; /* Set (.ui-state-hover) colours from theme here */ + color: #ffffff; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #f9f9f9; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #333333; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-flick.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-flick.calendars.picker.css new file mode 100644 index 000000000..c133db1fe --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-flick.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller Flick override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #444444; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #0073ea; /* Set (.ui-state-hover) colours from theme here */ + color: #ffffff; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #dddddd; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #444444; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-hot-sneaks.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-hot-sneaks.calendars.picker.css new file mode 100644 index 000000000..c6a581429 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui-hot-sneaks.calendars.picker.css @@ -0,0 +1,18 @@ +/* ThemeRoller HotSneaks override style sheet for jQuery Calendars Picker v2.0.0. */ +@import "ui.calendars.picker.css"; + +.ui-widget-header a, +.ui-widget-header select { + color: #e1e463; /* Set (.ui-widget-header a) colour from theme here */ +} +.ui-widget-header a:hover { + background-color: #ccd232; /* Set (.ui-state-hover) colours from theme here */ + color: #212121; +} +.ui-widget-header select, +.ui-widget-header option { + background-color: #35414f; /* Set (.ui-widget-header) background colour from theme here */ +} +.ui-state-highlight a { + color: #363636; /* Set (.ui-state-highlight) colour from theme here */ +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui.calendars.picker.css b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui.calendars.picker.css new file mode 100644 index 000000000..2baeaa73d --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/css/ui.calendars.picker.css @@ -0,0 +1,107 @@ +/* ThemeRoller override style sheet for jQuery Calendars Picker v2.0.0. */ +.ui-datepicker { + display: block; +} +#ui-datepicker-div, +.ui-datepicker-inline { + width: 17em; + font-size: 75%; +} +#ui-datepicker-div { + z-index: 100; +} +.ui-datepicker-inline { + float: left; +} +.ui-datepicker-rtl { + direction: rtl; +} +#ui-datepicker-div a, +.ui-datepicker-inline a { + text-decoration: none; +} +.ui-datepicker-prompt { + height: 1.5em; + padding-top: 0.25em; + text-align: center; +} +button.ui-datepicker-cmd { + height: 2em; +} +.ui-datepicker-cmd-clear { + float: left; + margin-left: 0.25em; +} +.ui-datepicker-cmd-close { + float: right; + margin-right: 0.25em; +} +.ui-datepicker-cmd-prev { + position: static; + float: left; + width: 30%; + height: auto; + margin-left: 1%; +} +.ui-datepicker-cmd-next { + position: static; + float: right; + width: 30%; + height: auto; + margin-right: 1%; + text-align: right; +} +.ui-datepicker-cmd-current, +.ui-datepicker-cmd-today { + float: left; + width: 37%; + text-align: center; +} +.ui-datepicker-month-nav { + float: left; + text-align: center; +} +.ui-datepicker-month-nav div { + float: left; + width: 12.5%; + margin: 1%; + padding: 1%; +} +.ui-datepicker-month-nav span { + color: #888; +} +.ui-datepicker-row-break { + width: 100%; + font-size: 100%; +} +.ui-datepicker-group { + float: left; + width: 17em; +} +.ui-datepicker-group .ui-datepicker-header { + height: 1.5em; + text-align: center; +} +.ui-datepicker select, +.ui-datepicker-inline select { + width: auto; + height: 1.66em; + border: none; + font-weight: bold; +} +.ui-datepicker th { + padding: 0.5em 0.3em; +} +.ui-datepicker td, +.ui-datepicker td a, +.ui-datepicker td span { + border: 1px solid transparent; + text-align: center; +} +.ui-datepicker-status { + padding: 0.25em 0em; + text-align: center; +} +.ui-datepicker .ui-helper-clearfix { + clear: both; +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/AmharicDatePicker.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/AmharicDatePicker.tsx new file mode 100644 index 000000000..7f3b226f9 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/AmharicDatePicker.tsx @@ -0,0 +1,457 @@ +import $ from "@/shared/common/jquery-global"; +import React, { useEffect, useRef, useState } from "react"; +import { cn } from "@/shared/lib/utils"; + +// CSS and plugins +import "@/shared/common/css/redmond.calendars.picker.css"; +import "@/shared/common/css/ethiopian-date-picker-overrides.css"; +import "@/shared/common/js/jquery.plugin.js"; +import "@/shared/common/js/jquery.calendars.js"; +import "@/shared/common/js/jquery.calendars.plus.js"; +import "@/shared/common/js/jquery.calendars.picker.js"; +import "@/shared/common/js/jquery.calendars.ethiopian.js"; +import "@/shared/common/js/jquery.calendars.ethiopian-am.js"; + +interface CalendarsDate { + toString(): string; +} + +interface CalendarsDateFactory { + toJSDate(): Date; +} + +interface CalendarsInstance { + newDate: (year: number, month: number, day: number) => CalendarsDateFactory; + fromJSDate: (jsDate: Date) => unknown; + formatDate: ( + format: string, + date: unknown, + settings?: { localNumbers?: boolean }, + ) => string; +} + +interface CalendarsApi { + instance: (calendarType: string, language: string) => CalendarsInstance; +} + +interface CalendarsPickerOptions { + calendar: CalendarsInstance; + dateFormat: string; + onSelect: (dates: CalendarsDate[]) => void; +} + +type CalendarsPickerElement = JQuery & { + calendarsPicker: (...args: unknown[]) => unknown; +}; + +declare global { + interface JQueryStatic { + calendars: CalendarsApi; + } +} + +interface EthiopianDatePickerModalProps { + value?: string | Date; + onChange: (value: string) => void; +} + +const ETHIOPIAN_UTC_OFFSET_HOURS = 3; + +const toEthiopianTimeInput = (date: Date): string => { + if (!(date instanceof Date) || isNaN(date.getTime())) { + return "00:00"; + } + + const totalMinutesUtc = date.getUTCHours() * 60 + date.getUTCMinutes(); + const totalMinutesEthiopian = + (totalMinutesUtc + ETHIOPIAN_UTC_OFFSET_HOURS * 60 + 1440) % 1440; + + const hh = Math.floor(totalMinutesEthiopian / 60) + .toString() + .padStart(2, "0"); + const mm = (totalMinutesEthiopian % 60).toString().padStart(2, "0"); + + return `${hh}:${mm}`; +}; + +const getCurrentEthiopianTimeInput = (): string => { + return toEthiopianTimeInput(new Date()); +}; + +/** + * Ethiopian 12-hour clock parts. The Ethiopian day starts at 6:00 EAT, so EAT + * 6:00 AM is clock 12 (day) and EAT 6:00 PM is clock 12 (night). + * + * `period` is purely a display concern — the stored value is always derived + * from the EAT 24-hour time, so the backend payload is unaffected. + */ +type EthiopianClockPeriod = "day" | "night"; + +interface EthiopianClockParts { + hour: number; // 1-12 + minute: number; // 0-59 + period: EthiopianClockPeriod; +} + +const ETHIOPIAN_HOUR_OPTIONS = Array.from({ length: 12 }, (_, i) => i + 1); + +// EAT 24h "HH:mm" -> Ethiopian 12h clock parts (day starts at 6:00 EAT). +const eatTimeToEthiopianClock = (eatTime: string): EthiopianClockParts => { + const [hhRaw, mmRaw] = (eatTime || "").split(":"); + const parsedHour = Number(hhRaw); + const parsedMinute = Number(mmRaw); + const eatHour = Number.isFinite(parsedHour) + ? ((parsedHour % 24) + 24) % 24 + : 0; + const minute = Number.isFinite(parsedMinute) + ? ((parsedMinute % 60) + 60) % 60 + : 0; + + const hour = (eatHour + 6) % 12 || 12; + const period: EthiopianClockPeriod = + eatHour >= 6 && eatHour < 18 ? "day" : "night"; + + return { hour, minute, period }; +}; + +// Ethiopian 12h clock parts -> EAT 24h "HH:mm". +const ethiopianClockToEatTime = ({ + hour, + minute, + period, +}: EthiopianClockParts): string => { + const base = (hour % 12) + 6; // day window: 6..17 + const eatHour = (period === "night" ? base + 12 : base) % 24; + const hh = eatHour.toString().padStart(2, "0"); + const mm = (((minute % 60) + 60) % 60).toString().padStart(2, "0"); + return `${hh}:${mm}`; +}; + +const normalizeDigits = (value: string): string => + value + .replace(/[٠-٩]/g, (digit) => String(digit.charCodeAt(0) - 1632)) + .replace(/[۰-۹]/g, (digit) => String(digit.charCodeAt(0) - 1776)); + +const toEthiopianDateInput = (date: Date): string => { + if ( + !(date instanceof Date) || + Number.isNaN(date.getTime()) || + !$ || + !$.calendars + ) { + return ""; + } + + try { + const calendar = $.calendars.instance("ethiopian", "am"); + const ethiopianDate = calendar.fromJSDate( + new Date(date.getTime() + ETHIOPIAN_UTC_OFFSET_HOURS * 60 * 60 * 1000), + ); + + return calendar.formatDate("yyyy-mm-dd", ethiopianDate, { + localNumbers: false, + }); + } catch { + return ""; + } +}; + +const EthiopianDatePickerModal: React.FC = ({ + value, + onChange, +}) => { + const datePickerRef = useRef(null); + const pickerElementRef = useRef(null); + const isSyncingRef = useRef(false); + const lastSyncedDateRef = useRef(""); + const onChangeRef = useRef(onChange); + const initialValueRef = useRef(value); + const [selectedDate, setSelectedDate] = useState(""); + const [selectedTime, setSelectedTime] = useState( + getCurrentEthiopianTimeInput, + ); + const selectedTimeRef = useRef(selectedTime); + + useEffect(() => { + onChangeRef.current = onChange; + }, [onChange]); + + useEffect(() => { + selectedTimeRef.current = selectedTime; + }, [selectedTime]); + + useEffect(() => { + if (!(value instanceof Date) || Number.isNaN(value.getTime())) { + return; + } + + const nextDate = toEthiopianDateInput(value); + // selectedTime is stored as EAT 24h "HH:mm"; the Ethiopian clock shown in + // the picker is derived from it via eatTimeToEthiopianClock. Seed it with + // EAT 24h here so the picker (and the trigger placeholder) agree. + const nextTime = toEthiopianTimeInput(value); + + setSelectedDate(nextDate); + setSelectedTime(nextTime); + + if ( + !pickerElementRef.current || + !$ || + !$.calendars || + !nextDate || + lastSyncedDateRef.current === nextDate + ) { + return; + } + + try { + const calendar = $.calendars.instance("ethiopian", "am"); + const [year, month, day] = nextDate.split("-").map(Number); + if ( + Number.isFinite(year) && + Number.isFinite(month) && + Number.isFinite(day) + ) { + const ethDate = calendar.newDate(year, month, day); + isSyncingRef.current = true; + try { + pickerElementRef.current.calendarsPicker("setDate", ethDate); + lastSyncedDateRef.current = nextDate; + } finally { + isSyncingRef.current = false; + } + } + } catch { + // ignore third-party plugin errors when syncing selection + } + }, [value]); + + useEffect(() => { + if (!$ || !$.calendars || !datePickerRef.current) { + return; + } + + const pickerHost = datePickerRef.current; + const calendar = $.calendars.instance("ethiopian", "am"); + const picker = $(pickerHost) as unknown as CalendarsPickerElement; + pickerElementRef.current = picker; + + picker.calendarsPicker({ + calendar, + dateFormat: "yyyy-mm-dd", + onSelect: (dates: CalendarsDate[]) => { + if (isSyncingRef.current) return; + if (!dates?.length) return; + + const date = dates[0].toString(); + lastSyncedDateRef.current = date; + setSelectedDate(date); + onChangeRef.current(`${date} ${selectedTimeRef.current}`); + }, + } as CalendarsPickerOptions); + + const initialValue = initialValueRef.current; + if (initialValue instanceof Date && !Number.isNaN(initialValue.getTime())) { + try { + const initialEth = toEthiopianDateInput(initialValue); + if (initialEth) { + const [y, m, d] = initialEth.split("-").map(Number); + if (Number.isFinite(y) && Number.isFinite(m) && Number.isFinite(d)) { + isSyncingRef.current = true; + try { + picker.calendarsPicker("setDate", calendar.newDate(y, m, d)); + lastSyncedDateRef.current = initialEth; + } finally { + isSyncingRef.current = false; + } + } + } + } catch { + // ignore third-party plugin errors when seeding initial date + } + } + + return () => { + try { + picker.calendarsPicker("destroy"); + } catch { + // ignore cleanup errors from third-party plugin + } + pickerElementRef.current = null; + lastSyncedDateRef.current = ""; + }; + }, []); + + // selectedTime is always EAT 24h "HH:mm"; the Ethiopian clock is a display-only + // projection so the stored value (and backend payload) stays unchanged. + const ethiopianClock = eatTimeToEthiopianClock(selectedTime); + + const applyEthiopianClock = (next: EthiopianClockParts) => { + const eatTime = ethiopianClockToEatTime(next); + setSelectedTime(eatTime); + + if (selectedDate) { + onChange(`${selectedDate} ${eatTime}`); + } + }; + + const handleHourChange = (e: React.ChangeEvent) => { + const hour = Number(e.target.value); + applyEthiopianClock({ + ...ethiopianClock, + hour: Number.isFinite(hour) ? hour : ethiopianClock.hour, + }); + }; + + const handleMinuteChange = (e: React.ChangeEvent) => { + const parsed = Number(e.target.value); + const minute = Number.isFinite(parsed) + ? Math.max(0, Math.min(59, Math.trunc(parsed))) + : 0; + applyEthiopianClock({ ...ethiopianClock, minute }); + }; + + const handlePeriodChange = (period: EthiopianClockPeriod) => { + applyEthiopianClock({ ...ethiopianClock, period }); + }; + + return ( +
+
+
+

+ ሰዓት +

+
+ + + : + + +
+ + +
+
+
+
+ ); +}; + +export function convertEthiopianToGregorian(ethiopianDateTime: string): Date { + if (!ethiopianDateTime || typeof ethiopianDateTime !== "string") { + return new Date(NaN); + } + + const normalizedDateTime = normalizeDigits(ethiopianDateTime.trim()); + const [datePart, timePart = "00:00"] = normalizedDateTime.split(" "); + + if (!datePart || !datePart.match(/^\d{4}-\d{2}-\d{2}$/)) { + return new Date(NaN); + } + + const cal = $.calendars.instance("ethiopian", "am"); + const [year, month, day] = datePart.split("-").map(Number); + + if (isNaN(year) || isNaN(month) || isNaN(day)) { + return new Date(NaN); + } + + try { + const ethDate = cal.newDate(year, month, day); + const gregDate = ethDate.toJSDate(); + + const [hours, minutes] = timePart.split(":").map(Number); + + if ( + isNaN(hours) || + isNaN(minutes) || + hours < 0 || + hours > 23 || + minutes < 0 || + minutes > 59 + ) { + return new Date(NaN); + } + + const utcDate = new Date( + Date.UTC( + gregDate.getFullYear(), + gregDate.getMonth(), + gregDate.getDate(), + hours - ETHIOPIAN_UTC_OFFSET_HOURS, + minutes, + 0, + 0, + ), + ); + + return utcDate; + } catch (error) { + console.error( + "[convertEthiopianToGregorian] Error during conversion:", + error, + ); + return new Date(NaN); + } +} + +export function formatEthiopianDate(ethiopianDate: string | Date): string { + if (!ethiopianDate) return ""; + + if (ethiopianDate instanceof Date) { + const day = ethiopianDate.getDate().toString().padStart(2, "0"); + const month = (ethiopianDate.getMonth() + 1).toString().padStart(2, "0"); + const year = ethiopianDate.getFullYear(); + return `${day}/${month}/${year}`; + } + + const parts = ethiopianDate.split("-"); + if (parts.length !== 3) return ethiopianDate; + + const [year, month, day] = parts; + return `${day.padStart(2, "0")}/${month.padStart(2, "0")}/${year}`; +} + +export default EthiopianDatePickerModal; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateField.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateField.tsx new file mode 100644 index 000000000..28824a1c5 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateField.tsx @@ -0,0 +1,233 @@ +import { useState } from "react"; +import { Control, FieldValues } from "react-hook-form"; +import $ from "@/shared/common/jquery-global"; +import { FormField, FormItem, FormLabel, FormMessage } from "../../ui/form"; +import EthiopianDatePickerModal, { + convertEthiopianToGregorian, +} from "./AmharicDatePicker"; +import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover"; +import { Button } from "../../ui/button"; +import { cn } from "@/shared/lib/utils"; +import { format } from "date-fns"; +import { CalendarIcon } from "lucide-react"; +import { Calendar } from "../../ui/calendar"; +import { Input } from "../../ui/input"; +import { useTranslation } from "react-i18next"; +import { + formatEthiopianClockTime, + utcToEthiopian, +} from "@/shared/common/utils/ethiopianTimeZone"; + +interface DateFieldProps { + name: "startDate" | "endDate"; + label: string; + control: Control; + isEthiopian: boolean; + minDate?: Date | null; +} + +interface EthiopianCalendarFormatter { + fromJSDate: (jsDate: Date) => unknown; + formatDate: ( + format: string, + date: unknown, + settings?: { localNumbers?: boolean }, + ) => string; +} + +const DateField: React.FC = ({ + name, + label, + control, + isEthiopian, + minDate, +}) => { + const [gregorianTimeFallback, setGregorianTimeFallback] = useState( + () => format(new Date(), "HH:mm"), + ); + const { t } = useTranslation(); + + return ( + { + const getGregorianTimeValue = (): string => { + if ( + field.value instanceof Date && + !Number.isNaN(field.value.getTime()) + ) { + return format(field.value, "HH:mm"); + } + return gregorianTimeFallback; + }; + + const handleEthiopianChange = (ethiopianDate: string) => { + const gregorianDate = convertEthiopianToGregorian(ethiopianDate); + if (!Number.isNaN(gregorianDate.getTime())) { + field.onChange(gregorianDate); + } + }; + + const getDisplayText = (): string => { + if (isEthiopian) { + if ( + field.value instanceof Date && + !Number.isNaN(field.value.getTime()) + ) { + const ethiopianTime = utcToEthiopian(field.value); + const timeStr = formatEthiopianClockTime(field.value); + + try { + const ethiopianCalendar = $.calendars.instance( + "ethiopian", + "am", + ) as unknown as EthiopianCalendarFormatter; + const ethiopianDate = + ethiopianCalendar.fromJSDate(ethiopianTime); + const dateStr = ethiopianCalendar.formatDate( + "yyyy-mm-dd", + ethiopianDate, + { localNumbers: true }, + ); + return `${dateStr} ${timeStr}`; + } catch { + const fallbackDate = format(ethiopianTime, "yyyy-MM-dd"); + return `${fallbackDate} ${timeStr}`; + } + } + return t("delegation.pickDate"); + } + if ( + field.value instanceof Date && + !Number.isNaN(field.value.getTime()) + ) { + const dateText = format(field.value, "PPP"); + const timeText = format(field.value, "HH:mm"); + return `${dateText} ${timeText}`; + } + return t("delegation.pickDate"); + }; + + return ( + + + {label} + + + + + + + + + {isEthiopian ? ( +
+ +
+ ) : ( +
+ { + if (!selectedDate) { + field.onChange(null); + return; + } + + const [hours, minutes] = getGregorianTimeValue() + .split(":") + .map(Number); + const nextDate = new Date(selectedDate); + nextDate.setHours(hours || 0, minutes || 0, 0, 0); + field.onChange(nextDate); + }} + initialFocus + className="w-full p-2" + disabled={(date) => { + const startOfToday = new Date( + new Date().setHours(0, 0, 0, 0), + ); + if (date < startOfToday) return true; + if ( + minDate instanceof Date && + !Number.isNaN(minDate.getTime()) + ) { + const startOfMin = new Date(minDate); + startOfMin.setHours(0, 0, 0, 0); + if (date < startOfMin) return true; + } + return false; + }} + /> +
+

+ {t("common.Time", "Time")} +

+ { + const newTime = event.target.value; + setGregorianTimeFallback(newTime); + + if ( + field.value instanceof Date && + !Number.isNaN(field.value.getTime()) + ) { + const [hours, minutes] = newTime + .split(":") + .map(Number); + const nextDate = new Date(field.value); + nextDate.setHours(hours || 0, minutes || 0, 0, 0); + field.onChange(nextDate); + } + }} + className="h-10" + /> +
+
+ )} +
+
+ + +
+ ); + }} + /> + ); +}; + +export default DateField; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateTimeField.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateTimeField.tsx new file mode 100644 index 000000000..7b51b0341 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/DateTimeField.tsx @@ -0,0 +1,242 @@ +import { useState } from "react"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../ui/form"; +import EthiopianDatePickerModal, { + convertEthiopianToGregorian, +} from "./AmharicDatePicker"; +import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover"; +import { Button } from "../../ui/button"; +import { Input } from "../../ui/input"; +import { cn } from "@/shared/lib/utils"; +import { format } from "date-fns"; +import { CalendarIcon, Clock } from "lucide-react"; +import { Calendar } from "../../ui/calendar"; +import { useTranslation } from "react-i18next"; +import $ from "@/shared/common/jquery-global"; +import { + formatEthiopianClockTime, + utcToEthiopian, +} from "@/shared/common/utils/ethiopianTimeZone"; + +interface DateTimeFieldProps { + name: "startDate" | "endDate"; + label: string; + control: any; + isEthiopian: boolean; + isEditing: boolean; + fieldValue?: Date | null; +} + +interface EthiopianCalendarFormatter { + fromJSDate: (jsDate: Date) => unknown; + formatDate: ( + format: string, + date: unknown, + settings?: { localNumbers?: boolean }, + ) => string; +} + +const DateTimeField: React.FC = ({ + name, + label, + control, + isEthiopian, + isEditing, + fieldValue, +}) => { + const [ethiopianDisplay, setEthiopianDisplay] = useState(""); + const [showTimeInput, setShowTimeInput] = useState(false); + const { t } = useTranslation(); + + return ( + { + const handleEthiopianChange = (ethiopianDate: string) => { + setEthiopianDisplay(ethiopianDate); + const gregorianDate = convertEthiopianToGregorian(ethiopianDate); + field.onChange(gregorianDate); + }; + + const handleTimeChange = (hours: string, minutes: string) => { + if (field.value) { + const date = new Date(field.value); + date.setHours(parseInt(hours) || 0, parseInt(minutes) || 0, 0, 0); + field.onChange(date); + } + }; + + const getTimeString = () => { + if (!field.value) return ""; + const date = new Date(field.value); + const hours = String(date.getHours()).padStart(2, "0"); + const minutes = String(date.getMinutes()).padStart(2, "0"); + return `${hours}:${minutes}`; + }; + + const getDateTimeDisplay = () => { + if (!field.value) return t("delegation.pickDate"); + const date = new Date(field.value); + if (Number.isNaN(date.getTime())) return t("delegation.pickDate"); + const timeStr = isEthiopian + ? formatEthiopianClockTime(date) + : getTimeString(); + + const dateStr = (() => { + if (!isEthiopian) return format(date, "PPP"); + if (ethiopianDisplay) return ethiopianDisplay.split(" ")[0]; + + try { + const ethiopianCalendar = $.calendars.instance( + "ethiopian", + "am", + ) as unknown as EthiopianCalendarFormatter; + const ethiopianDate = ethiopianCalendar.fromJSDate( + utcToEthiopian(date), + ); + return ethiopianCalendar.formatDate( + "yyyy-mm-dd", + ethiopianDate, + { localNumbers: true }, + ); + } catch { + return format(utcToEthiopian(date), "yyyy-MM-dd"); + } + })(); + return `${dateStr} ${timeStr}`; + }; + + return ( + + + {label} + + + + + + + + + + +
+ {/* Date Picker */} + {isEthiopian ? ( +
+ + + +
+ ) : ( + + date < new Date(new Date().setHours(0, 0, 0, 0)) + } + /> + )} + + {/* Time Picker — Ethiopian mode uses the Ethiopian-clock + picker inside EthiopianDatePickerModal above, so this + Gregorian-local time picker is only shown otherwise. */} + {!isEthiopian && field.value && ( +
+
+ + +
+
+
+ + + handleTimeChange( + e.target.value, + String( + new Date(field.value).getMinutes(), + ).padStart(2, "0"), + ) + } + className="text-center text-sm" + placeholder="00" + /> +
+
+ : +
+
+ + + handleTimeChange( + String( + new Date(field.value).getHours(), + ).padStart(2, "0"), + e.target.value, + ) + } + className="text-center text-sm" + placeholder="00" + /> +
+
+
+ )} +
+
+
+ + +
+ ); + }} + /> + ); +}; + +export default DateTimeField; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/EthiopianDatePicker.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/EthiopianDatePicker.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/FormFields.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/FormFields.tsx new file mode 100644 index 000000000..d2a0e58a3 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/form/fields/FormFields.tsx @@ -0,0 +1,806 @@ +import React, { JSX, useRef, useState } from "react"; +import { Trash2, X, ChevronDown, Search } from "lucide-react"; +import { useTranslation } from "react-i18next"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../ui/form"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../ui/select"; +import { MultiSelect } from "../../ui/multi-select"; +import { Input } from "../../ui/input"; +import { Button } from "../../ui/button"; +import TreeView, { TreeViewItem } from "@/shared/common/ui/treeSelect"; + +import { Controller } from "react-hook-form"; +import { SingleSelect } from "../../ui/single-select"; +import { useLocalizedName } from "../../localizedName"; +import i18next from "i18next"; +import { getCheckedLeafNodes } from "@/record-management/components/userRecords/common/treeUtils"; + +type BaseSelectOption = { + label: string; + value: string; + unitId?: string; +}; +interface CustomSelectProps { + form: any; // your react-hook-form instance + name: string; + label: string; + placeholder: string; + options: { id: string; name: { en: string; am: string } }[]; + localizedName: (name: { en: string; am: string }) => string; +} + +// 1️⃣ Form Select Field +export const FormSelectField = ({ + control, + name, + label, + options, + placeholder, + className, + customLabel, + disabled, + onCustomChange, +}: { + control: any; + name: string; + label: string; + options: BaseSelectOption[]; + placeholder?: string; + className?: string; + customLabel?: React.ReactNode; + disabled?: boolean; + onCustomChange?: (value: string) => void; +}) => ( + ( + + {customLabel ? ( + customLabel + ) : ( + + {name === "headerId" || + name === "footerId" || + name === "recordType" || + name === "initiationType" || + name === "initiatedAs" ? ( + + {label} * + + ) : ( + label + )} + + )} + + + + + + )} + /> +); + +export const FormSingleSelectField = ({ + control, + name, + label, + options, + placeholder = "Select option", + onCustomChange, +}: { + control: any; + name: string; + label: string; + options: BaseSelectOption[]; + placeholder?: string; + onCustomChange?: (selectedValue: string) => void; +}) => ( + { + const handleChange = (value: string) => { + field.onChange(value); + if (onCustomChange) onCustomChange(value); + }; + + return ( + + {label} + + + + + + ); + }} + /> +); +// 2️⃣ Multi Select Field +export const FormMultiSelectField = ({ + control, + name, + label, + options, + placeholder = "Select options", + maxCount, + disabled, + onCustomChange, +}: { + control: any; + name: string; + label: string; + options: BaseSelectOption[]; + placeholder?: string; + maxCount?: number; + disabled?: boolean; + onCustomChange?: (selectedValues: string[]) => void; +}) => ( + { + const handleChange = (values: string[]) => { + field.onChange(values); + if (onCustomChange) onCustomChange(values); + }; + + const fieldValue = Array.isArray(field.value) + ? field.value + : field.value + ? [field.value] + : []; + + return ( + + + {name === "toPositions" || + name === "toEmployees" || + name === "collaborators" || + name === "receivingDepartments" || + name === "assignedEmployees" ? ( + + {label} * + + ) : ( + label + )} + + + + + + + ); + }} + /> +); + +export const FormTreeSelectField = ({ + control, + name, + label, + options, + handleCheckChange, + collapsible = false, + localizedName, + selectedCountResolver, +}: { + control: any; + name: string; + label: string; + options: TreeViewItem[]; + handleCheckChange?: + | ((item: TreeViewItem | TreeViewItem[], checked: boolean) => void) + | undefined; + collapsible?: boolean; + localizedName: ( + name?: + | { + am: string; + en: string; + } + | undefined, + ) => string; + selectedCountResolver?: (value: unknown) => number; +}) => { + const { t } = useTranslation(); + const [isOpen, setIsOpen] = React.useState(!collapsible); + const containerRef = React.useRef(null); + + // Close dropdown on outside click + React.useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if ( + containerRef.current && + !containerRef.current.contains(event.target as Node) + ) { + setIsOpen(false); + } + } + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + if (collapsible) { + return ( + { + const selectedCount = selectedCountResolver + ? selectedCountResolver(field.value) + : getCheckedLeafNodes(Array.isArray(field.value) ? field.value : []) + .length; + + return ( + + + {name === "receivingUnitIds" ? ( + + {label} * + + ) : ( + label + )} + +
+ + + {isOpen && ( +
+ +
+ )} +
+ +
+ ); + }} + /> + ); + } + + return ( + ( + + {label} + + + + )} + /> + ); +}; + +// 3️⃣ Addable List Field (string-based) +export const FormAddableList = ({ + form, + name, + label, + placeholder = "", + valueAdapter, +}: { + form: any; + name: string; + label: string; + placeholder?: string; + valueAdapter?: { + getDisplayItems: (fieldValue: unknown) => string[]; + onItemsChange: (items: string[], fieldValue: unknown) => unknown; + }; +}) => { + const { t } = useTranslation(); + const [pendingValue, setPendingValue] = useState(""); + + return ( + { + const items = valueAdapter + ? valueAdapter.getDisplayItems(field.value) + : Array.isArray(field.value) + ? field.value + : []; + + const handleAdd = () => { + const value = pendingValue.trim(); + if (value && !items.includes(value)) { + const updatedItems = [...items, value]; + field.onChange( + valueAdapter + ? valueAdapter.onItemsChange(updatedItems, field.value) + : updatedItems, + ); + setPendingValue(""); + } + }; + + const handleDelete = (index: number) => { + const updatedItems = items.filter( + (_: string, i: number) => i !== index, + ); + field.onChange( + valueAdapter + ? valueAdapter.onItemsChange(updatedItems, field.value) + : updatedItems, + ); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + e.preventDefault(); + handleAdd(); + } + }; + + return ( + + {label} +
+ + setPendingValue(e.target.value)} + onKeyDown={handleKeyDown} + onBlur={handleAdd} + /> + + +
+ + {items.length > 0 && ( +
+ {items.map((unit: string, index: number) => ( +
+ + {unit} + + handleDelete(index)} + /> +
+ ))} +
+ )} + + +
+ ); + }} + /> + ); +}; +export const ClearableSelect = ({ + form, + name, + label, + placeholder = "", + options, + localizedName, +}: { + form: any; + name: string; + label: string; + placeholder?: string; + options: { id: string; name: any }[]; + localizedName: (name: any) => string; +}) => { + return ( + + {label} + ( + <> + {field.value ? ( + // Selected value with X to clear +
+ + {localizedName( + options.find((o) => o.id === field.value)?.name, + )} + + field.onChange("")} + /> +
+ ) : ( + // Select dropdown + + )} + + + )} + /> +
+ ); +}; + +export const CustomSelect = ({ + form, + name, + label, + placeholder, + options, + localizedName, +}: CustomSelectProps) => { + const { t } = useTranslation(); + return ( +
+ + { + const matchingOption = options.find((opt) => { + const english = opt.name?.en ?? ""; + const amharic = opt.name?.am ?? ""; + return ( + field.value === opt.id || + field.value === english || + field.value === amharic + ); + }); + + // Treat undefined, null, and empty string as no selection + const hasValue = field.value !== undefined && field.value !== null && field.value !== ""; + const resolvedValue = matchingOption && hasValue + ? matchingOption.id + : ""; + + return ( + + ); + }} + /> +
+ ); +}; + +export interface TreeViewItemO { + id: string; + name: string | { en: string; am: string }; // allow localized or raw + value?: string; + children?: TreeViewItem[]; +} + +interface SimpleTreeSelectProps { + label: string; + options: TreeViewItemO[]; + value: string | null; + onChange: (id: string | null) => void; + collapsible?: boolean; + localizedName?: (name?: { en?: string; am?: string } | undefined) => string; + className?: string; +} + +export const SimpleTreeSelect = ({ + label, + options, + value, + onChange, + collapsible = false, + localizedName, + className, +}: SimpleTreeSelectProps) => { + const [isOpen, setIsOpen] = useState(!collapsible); + const [expandedItems, setExpandedItems] = useState>(new Set()); + + const toggleExpand = (id: string) => { + const newSet = new Set(expandedItems); + if (newSet.has(id)) newSet.delete(id); + else newSet.add(id); + setExpandedItems(newSet); + }; + + const handleSelect = (id: string) => { + onChange(id); + // Optional: close dropdown after selection + // setIsOpen(false); + }; + + // Get full path for a selected item + const findSelectedPath = ( + items: TreeViewItemO[], + parentPath: string[] = [], + ): string | null => { + for (const item of items) { + const name = + typeof item.name === "string" + ? item.name + : (localizedName?.(item.name) ?? item.name.en); + + if (item.id === value) { + return [...parentPath, name].join(" / "); + } + + if (item.children && item.children.length > 0) { + const childPath = findSelectedPath(item.children, [ + ...parentPath, + name, + ]); + if (childPath) return childPath; + } + } + return null; + }; + + const renderTree = (items: TreeViewItemO[]): JSX.Element[] => { + return items.flatMap((item) => { + const hasChildren = item.children && item.children.length > 0; + const isExpanded = expandedItems.has(item.id); + + // Determine if any child is selected to highlight parent + const isParentSelected = hasChildren + ? item.children!.some((child) => child.id === value) + : false; + + // Skip single-unit org + if (hasChildren && item.children!.length === 1) { + return renderTree(item.children!); + } + + const itemLabel = + typeof item.name === "string" + ? item.name + : (localizedName?.(item.name) ?? item.name.en); + + return ( +
+
+ {hasChildren && ( + + )} + + +
+ + {hasChildren && isExpanded && ( +
{renderTree(item.children!)}
+ )} +
+ ); + }); + }; + + const selectedPathLabel = findSelectedPath(options); + + return ( +
+ + + {collapsible && ( + + )} + + {isOpen && ( +
+ {renderTree(options)} +
+ )} +
+ ); +}; + +export const SelectedItemsChips = ({ + items, + onRemove, + label, + localizedName, +}: { + items: TreeViewItem[]; + onRemove: (value: string) => void; + label?: string; + localizedName: ( + name?: + | { + am: string; + en: string; + } + | undefined, + ) => string; +}) => { + if (!items?.length) return null; + + return ( +
+ {label &&

{label}

} +
+ {items.map((item) => ( +
+ + {localizedName(item.name)} + + +
+ ))} +
+
+ ); +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-blue.gif b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-blue.gif new file mode 100644 index 0000000000000000000000000000000000000000..601cbd55d9bcdc311d51fa1feb74c66a9cc51a51 GIT binary patch literal 969 zcmZ?wbhEHb6ky{$(isryP37Ao`R|(nXK# zTcHK_Ldza9bo^tO_AjaFMPBRcyxw=!(?500{W5j&w^KL&J$d@?$-93aKmYsx```aR z|Nj5~4>WibjE2DA4*?yJ6G3@_fnyzmCWC;7fI~|oho(Zr0Y=Be?R@M70tOeESh(qDjv%sCU!o7yk|#tCNj71NHX1ca^OK) z;38Yelnn|cOw6nT^W175JZNZK;Z&M+_klw*8?(3uOGm<$jPuM=1|mBG64wN;2$GaA z2w1=nw#mZs2MgCj6&CK?k47F`Qx1BvHQaRyFi0#+KGv;iAR)bA)6>&4n3))?0d)&? ATL1t6 literal 0 HcmV?d00001 diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-green.gif b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar-green.gif new file mode 100644 index 0000000000000000000000000000000000000000..9dae1a3b26b411f683e337db9663bdcedbbffec0 GIT binary patch literal 934 zcmZ?wbhEHb6krfw_|CwP`z|$jZ{Yv`|C8^=#O;ZE{r}bfzkmOI`x?D6{NeBWJ*(aq z&wC%$_1v=X-v2*;{(kysn0bz26pV(za0vm$pDc_F41x?gAP<4^1OrDi10#!oN5KL| z1`bv(h7B7O4>K}xxTwt7u;?g*1b4=r3`50Z{R+-aA_@u&o|9F1B{&KmFfdIq@L!cO z^TAS&9xgG1jE0X-PtIo(vnaT*z=2`DYN}Mig9nT(i_P-QG8h=0&d<<}X1gGva4>L& e@z$cRQeV?fOy{_?D)zKl)9vjAkKH&p7_0%?omv3^ literal 0 HcmV?d00001 diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar.gif b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0abaa7c0b892e781b6f553453a0027efea014b9 GIT binary patch literal 269 zcmZ?wbhEHb6kyoJ#dt% zaYstuiRe5}O|8;NEA%ba6j)5k7TbN(gNwC&D)Y{1Cu2PhDy(ymnp7_1Ai(k{X>FbJ zg$yQ1aX#U+v{)u7c4kS5=DdO;0Y*k<=8BdGnYaWYcOkak83LIJ0`39}`h<8zSFc^O QT3n!+Z|k=0I}{nL0T`orxBvhE literal 0 HcmV?d00001 diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view.png b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view.png new file mode 100644 index 0000000000000000000000000000000000000000..2660a22897b4788c08e6411e43d64544392ec619 GIT binary patch literal 10259 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 h6YKv!6W4T0_9VwG-{Igc0| z99$h$FPs10FD|=ZtK9&;PglmOA!?i5;odE}TiT$iRYCR0X1`ECW7=`IZ4PeF<38=& z3!&^e51>9?uiEyvxJUbFJR@5?_(OsD_!R@s<^1mZ^R;+R3=PCH(8q;J-J5^Xj4YbMHdX7c!3)pS8Qn>`=uodUCq|@gzdN5a@(j zDt__)9x*9ea%Irg=d?4(V~%zHP^{>;?z8!prd6GbP{(3uw>!Gc)9T*Rnpo2L2^H;# zclDdKUFcHxYX2C~jwZB2*x>{r@;e_K>+nz9=r(p5?i&Vb4@r*E`wzs;&d=*`Q95h{ zx=US&G~4bUg#$bs;n2kQ&y(}E7IAA&i{o(lJyZSUR`Tmy*OZX2@eW5H)kFiRM5bS& zsYlg4Kg*4pG#YlvtuX1FKiA4KwC{GqC&l|(F>XZwn975f_ubHMK5u*|m&uM!m$SBc z!Wo&bXL#-L_<1BK*Hn(`6Ox*X;dGyCxOfF&vZiJa>d1$CyAOEJN2W&fnVBErCD?{eGt}t99YL zCvj#$r}rKaEAsKe9=F8m+G<$HA0U3a4$(ro(=_tk*Q@8Qx98O?|1);FhV&rf?gF## zZ2H!l4%RYc1saTH(`eSDe_onOZaonVws^M)?%LiMiK@*!Pb_hq0bQ|jlr--us-V*s z_Yw97TbI_r?nLtMqAsY(A;AoZThqB$EM=Tf;Wv*bsm9e<;CPMPK(aGYsW$>0mOD9K zA;r>+U~+9eA5;B6k0to0`Y0~m{(A>Vus^1DUwxb-G99bkxwzO1N(Oku{*pS6cVXmr zM3)If8}yDtb6|Zpgm;|U@};<`IWWw>mZD8)y?GE^XB9tzvWKXPmp3b9fQ8na75X$t zeR_bMZOwXykqd=rfwinPoY2-B(v+X^TL0te?D0*nFuA77gZ&n(z0Vu^r^oaifoz!Q zmk$_L-j?2ZMIxGHnV~JC#QU}A;hDi*9?2M1_GvvMXBD#9wRWCRq4h6TUJPm51S?D= z&zgRW^-fz6U*HBTKA>@WzKIp8n5bNl26!gQuc5ON18}DF|N3ov#q>?QFQQTeeQ6b@ zeA39o6~IRjYDDzl8yB@ZxEb$!MO(Ljt^KP|1fS9QIn`$`uzIwqOQdWrQ=S4P_ro)6 z@%$C!u@vI;W7kwtxZ33Xz1YpDR&xDK13|y6ogBQAFBnCu>u;GuKF2Hk?nN=mcx8CEF+! zUKqHGb6|8dBAWt6xML?9vPScZJzLx6P_g3mYE0kZgsQ--V1LWjI^zXuR~2N9xMvg@ ziVZnm@GAm!w=Xl>QT(exXNLB`so6!#gMUWgaU{yu4b_QGbf$IEwU@DF=56clT3)Ki@FbrJGh>&PW62@ile^*_7? zgKNV;Lqp>P3(+3tC>`_tU!O%%^6p&t0}~kg zV!^+8%}t*}f%@lxkvNtWZo&MoPqY%+_jRTJ8qWYqmK1yMV)|W{Tm-Uz?L5!ID<~<7 zY2LehRmf7vm{Wgv{rT_jkDl_tH*+igKM~ZaKgY1biDqc zBlkqHWKpP{J}$+*KG{IWh~&u0%_Yz6?hW@LZ;SSu5?*3?_rVkyX#y5z`$b-LJo0`m z5+&{Gx1*NeyC#yR5PZEFQ%gPgPV`klK_TTc542)oL&+y!2uobtr>kSk?vxq#>w9wa zuyIbWDx_G=7kH+;NNV{#-zRKt9v<}45@cD&!^dMNy(G&(RO!pBi+6Mk(x3jqx>zIX z(!{cketeLM^DL2w@e;%BxiTp{?Qqzh#?}!#KwEdAbrU zy26Dg;PizFbZ0^HD`jMq2c{ZG%hFH>PLS;G{6v&CseZk~nK!BMUI>{)bk3gF${pL7 zpX?3}p%Ly3iu85sr}phJ+!V%?(S1ZR9(DH}uiZ@2WIeeUOAQi@vp0)CR4F+0DU z^ShH2u1y1E>$c(I;VUiQ=a1wmV*aE@I|=58S{K2s#Acx#l0FALHYBr6wqF6bEH?!F zxz*dY9MvjE46i=4cPYrn~F!>($cg2M=Tob>QXp$ zNk{ogRN-^+N3NtGw6 zchA2;L>9Mb<>s2fyCPJ0?mxS^A*hyG3uODk%nyhQEGU{@|KTSh?h=1GV4_*xN)m8$ z4spM<&M6Vzo-bp4y4!)Uyz}n#y~kkrJ%DFzEWCx~^rm%2vA-%)i(sAgd#XkYj=1!f zCNJZ2ST|YSvw~b&`w`ljxMcbvXrSQ3;vfhP_0 z6WzG4F8$w6wV*ccTsqf%81QgP`5FD;3Zd^DD zRp#aY+W(Cru%Us2>Mv!d|Mbf@Yl6GimStB(T%F`%n#w32U((HOEHYN}=ok2NQzm-KO(Qs}b^}emGxyy66~vN%30<(M%fb zqn)WS2*hzuwS{Q6F8`skP2iEigTI4`aoO*YjrMVK@XN=^dZCe?Vwi&|?Yd5058+rn ztyTJ3L1JbOzTgXIWxgXGD9$SO(@^|KN8PDBeL;{GJ+F7Uq%f1ODqp5X& zS2Fn~p)m({_mht87Fv25`qX?O#gZQ9b}LS4=UJD%3c|7`58ItuA#!vZ!m(U7Mrc8_ zbM+H#s!9GtXrx1E*27a#MZWS52n4qJzH)zDlYXMtxVxRGzQAj4@)wCJ3IX{OYdK4R z!0@jMH8dgI`>#E>GFcX{zIQ7f6qqW`F;jB16_(V({88G@q&+2Ug0DoZK=?@i$I6iq z4`PDFX&xj{Oei(lefBn1@#pKmjSTmAQVF-*9T9)YrJ_qR@C~!fHVMl|wTP#}$hTKA)j0$9 z(h`O8)V<7wTB?4HIiX?a(x!3|<6#6O`t&l+(~+E%UVqQAc52pgYa(+lqsmLaj+Gy6 z+I~qHdYxSP{k@i8W10tqpG!lOtoM;EIHekr<0q&dr>j`+!m)owzbUj*A<@(2#bIcx z;z|~EsV4n(6_YSZ-o1YuEHx`ysdH$kzi%yu{B9 z<*hpb4u*H8{G#k+Iz5`wjjc>;_<9@hWQU$yT#QFt#p3a2-LG341m@g$p22UBN8#DM zE;=W+9FdWCK*kIyS~9n6UoReJEpZIVuI+g*j~FHSqNgBpegsvm->xR7=B^q)KS=w1 zHAf&<%}d!eV}HmievlNqhl`*nkFKh-Tuj;Q0vq#uzQ zWU{fdN0wVUNe4(j|+XB!Ejxur>eR^P$`uyvY*^DPw<8312D3*vV1m30^7{ApnKq*UInjlFL0z~zZtc9!;?G$Y zMcn*_Qkb^5KEn@9uQ4!o`GKxB8sg_{V3oM<8%dp-pv8wlttdZVRXU)3s@MCIY>au8 zz9c*K4CV!}A0%t{O|g|MZt3UXV%~&R*qpK~(MnOIEQS$NcV^HjtFy}KIakLNRYuAK zwW9h%<;4o4j0->5HYSGg?;;Un#+PTBfW2W8T=J#np`QaASJZV3E2J!npO^lX3jbuGN8xEAOATvG&}SX|F=?+R;9(u_7)hAb^>l zX5;6NJ|5M}k2|4Z;}S$%VkE%L2l(pD0epD_SDYZ;JQ*#sJubW=C$B(A8G8MuBd?L} z!l;;Ol$8fPC@4?s)R=i>W6bkgK{1o<-3J?lOM@Mc(gnwqM8vba9Zv%&-~cCiN>H+8 z${t0Jj_&uI&|7L&98gO%kdD~t9!W8diS@Jx*8MZoJ_prB_T;U_uYlTbGt!dvI!!6M z9-bw^19!;#*g$@!hBsPx$?rQ!)ErW0lM^>;kwY3rTP~t)e0dd)@Gji%{pwN zV~#JWYP5&DTcC1&x8A3KV%`34;8_PMwXnu^X3=~VW@ikT&8|<$W+>2P*zlD#%5mx))9NL~M6zDyo7&ibvIooM30-%2w~7PO zCkTS+GEj))iXH6KTTu42M3Hf81sB<+wkRuOxBt?|ne841#v82-du*(ef2DNhho;;K zHV{72C@H*!_CH1@H}lP^aZXtv{mV`!UH%W(lM*xjN)Mjg3+>HvO%vfqsLF0LXnCW#fqK{*j7xJWieCvVp^6 z$wYBgDO!+Lk>`JM&T#HvBm)R)5Q4OdGcvM<8tMJZvN=-`aCdg8cz-8X6VOi&@oCig|IA1t`!WAf45t6Zh0G|IGBfc(vnsSVlf4+ji#EF9QW^NEeb26lEtb zub{mISeNHVdl#+c0_VX8OE>?*^57YZY+w!$JlvGz_7+h~ORINo4nu$hHSN$|a;?F| z3F#$d=p(H7{#||srq+0Br}wQB(xq8rJPEkI3g3Oh^doX3^zg&)cJxnO7;s!KxyMfc zwu{R!`>L7xthD|Kfy{e`LEe!>cbNX?G^?}U89j5bJ@~73bxXCAmq$SG9#*}kq08si zR^ODL4j!DL>asS2m<<;&EHst*jATwG*Yf&W?(U}BVCO{cF1$iMr)*vZR2shcD~8vS zeaqmp`?>60#yENDy+(A1n^w!F`NH9X$Ow0KX7afW2K!2GSH;xm#x;Ypr|!VJz4Enp z^jTUXzoE5rBDSRB*3^z!O(@Ksn-KAN-^H$E0Frp+)xiDeA~MF?01Pk#eBho zg?(KX<^^~3_7Mn?F0B(j${2oo6CiToo|vc#uo!G-!s971)`cVg0S$Jvd_Pfl<4Atb zRW@Bl=t7-u|Fv!Pkf+w)CkQi3>g0xUN?BRtvU)+Jmb)^y9>81{I>UeuPC00Y3Th!``t)mbiIsvj$M1C%O!;ZDdUfYD)bu6p88NTle6jHJyCG{ug$!R zC5RW3o)69_+fgVH5li5GBUp(UIkoWnSq$P4-zRW+zDh``^Whpq`&7GV@f%6MN)zaE z(eDYk>HK7Ce&#yM*V{FHfa)NW&&Y2ucJPDd=NxZbF|EX|OR$qC&+(aP@-#KDlKz`> z8pT}c0a37m8-Ay8juSTt>F{P4Cc)8Ul~B?G2;s*yO2^O~#xQqEdFl{p?_G*dFK`!d zTDEgyvftrF1T#$Bv>%vrM%Vx|{g>Z8OXSQ*rEmVutMC|9T85w%vydrX- z>1sE1C;;Ap$yOqGl`ghrm5!QZf6eBz&VF0X`jp^ zoZ6}!ET0~xT4tlukkfU@N}2ApFzW6-_h=?bdo8}5CJC!(dz3g&X_t}a!|SiG(B}(HK<1J7YA-ynt42ZVYqiEdjom*tTjN%oh!!XOs3|xjz z-7pNWcL2BTs6^Z|MR;9OfMBlIv)4i>0mQz`;3lcjPcR!%qxFOPMlC!`e?0bB%=5vz z7?s#16#Fq5wN%#3g8NCj(h-Z4$XcQ>zS8SiG{}%%QZ)Jpje{1De|Cs2bMI7nzQ^eu zTBCWyTWCE)TP9=KvwNzJQ|?>ma|=gQmY`JTK`WlQc4c4Z<&gXWs znQJ6!K*4F4|3-8uP&tT7ChvFvy#&}B6;HploDy|%uIc6G2v2=?oiYcsMTbhorUUlw z_t9SY39nKpMb;qPlxo2Ab|eHu9pFr@Z4I>A4RWEjwRQTY;HP)_K0oGgP*l^Op4dZ~ zGdD+L>`4e=X=M!a_U^90!pn|$g$4VLJ#o^H%6R!k+dkq@A}Jn6PvJ|Al4J`$K3O^=Ob<6%ZZZNo8IB3K9}SwBJSCi>|u zOU(GurgiU(J&Ga2dER9~BgijpTborBL58?D!G)dq9|*2ZvoF8NbOs}6{5S9KufgP- zLGh8vD4h_h2;R+M4~n#=I-yHp?`|J2JbYNDAv*7Dhv4w&knM7%SHlYT^_5?Xo?|GR zbmqn>O)*PTZp{a*%~=i4w}Clyc_=dY%b*2CvrDTvC^`lDRMvVBT7#{;uVB5wzP%q7(S}J_hZrxQNy`PE8k9M_K9bTw0KpVbDBCD2ij`#Ao?JPvI{p^dA4*UsP@jlPc@Jxb}6LiE!YOI8L&E&k<@hZ z(>Qik*Y07b^P)imhyqpp@EK8PrY@aWhzM+51~nw+0uF-gQSyRageEU-y)1h945CeT500jGpypKT3kTTciQ`uZJoi4HFU@0UJP<7|hef@&ad4Pa zM6%Q^{8r&}hZ1(8b}06A7j-(c9 zf$E@R%2z|SNEA-JZ3(LR=xo008aAWxQ`$h?o*!Uux7xi&P zuT*gYnP2<(LhrO4hJVGIssc&%u@$_U#PDjKlS`I8=!k0id3nu;14XJyQPYhYCPByQ zBqURx=?5>1ef}3GW{|hHB#Y9o*vF91mDl~q->m-ET>u;QmOh;gLrHD$X0DtxE&&j1 zRT+PK;(x-%BX5Q%5_e)gs;}E+Y`QaBn9m|vzMRB8PFx!U0V!x6)j*n&WUembF z`rEbF#=-)IJI|G+&c!}KB1L;9Wg!J&XL(oES`IzYK9uD|I43i+uit_En_4_yB~gPe zgYr+$@;ELQHmFF%NW&^DL_CeQqF>leu}j>nfbnn$Td7a~Q@Yy-dZU=R}GKY*9YA|GQHPntv z2i>~hhjJFW$l{3JI~h?+Q0BfzjL(}Akq~WfZ-aI4i|OE8VV4tg2OIgpmd6`9-?PUC zr@oDPlkgu`=pn2+K*B3<8noEp)ui)mPXyMNd)yN88cl103GIIIjoRBlo>)8FUf~1t z^@_rL0V~ALeBVVehU_~qCT`o~phzE9FZT!m12Aa(q4RGIsnQk=)&Od-2sh078Ucw~ zEIa?ai_C!68gDiPVNYY=9A>xdMEw7DA|;{$*jQZ^V@N&mu(P*UpF2x4%%!lbtC%<2 zT3t1<&D-#C71LeIwQX*02GLM}{p26(dUuE&G=M!Ri0AFE)`MzZLiLmHuL^;VmPVS) zHOodf;X}knntVa0RtdJ_)k?`-m~i0h&UVnrOU7D#q z{K^e%(;T*PXc*6rEx`Dd;O?x5C+e`q z_`HVCom$g&?yD(lyO1xRhz*AL!`LuDr+jU0t00N+jyOAwX3D`gjgU3MM(gY|#9r|7Pp~fVx(nhSd(ID88(gK-dpfKiMzu`(<)IK`K zk|q2nMc_ZFUGK{Q=_zQc^6B4@Fhhrbg-UTi1#>`@Zj5kA73Mc6s7pzFkrYanr69PY z#49|_BC$_err5F7jZ0K(!=UFArp$+{FhRsiqQ>e3vlruAbioL2F#Nj55|i~btCa1* z{8qUZ%a%a|Hz4Or6Q{-Wjl=&xLzn{@f}^BJwA;fGQzZ#y(O_k7Go>buENSBg=z4*T z$~TAO>E4>j=a|%0qYVvreLYOwaG*`-ADi$EmY^R*!M^&H>bCv=qeYK@TBOyaffHAD zcwSW=Bsero%?C*sPkZYs!H{fLA;#UiF-y;M9Fp(3okV^E;v4@9Z+c&qF;jZI9sEBt zJ^D8rhPE$7z46}>-5Vo5o9stZ0}X-C`uA+vv1~EOg+2U7@*2pQJB}r~WU2jmP3cWa zRi2C15Z=|pc&#po`dz_np|TRnA@=tehsZFx*#vuw%uqW z+wlBVfXP&V!Ot|W$+g8;Cb3NaKutq;Bn$tqebT?#ptM<_u{Zc>q-Mr8)9w)N&NYZB zI-@SEX$&LYY!)!E7_ve3L^my(1dVN@O%aA za)THwp<1vBwrTL9)9v74F*sUGI2p(~zh1)&%7O~aYfVl^U78v^tGh~9-Hp)yd1>=M zuk-*Y_7A@>bljUDas?+Ctb9we<<6Fzf| zfUL&*XFG#6N{J22|Loi}9Otrv2;*UcgBX!wrRdYUACx${L^A%zC6ema3fw(Z<3pMvp8p%(Ug?hkxg;l| zYl4<;jDIWq&-~s{s;Eq6;lv8bg8ImU{78NB)_0hd#vp(RQTM|Pg_BziTT1(5EtCVz zK-7FtfEY$DGe;u8w#|Ly*L8K0M=1Be+BpY<2>el56CY|g%VX<_7tXKHw_JJCIu}l=xg2F-!35#rx zu3>t1ab7@Lv2ucQFS-;H%YK6tG2~m9E^xerS@%CJ--9GVC|~{kW&sQFiRzsVwR~n{ z12UFfYf1YTGUbv25>BeqNh)8KqcKOs*L#&my4fm%Br^%lSUpVe&7-7%Q+P@h38t}(R(e| zqCr|8Bj$PPZB*n&M*}eX{fNpL{1<@m!I|6K*|~D{+T1v0hrC<`zDd_c{nKJ|Hz<~9 zMWPWvCIB_TKK)Z zYW6};9E2Z?iSJ=!x{kWKih2Kyp$D(S3{;kUP)csuY;MjH_|MtfFdB8j^8e4~_FSI- zDGESs)r2IBy~3}!>9w|Mb3^qHoetz?Z1DXU>fN(C@0*+c?92WKQKW( z1Y*?>+Hct_5xtjw(f(dnEl-n%@7N#X?hW>G)y@(?@JiSsuJla@7eH)3`+9V>E+~rX zdl=OM4|KxZ1p|5?xb=cto`9jRM6=E0OFy?F3jMIXyu1qL@OE4~{*~+Jonp?;353|1 z*pXCGrXbepllKA`IZ}nxn z9j6t%t4siMF)SogQ@r^&;|Zg{`Qwmz>p;b*R7q;mv_=yd(Pd#nh*xCp67Q`UGeH`woVlON)1L(IYWUZV!J%+*l-F0o8 zj{6%+rTGnBFLW0r#*;RTwqHY_b#U{t>V3eeZInyu9`WGo(2X29hbW#`D|h+M&$Zx! zjO_%Gm-m!~FGab3k1pt&uEx!{Mk&29NSd5(y4a~$Vv|CY)c`*?>lY>|G*?$xllc0_ zi5lR{joR;Hg(KQo0PlNSdzY>3w+%gmJJfBu|C^$Lcvrf%ZTCVvE$N}KN3NBN~xUpUW=8|HbOBzfOglq z^B}!807@=waIjj2@kS{NkxWP^Io}0U%I}?q_f@ysduWdXHMC1BOy zSS@f@Z#l5}B>B7v-!h(j>Ppc%-`X?u|J3#QJl)zgv^;(K@EZNY857tIjzriMLGwN0 z61uj#6DeI&$iUhWaA1kfFXh!SW2rS{AP^|QgtX*A>ac+y#)am{0hp9VQuE)zUfFYQ~i@`xi8SG`{ zkH&eiwKhx_rGdCjKoH!Jqf33CQFY**1f9YE4w}UkqmmHa0K-+RYhIMB_J6_rxK;Ka z=yUHG?s@xm#_}Xc@+m<3c@8@y7TqlC5C{>c?LYCN{c7U|=}OWjb?#B1BH}!paiqEt z+!TKwdDg@T0{)T(ChPJ7E|BXrsW^`>lly14Lf0F;1x>4SS%iVG@4VS4BDHBtkw+r% z^gT{tfsWyiodi{~BsXSIVF%=B>a}si<2`cUv{@p&wKjlQj1BbDIN7gDdP8cB(&k0! z$}Pmeik=tZkFvj;pKlvA0RPWt$TwU0b%;=zkl5DSd5R^dX6>z!szi}ILy6XcXI#_G|S% z&s*F9^`E;-ytSZ1&Q1|c#!;?Af|1b$^WJ8Kz-w;WCEhgBeHh&(51~LBH117$l5<-= zP_7kwkYZ3?w~uZG!yXSV{?2e`8*@dyroNMWWu0ng*8btME;Xw3%8W-y(4R4g`V}OQ zW78^o>Y=y$4*jh8C8i8KF(FhRa-9*hf@P87D6z`K9{rzH_lXt6YyR&X+?3no5dNS< z{_UY9!~2O);6w5~6XGVxmgp2{r*m}mqC9w{GxZf)yXlKt1kpZ2bIwVVf^Nx`f)mn4 zrD4q`e1T^@2OK`2+w>rzOffk84_PqW8cFEt(#%T>1+;WQ6~cp2RlA6OOEDi7hZZSR;4kCHZL7ckGQ3siS>4l{vNHAgE%WqJA~$J`%KKe>wR8wRg|NdN}YZJ ze2z>Nuh*%&8Dp`-LpwVDf=-Jh&fv6wKpMkA_*L*k~RT)`3A zkm|~)?Wr3ovD(|N-rKj&JCCnBkFe-bA=_%vt9!{yWjR}mUcS|zFWH8og-?7#p9#7j zpTl>Kh0o8d>>sa}r!*Scqd(SqEfDVd8{aV-^lBt2;#y;L4Nqy7YxD$(I0IA~ud zRSUd(9jljD^HCxzy0$q7W0!#63S^wXfH*01cu4}UFBLVvoawq2Y@1L%EdsOlrUhPLmX z(UBz4B8Sir3CvQpg;uP2xi)+ZD<(;v-b6zvz73e5`&s6I_5@b7KWQSQI-pHNNkK_a zj1(mj3}nnU@Oe`C#rr+`wY+b zS0qZ-wl8oe(4m^&>VjU;<)S|vsM}xf?URofHVaE;4q?|qI`#Q@uojp*_7jM(nLJ^~ z*vK1 z^~<|`ws;Y^5un!a*1V`tz4a;Rck2R;6_vkp>1Qv|PVy)Q%If9!CKAgE2cD@SwXkMA z&cUmjX*9bN6{-HTkEW`=DeTRe5fol2EWpwpm?_`bbgtKrF{r~+j3x#Znw`d1! z5pwnf)k$^$4LQ6{Q(T|O69yOLs$y)e@AMy;RIzy8Y)va{VeF>ne}oRygAfiT*<|L< zL|63`X=4d=EI+QJCX>2!+Jeu(w@vZBR}?;KYB-d6hNup<8n-(C4`XpCTeVAVDc%;O zt`UCvB~)D=tohyUAjo#g(_XM`2zd4NtX8M$U*RWmYSnY%J*y=kDTwBGVefgd6^OYv z$JGO6^=`04D6qPPy(krbA`&-s-^kbEA^(sPYRqn%6kT=X7SJJJN%kGP0ne{{&)tH) z*Z_W%QH2v)q7^o(JRXh3S;Z)|ZaB1Vka+m`J<-SRC!EWnNL0(g|4!qHw&RBH0mXYe zW`@*0_?F?}Mc1fa$Gc3V3weyLa8Y zH&rqBtuJufyscEjKo*2Um&W{Py)Q3cJ2%alSXoV14uXIV{ZB@u7wfxYPU$s%a{xf> zZ7MFd3KB0G=2kqjX@W4X2iOChyRuGbfvrFff+$4bu>RY-foki?N_kS>AXF2^mlUlm zS<*0%mA3EGVk`EcVv%)5n`b$Zy%YI)hAV{&f9QPfZw_VTcxMeG>s0a-8evV>1OJS% zhy3P!srkNQo1_a!a6_H=R=%D|M~%h0|9hP~QqR^pzO_9Rz*IBAjkzyhIIgbI$-XCy zNJIBEr7J%v?RR0W-JljUmK^ij5)qt1oUP4XD%SUMJUvg#E*go)G}urCME$+M`p!8M zKrAI23x%jDIs8xyF;$SNg$n~faof} z9=In0wgzV_6KH?!&rH^P0f#nQ9a@kOslbO;B={8Bu1hfB1uaT)yY6q{H(NFfPGIFy zL76UeQ=Ztbs5w^kMB6_%7A~;g`6tk6_22K^I<6fyNm_ zHvBc=Qh(R9em?p?oNNU+!4aXe@K=Ljw)mcBU*&u#=94PO0@VbS~YpI$e5UGd0?&qpPJ_4& zCkXyTTUgcqxkP&o*52KrP2ySu4zh>)$niVQLaj|qzb1<#nnM(XB;Sr}ln6fC!qy~f zm1#YrQ!c==!H7aBro4UD@$LXYlBW0y@1^i;Hi+TdR4KYIv!*v7;<`G^A=v2MJc-k! zQ6QCyfa4?iD&Bd~0TqcHW`!x(j47yK8o6vf+zPuQ-=?+H#2^xSn=Q`N>0 zp?^5zgccF}R3uZ6n<MIajg9-63C0fi$RB>DIvl{-hV&rk!t~`U*VrEFa-D7QP%>?H7rwM6k;H|_J*ob?_Jj0B zFcn@NzG4?*YzOzg(H4+sGlJwVz7EkemMs}$@@~e!F#UCs>~L0mqgbNF=2t6gEqJ{q zjXMnbBCQr07{1>$MU`sk(l>ESB6hZplf(!Qyq~V_Uve$`l?=8zxVvEYS(mUX>n%cLLLmgH>Bw+miDU zX$+wUKI^8nF|(9x%_0L#DHvFGld)$T)jD&e%`xaH=_u$a{xCgE(4OT6&=WF9`&ddF)n#wsGw; zii&1gmJF{o%sn}WM?CX71#?GR>^(yy8s4VauM@b+&bNJy1JR&G zXCK%hr{{rB52KtPDyY2-Q77lx-rD_5CN-J+W3Qx$E)0mhAqAEjVB%7UOgM-WFw6_@ z;xnp$QX{MXn?YDIa^5edKj*zR5odqyI9k@3WMs;AG}2{llR9cn9pV#6^;^FMiw@ZL zs`#TW3?x>jPz^jB`NT@Af!ddq|M?f_n zA6;zr>Dk5-{IxLYo-TqUY=z2&y;b0<#y5_|qg?&eYZXT2BlP*ADRUw##o??Nk^_!` zI)wrCTPlBUepvvj)HW5M!YY6;1e20PBU_(pLZ*Rv>_B1RVCK31R0JHyX(w-za&n zj4tRIut=r&GB(a=GO%O*-q-?zT&ttVhCh5Aux3=CVl<<^IXI&M;+S=?6ayv^hPVk) z;X7Z1hOV~Bq=sTasSca=xfTxbKtjZD#b%~DXcOmNvAynp-30(ScLr6`C{;#O`aM1s zWt-q)p9<7BA#`ELuyP-3wFVPSDn}Uhd}x?15*Ybf*DG3}+U&*4Kc$S*dmaFIn6Tx; z9zg$~nS=x>MdNR`H|&og+JHk43nQ)rIe~*nR|flm;7$XIJ5!9%(}Rg-(3`4Ni9wgZ(VD1s$%^)Yq5z6qK%X z0K!|At4ecLsz)TB!j>w88%s0*ljmwC%F#Ex#_T7Bf9{G68CU%>WhroC$*{(V4bb;d zYn*`A_`yY4IND)SoETzsSQ2c1!?%uthxfwPWc!Ma=0<)$jxLhK zR47~^y=IyKvWFK`erO(DSS^=pVK;??GZXOm^`HvH!#Y@Q2GTN5xKw!vsNcnubqDL( z?4&|ap~VlQZ6H$Cb|Z!VfdlRt3;aE;pmQlW*w2ECX;3nS#&VZ3GJG%*tc^XtB6(Pp zgzs{X@$teYZTwE>Wb1+Non&wATp7QR zrcvVHP(v2R!uwf@Xt|WA61wK$uDX34dG7((7P^Itb%zF%J*m_l<05C!Oa3uo(_g=d z4_ZrcKnY_}tuWdY6&_oA?U}x`5r0fqm%Y|2lptQMVg8R9P^t)GVxp=E!8jl$#!~)> zGSq?zy|3*$EHQz&XT;jxez6^B+;xH#B{!`6)24!%tF(Aj$hB$8kP!Ho?SWOcW8wWj(dDxSUYw6&(6Grh@| zrsfn*adkoybudJibhh4jQ1?aR-+#SfLj=Q>Ncy*6Y`nje9<(jq7>o&1?%!zC7Z#kA zYpLJL$tBg7sDL&#(jRldDPf|L0J=%GSaF?uT~SkFb#z6}g^)2_cBQ=q#NJ>EgsxminPVuTM7*XEAH+t z!JR_UA_0oDCq3`|bniWD{lAVJ`Zr&pNNMl-=S@fFv!dO@!OAAS=p#sIhBv^#2xqmC%)U#qytx)As0)-6|4G zDRJD)O_i#BRr>2rVkVcwLK4v4TML< zzPH_Q7t0Cd)H`w!Uf*d94tqn-Y*a3Frta$4>H+u{hALgtbN^3@>L{g)8Y3JUY6S0t za@20T_H*_BM^gO5C{RVM|Leu&T<}h8G^P=CnoBtYeqTwzBCIAoT{QYe|z~bF2tVOy6U^M<>T&QKo2wMa=v^2q0>0E3_9SsZhmVp?vejp~aJ?S5E!D zU2*40zyzX?=GLoNt!u=sYmw);KDQpUxN(f7eALZC+P7;OS`^rE#ha+a>)LnITS}f* zwAs?JU$sF{o@O59N2Y0U%?q~3{JMR>i&k*E*oSZn?zRS-k9_?_q<}I!A0H149WC4g zHqZYhV-`$01h}F(mugbt#$iXF;@`6#pwu8rv3mBNc-PsO<`!}Z4>Zki5pZ0w_>pjC zbgI)TaiKQCeRWk<_*`$C=&etXb0xB!eG73@k|Q$&wsGq@IqyCr zVMS?ES5m`RF1ZExe)bED0SlrlWRa^m4QC7?e+D6c4C8?OR@bAc)r(2r`2SP(S8R9B z@P&sAW##S!4x3<8U=lm@hb{`?GzV}TM!z}McrQ5}`crH-13LVKU3P5)`uKTzxkIC;SF=qOg|_gZhV1F5DTJc)822*TQ#WtqG^V=QJIu9Z<<>#QXiF(ggT%9u1t=@@-Zh;JNm`Z zV^BokR8?*b3a3KZ@L}#nrs`YANeY20=)FUN$^(^A`c&i=nf}eh2NBv}A#q@Ttvd~7 z5GIX?FTLK6D3tEhnP5#PCwK3CQQDswrl6(g&t|KAK3QJQ`gK=Wq&SJ|fMAqxwCLBi zx}opj~8XU|Ca zN%l+bq?gi6ucVn2dFlGs|AU-3F$V@u5DTs4@4<9^f=$gPU1HTjEtfJ=t3)PrSRa}RShE|tEns4RF$h`)U@&5h>|=2MH^Ix zFOVq-r6^6QhZX1kihOrD+0al$s}$&>rNOLFgC|WTBk~R~kYJmMLfF%>5KBlX0(rwRoEt#?o^j>aGsju&U~k zc+a%}F)%tYJ?S%rVx0N5xjj**;bTf!5FzzB>25Sd5o~G`bxb zFf*AjR?{eq@CM#0VYc5P9E|wp; zWsD>gajg2LH;ZH|nAK;HNfu{C_;bWdcoD>p_=mI-irxD@kx6LXpWbXY2%6+1CB!9N zgs-Mn#elIb+hh;ejI?L&jvsu$J7XDYTf!{uLp_D0qt>85?L8M8C}SB?G+NBGWRn&T z#12R`ZgS-PfVk_h-9)(kQI#39Wh1guJUE;9ou;p7drN;z^=YTQk4x-FVev)9EGk?t z`W`4xd&4S3B|3w`)~L!w4O#pr<2uODzxncJ?@Oth=Op5;(c$m*herlLJ~ob)#x?+( z2T)Hzr7tMvXeS%NH>5`17H?Dkw%FMSWBFGu!je{x*bH&xy&VjUKFToDZq>ab2=2ty z_)1P;17!U|SvouCsy>a^^2{jrPj0cbrP~F8G*){sk(ECi@2UA|2T`0!(sAuDsJHjp z>n4*v_$$>K0k)pi={E>w<(Z>)bi^`1GDV&<#lgkKly;eP3!|IP3}WEzFe+-;KW}~W zBUZEq_a2kKMJ{&m<14|7MYI$v8J|u(YQDMxYC9J9T{=`q`cu_j6BQ%M5v2|@@(^2y zX%q1xQW>?xn{A5)Yx~N)XA!{*W5ErB2d`2+*6mmYt2=lSzt$GUx4l16xqZ8LGJWrH z8b<`!plPH)4sAPDnqH$W1y3wbC*$9s;55{05Y{w;#&4s238lGa35u^97G`j8f*by( zSzIj=l^+Bo1|iIRusdtnmM@>Lu03euxoV-k5yY#!B(6j)__eOPpg z*K`^0o{zac>yDQ{!%b~XrmTbPJIj@>7Gj)u+}4t7@XI!HOkIi(VPNo(CqT0v(9C%Y z!0t7w@*aK1N+6ZPyNXw)Pm95r)>AuT}Xq28&N-RZ>ngXzpAhVFzU6)P1{bgvd= z6Zk;_1EWp>&T`N_pEp-Mdg(+cYee?tS)SBE%Y4*2ko=gKIz6NPmp^Jo02hh7WV=9w zlr-QDS?6LG)H+|v%$w60gkz27w76P|ZuW7EIDbTznqaq|(Pb!LQp$>yTJy!V0e~vZ zA_O3fb%KWXBRm0>(Dx51ian+QoYwN43g};!!?n^3eDANkaI{r1Z9Xz}yruwlV!w;R z7zysJ2YUZrHnyVggA15BhkJ4ZVQdu-7h-fxFq!c0+D{44Wc^o+una6sB9OK(r4&HI~}_FX6Fze?1_Ay?D{oY|!7ls>_FN&2;eY&cEOK?d{rmEqMN)eb5JtKVfNO zG}p}c`%i&WC0Wg}I1wL+KG7P9`V`AXM{Ffk4VfJ_5`CtF3R8#kPj}pVEawzqKVNl< z30zFF1LKuR39x}gcUzY=G3}WsHVZ##PBr`$v|uiESkRmXhbYBblbfJtfB2+!P> ziLDg_!ELC#Iw+6zD0?g2+-s7XiXF{Dc|@(JkkhHz3AxX9)s1!5bvgExc6q^PHRWdY z^lxDyPDf7m0HGoq9sc>w#@S^J?x9xoLGxVgQBZ9fRGk$_eX>55=Tv_@axy{3K*M_| zrCu#f@y|tABRsnh0`sE+9-ag?%mW*7_EagFZ(mUAJhoy~imh58poVF2!29;E>)9bB zr?I2D)Hm+yCWkM+FP{C-6Vzlr#Hu;M$)#uVKp$7?G!Q>+Ic2Wpjyun&#Oas()Ni(Q zJe!vQuq=|gJ=3}Q8*ukMukQ}JjaVhLE8lLMOgatn^pwpony5{rtbO0+$ZJQQfHO&o zg|4ZoN!m9hD#(;5=o{R3;*~mslozjT84?x5{%)1PM_fx~3`{@idR{xuQ;W_mcaE(? zfo<%aEPiFM=EY;C1#7@Ov!fgT4l0YrpRKi6vE_7lpkKw{aOaTciBl+nb)P>bc;-`Rn`;lrz87TcNn zS|-N+^q!tMeXMBqT`_3?vS8kOQ+WP)>ocMJ0S?^8?s;AGRQiBt;FaCqF2*@uOC}qp zof^7g3j*`=N7{*JxXW&YbpjWm*`WpFA6|^qJ!>_?5I%3#(Yt3nS`Fi#vKP&#$-QpNA?wX(wR080ZyxI9~yK$k)Lft$^4b+Uqn z==5J^rXC+%6kf5EMUYubdU>rsrV>iyrtfvZo?FOhPJO0;zj<$)lIF-0e7g{EGGb1* z)nW1Z@V+z~zIUT$u2x7cL+ryU6?wiR+&1x@DM-%w-3jmW0)egLTXlp7i_jGRx!^K# zo@(dQSsj>~oX8X>lRxg&rQszo(v+mf+(2#m<+IWGg(oC72OOi%H21q)tMM6VvI%ww zy@shpo_&O!j(pK=LU@UCS5-LnKk5wDNvu*jzF)FVc#9wG7Z3o;6$mj#uOv@yiJ;!_ z#?vqg7CDxqTlYX9=bEEYV5wpFjvsG@h!5Qstr955tdSS^D~1~gSH)m z8O|tXe@4h)6dh)+$6N#rgg_S4^;;ZiSrFjb9@uT@N)G+%s_dqp$bhf(fUiiXZ%ER2 zsy3>|{mmD;=r`hsrk0i-WL{{ueI#l=w~iYgg)BQFU7+kxq{Ve>p%kO%0Y5t^>f1Lh zO4=Z?lc&q4XJa(Ww{8{HIc@o#DI_7(8f^Bvr(9;oq^bS%%s9B|v^xuh4s;^=QLJjD zi^Rr>P3TaFRX5M}n$u>EA|3-Sd^C)leW;e`ZTb_zN;l}Uv=A-Rph#VLfsN4Djnhsd zFGcNR;|TO;EiyTGKVx%Z8^B~As%rD|@j-F6n#dR}3eoHrQ?DA+91w4zE!e2zw6vm7 zcm2Z8blxJ2A)fd8iFtl=LtwLt*sP22YU4bSrr|ke+oM~Ll_+%FQ{UB1&}V?~t1h;Z zQI=yzl0)qpt&5397H6McNq}3bSB;_;u`3tTT;890`5)QoKa&f5z8zW|>;H=09?2u( z=jl$nW&?cfy)y&7&_`aR+VkH3aShUab31E0BQhI7rT zCVg@wek;%y`LZhC^rm8L-ZHLxlu&ur#^1R;^wXz(T;V=LwXp%VgwpsDBlyxZ9iPSD z(7Og=zZa3kQdy4Z$HD&9CdKvQtK-@r!91#E5t4q1wr;5FwT|zOVrB8lt#v}I-OIxn z`$j2qEIvfHY-Bsx`Z!Kb*M#TUnbSvJ60rRv{{b<;V6M}XOrEm6Rsj1>M&|<6O#qFS zopXmRw)o%CH8$LJZ^iVIFh`-J`U>#DIxvFxM+&-fN-7qD2lpBp_S-3Ln2Uka+s7j@ zXIH4l97mv}Z0VXVe%}Oa3f?@lFm4X>hL2PFR*TTa**=YV@=K=a17LKj=-F1G zSm~^C%*TyYrUcmtgF1ZUDQ=%(0Z%;DtwiEBQLMqK!dBL~N+2uxL*;KhQOl}O@qr(2 zCG|iNKXDeZ};$mG}+kA&nxan|8Fmd$0kd z1=Vn%^rGx_?d(8u=%XIPo2V&-e^5|-%sx=L#7^5snJK>J|RCCH%U5L?8~UQl#4QO=#% zj?)$vCA*>wTY6bCjV`D6LeuOX`U=8YqK1Mh0sfpA)=UlluGyDJuaLtBAWYGYR_AqhIT^mZf zWVh-!DHbQi49#sBkXM3%!cx6MaVrI5KLhwz7r6--%A_%~_gEaV?5lZR8R!ufr^)$e zkBWn_&uk;6G;@=+0%;hsWNEaxBibd`0bmKn>D8YxzA`5=7x*oMn(+y^%JHWTXelISQ~=rfZ{#w|WVy*SojETx)4>}HVzwpJ z(j=uUHSi3YRZz~^9aH-{8&d#A{;RrQck7)NRu?oMHaeOD)>)=R(|4Y(Zh&`wXmnZo zNV{M|*Rc4BZ17YTdNIjfe9FS}$-$oV*z^S^Tkc+!`%kg%holIIwMZ8188cSF)HaQ% zazDp(lWE5Dp7?}Q>enFLLxONi8%}aOqqPOgWO#!zVWb8!_ne_X+_(c4Pe>H+C=D@( zo4dbm|C_LPEq7B(YsW+aS*f||0&Kf?HXtnG()Q6I1ReJ01u@Q#Nm84^ZTpUpft~uQ z$ewfu4(J*giT{;>%enTPgj-R6u)cxJf$jx>|GPaM#NPBAVBn-{Fxa|uD;PCIHjKQ{ zuSSH4vvctDyqPwBHiqO}$e81)o_6gwBb7XEnqsf!Zni(173G*QQ25NhI{`mp3mq2s z=3U+X*N`E2P>4FSo4j_ROMcDbum=Ewdz0w`EQ>gIrnn`elCp9$%>0<|7UB_QVj))# z(|{t8Lmv@I4YJc1Y6-IFOOu!!VfZYPyz0?0UGAIr1VrKmj)ey-WeGmy6Zx*M{=8fo z|NECeqMf*{=vI(5{@XMk^{?_2u-egHdHFrpj`Hi7*5${Dw?J zO|}d*#LF4f@EegTz#*1|4fR4fv}XA806f>LHQ%p&^B;n$#igRq9LEY2VAtEv`CK6q zYGbc}+Gk)`0T`2Jjidrw{Q8TREKA{=2}dbOYYinZKrDmOaN$KcV^!6y=k)Sa*t_j*hI1e)vDOSw%^buWD0p9g?*p z@)W}6F-q0}`~v*$9zGvq2ALxFfu(iN{j+!@zvjx|k9=}`NOw__ay8S$RMajk#xgm!@Q$P0!$S64ws=ng%)+xR86|q}d;d9hoeb_h@*aqVnC!b=# zqgw!TB<*(-J`sBL?-Ka6#R{{Y2Q9=9adYF=z2X=W-@IMpKN48g?2>Kp0ASXzdA9Q} z<3GG9R!4^`1X!h*(d1pijDq295Z`2XSBl{eOZ~T~W5WD&M8Ccu_M?v0wrVs_^Fj3Z zHxVkoz6_TyPuuBwTUpJ$^>Mtt8G}0AqD#;R_6DOV9lcl3Jjg!GU+@khNQBwIQz)Q9 zGs5jTI{uiYcT1|*lcTzMkJq3oz~T8*%(zla(ur9aV&Lp~r97A~S^!KogMaU1M)gyf-Xy!BrE+T;1!HEbvOXoY^^h|&N?X~2W~ zp}o&iw%3}$z;110y;FC)CA>Xz2Z^La?eXkStdw(_l5W%mna!oDq*TCbzxk9*ebbIR zgkdoqT^#^(GRltfEPD>x?7d`IG+11EP3GsBMJx$Ha^ZFet*fKSed7`W07j}wlFq_^ zdJ@<$pXyz-H`MDVlYato0VQxzd+kr2s(Sb58Lk<-;x>)!5i6L zdm`BU`NkpQaY%ow*Q1?|@X5$dB8SPBdPpv?%fNT4lG9kEQ`gjAx~IG%0~YEW{Y>3c z&Mc>oyHEe_CM>N3i;j2BCwAS(*{H!p1y=#?XWicCBsAcp-PS$g|EK}$7GOaD#KJHY zbuAYAbyNaPBBWD`s2?DEidtl@;I|@r2_u!q1Qw{a=$K5$NZMx^QMO^W-U1wOwJ?j_4^Bh0+x>!&Un{PiTOoh%HyU|BD0#@b z!P5C~LHOr(hveaABc$NMh6TzI&s#gh%Co_`t4j6OI>{>%G?ezQ<_ItT6A!8av;d@H iF+^3wSFlz5#l)Pom}ZVBy+D2I0!;;^p#)bj5C32Jq($5S literal 0 HcmV?d00001 diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view3.png b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view3.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d0e41e25719609cca809c2a57cf63a1922ab3d GIT binary patch literal 14991 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 literal 0 HcmV?d00001 diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view4.png b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/img/view4.png new file mode 100644 index 0000000000000000000000000000000000000000..8cf2995c3c4c5d5fee0d62040068625dac72718d GIT binary patch literal 14043 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 rWBv2ZSJi7HOQ=P>&=kz&iT)(k|2WFhttp://en.wikipedia.org/wiki/Ethiopian_calendar. + See also Calendrical Calculations: The Millennium Edition + (http://emr.cs.iit.edu/home/reingold/calendar-book/index.shtml). + @class EthiopianCalendar + @param {string} [language=''] The language code (default English) for localisation. */ + function EthiopianCalendar(language) { + this.local = this.regionalOptions[language || ''] || this.regionalOptions['']; + } + + EthiopianCalendar.prototype = new $.calendars.baseCalendar(); + + $.extend(EthiopianCalendar.prototype, { + /** The calendar name. + @memberof EthiopianCalendar */ + name: 'Ethiopian', + /** Julian date of start of Ethiopian epoch: 27 August 8 CE (Gregorian). + @memberof EthiopianCalendar */ + jdEpoch: 1724220.5, + /** Days per month in a common year. + @memberof EthiopianCalendar */ + daysPerMonth: [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 5], + /** true if has a year zero, false if not. + @memberof EthiopianCalendar */ + hasYearZero: false, + /** The minimum month number. + @memberof EthiopianCalendar */ + minMonth: 1, + /** The first month in the year. + @memberof EthiopianCalendar */ + firstMonth: 1, + /** The minimum day number. + @memberof EthiopianCalendar */ + minDay: 1, + + /** Localisations for the plugin. + Entries are objects indexed by the language code ('' being the default US/English). + Each object has the following attributes. + @memberof EthiopianCalendar + @property {string} name The calendar name. + @property {string[]} epochs The epoch names (before/after year 0). + @property {string[]} monthNames The long names of the months of the year. + @property {string[]} monthNamesShort The short names of the months of the year. + @property {string[]} dayNames The long names of the days of the week. + @property {string[]} dayNamesShort The short names of the days of the week. + @property {string[]} dayNamesMin The minimal names of the days of the week. + @property {string} dateFormat The date format for this calendar. + See the options on formatDate for details. + @property {number} firstDay The number of the first day of the week, starting at 0. + @property {boolean} isRTL true if this localisation reads right-to-left. */ + regionalOptions: { // Localisations + '': { + name: 'Ethiopian', + epochs: ['BEE', 'EE'], + monthNames: ['Meskerem', 'Tikemet', 'Hidar', 'Tahesas', 'Tir', 'Yekatit', + 'Megabit', 'Miazia', 'Genbot', 'Sene', 'Hamle', 'Nehase', 'Pagume'], + monthNamesShort: ['Mes', 'Tik', 'Hid', 'Tah', 'Tir', 'Yek', + 'Meg', 'Mia', 'Gen', 'Sen', 'Ham', 'Neh', 'Pag'], + dayNames: ['Ehud', 'Segno', 'Maksegno', 'Irob', 'Hamus', 'Arb', 'Kidame'], + dayNamesShort: ['Ehu', 'Seg', 'Mak', 'Iro', 'Ham', 'Arb', 'Kid'], + dayNamesMin: ['Eh', 'Se', 'Ma', 'Ir', 'Ha', 'Ar', 'Ki'], + digits: null, + dateFormat: 'dd/mm/yyyy', + firstDay: 0, + isRTL: false + } + }, + + /** Determine whether this date is in a leap year. + @memberof EthiopianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {boolean} true if this is a leap year, false if not. + @throws Error if an invalid year or a different calendar used. */ + leapYear: function(year) { + var date = this._validate(year, this.minMonth, this.minDay, $.calendars.local.invalidYear); + year = date.year() + (date.year() < 0 ? 1 : 0); // No year zero + return year % 4 === 3 || year % 4 === -1; + }, + + /** Retrieve the number of months in a year. + @memberof EthiopianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {number} The number of months. + @throws Error if an invalid year or a different calendar used. */ + monthsInYear: function(year) { + this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + return 13; + }, + + /** Determine the week of the year for a date. + @memberof EthiopianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if only year specified above). + @param {number} [day] The day to examine (if only year specified above). + @return {number} The week of the year. + @throws Error if an invalid date or a different calendar used. */ + weekOfYear: function(year, month, day) { + // Find Sunday of this week starting on Sunday + var checkDate = this.newDate(year, month, day); + checkDate.add(-checkDate.dayOfWeek(), 'd'); + return Math.floor((checkDate.dayOfYear() - 1) / 7) + 1; + }, + + /** Retrieve the number of days in a month. + @memberof EthiopianCalendar + @param {CDate|number} year The date to examine or the year of the month. + @param {number} [month] The month (if only year specified above). + @return {number} The number of days in this month. + @throws Error if an invalid month/year or a different calendar used. */ + daysInMonth: function(year, month) { + var date = this._validate(year, month, this.minDay, $.calendars.local.invalidMonth); + return this.daysPerMonth[date.month() - 1] + + (date.month() === 13 && this.leapYear(date.year()) ? 1 : 0); + }, + + /** Determine whether this date is a week day. + @memberof EthiopianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if only year specified above). + @param {number} [day] The day to examine (if only year specified above). + @return {boolean} true if a week day, false if not. + @throws Error if an invalid date or a different calendar used. */ + weekDay: function(year, month, day) { + return (this.dayOfWeek(year, month, day) || 7) < 6; + }, + + /** Retrieve the Julian date equivalent for this date, + i.e. days since January 1, 4713 BCE Greenwich noon. + @memberof EthiopianCalendar + @param {CDate|number} year The date to convert or the year to convert. + @param {number} [month] The month to convert (if only year specified above). + @param {number} [day] The day to convert (if only year specified above). + @return {number} The equivalent Julian date. + @throws Error if an invalid date or a different calendar used. */ + toJD: function(year, month, day) { + var date = this._validate(year, month, day, $.calendars.local.invalidDate); + year = date.year(); + if (year < 0) { year++; } // No year zero + return date.day() + (date.month() - 1) * 30 + + (year - 1) * 365 + Math.floor(year / 4) + this.jdEpoch - 1; + }, + + /** Create a new date from a Julian date. + @memberof EthiopianCalendar + @param {number} jd the Julian date to convert. + @return {CDate} the equivalent date. */ + fromJD: function(jd) { + var c = Math.floor(jd) + 0.5 - this.jdEpoch; + var year = Math.floor((c - Math.floor((c + 366) / 1461)) / 365) + 1; + if (year <= 0) { year--; } // No year zero + c = Math.floor(jd) + 0.5 - this.newDate(year, 1, 1).toJD(); + var month = Math.floor(c / 30) + 1; + var day = c - (month - 1) * 30 + 1; + return this.newDate(year, month, day); + } + }); + + // Ethiopian calendar implementation + $.calendars.calendars.ethiopian = EthiopianCalendar; + +})(jQuery); \ No newline at end of file diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.js b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.js new file mode 100644 index 000000000..833bc2aac --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.js @@ -0,0 +1,2 @@ +!function(a){"use strict";function b(a){this.local=this.regionalOptions[a||""]||this.regionalOptions[""]}b.prototype=new a.calendars.baseCalendar,a.extend(b.prototype,{name:"Ethiopian",jdEpoch:1724220.5,daysPerMonth:[30,30,30,30,30,30,30,30,30,30,30,30,5],hasYearZero:!1,minMonth:1,firstMonth:1,minDay:1,regionalOptions:{"":{name:"Ethiopian",epochs:["BEE","EE"],monthNames:["Meskerem","Tikemet","Hidar","Tahesas","Tir","Yekatit","Megabit","Miazia","Genbot","Sene","Hamle","Nehase","Pagume"],monthNamesShort:["Mes","Tik","Hid","Tah","Tir","Yek","Meg","Mia","Gen","Sen","Ham","Neh","Pag"],dayNames:["Ehud","Segno","Maksegno","Irob","Hamus","Arb","Kidame"],dayNamesShort:["Ehu","Seg","Mak","Iro","Ham","Arb","Kid"],dayNamesMin:["Eh","Se","Ma","Ir","Ha","Ar","Ki"],digits:null,dateFormat:"dd/mm/yyyy",firstDay:0,isRTL:!1}},leapYear:function(b){var c=this._validate(b,this.minMonth,this.minDay,a.calendars.local.invalidYear);return b=c.year()+(c.year()<0?1:0),b%4===3||b%4===-1},monthsInYear:function(b){return this._validate(b,this.minMonth,this.minDay,a.calendars.local.invalidYear||a.calendars.regionalOptions[""].invalidYear),13},weekOfYear:function(a,b,c){var d=this.newDate(a,b,c);return d.add(-d.dayOfWeek(),"d"),Math.floor((d.dayOfYear()-1)/7)+1},daysInMonth:function(b,c){var d=this._validate(b,c,this.minDay,a.calendars.local.invalidMonth);return this.daysPerMonth[d.month()-1]+(13===d.month()&&this.leapYear(d.year())?1:0)},weekDay:function(a,b,c){return(this.dayOfWeek(a,b,c)||7)<6},toJD:function(b,c,d){var e=this._validate(b,c,d,a.calendars.local.invalidDate);return b=e.year(),b<0&&b++,e.day()+30*(e.month()-1)+365*(b-1)+Math.floor(b/4)+this.jdEpoch-1},fromJD:function(a){var b=Math.floor(a)+.5-this.jdEpoch,c=Math.floor((b-Math.floor((b+366)/1461))/365)+1;c<=0&&c--,b=Math.floor(a)+.5-this.newDate(c,1,1).toJD();var d=Math.floor(b/30)+1,e=b-30*(d-1)+1;return this.newDate(c,d,e)}}),a.calendars.calendars.ethiopian=b}(jQuery); +//# sourceMappingURL=jquery.calendars.ethiopian.min.map \ No newline at end of file diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.map b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.map new file mode 100644 index 000000000..c4be63f74 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.ethiopian.min.map @@ -0,0 +1 @@ +{"version":3,"sources":["..\\..\\src\\js\\jquery.calendars.ethiopian.js"],"names":["$","EthiopianCalendar","language","this","local","regionalOptions","prototype","calendars","baseCalendar","extend","name","jdEpoch","daysPerMonth","hasYearZero","minMonth","firstMonth","minDay","","epochs","monthNames","monthNamesShort","dayNames","dayNamesShort","dayNamesMin","digits","dateFormat","firstDay","isRTL","leapYear","year","date","_validate","invalidYear","monthsInYear","weekOfYear","month","day","checkDate","newDate","add","dayOfWeek","Math","floor","dayOfYear","daysInMonth","invalidMonth","weekDay","toJD","invalidDate","fromJD","jd","c","ethiopian","jQuery"],"mappings":"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","file":"jquery.calendars.ethiopian.min.js"} \ No newline at end of file diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.js b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.js new file mode 100644 index 000000000..8480948ef --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.js @@ -0,0 +1,982 @@ +/* http://keith-wood.name/calendars.html + Calendars for jQuery v2.1.0. + Written by Keith Wood (wood.keith{at}optusnet.com.au) August 2009. + Available under the MIT (http://keith-wood.name/licence.html) license. + Please attribute the author if you use it. */ + +(function($) { // Hide scope, no $ conflict + 'use strict'; + + function Calendars() { + this.regionalOptions = []; + /** Localised values. + @memberof Calendars + @property {string} [invalidCalendar='Calendar {0} not found'] + Error message for an unknown calendar. + @property {string} [invalidDate='Invalid {0} date'] + Error message for an invalid date for this calendar. + @property {string} [invalidMonth='Invalid {0} month'] + Error message for an invalid month for this calendar. + @property {string} [invalidYear='Invalid {0} year'] + Error message for an invalid year for this calendar. + @property {string} [differentCalendars='Cannot mix {0} and {1} dates'] + Error message for mixing different calendars. */ + this.regionalOptions[''] = { + invalidCalendar: 'Calendar {0} not found', + invalidDate: 'Invalid {0} date', + invalidMonth: 'Invalid {0} month', + invalidYear: 'Invalid {0} year', + differentCalendars: 'Cannot mix {0} and {1} dates' + }; + this.local = this.regionalOptions['']; + this.calendars = {}; + this._localCals = {}; + } + + /** Create the calendars plugin. +

Provides support for various world calendars in a consistent manner.

+

Use the global instance, $.calendars, to access the functionality.

+ @class Calendars + @example $.calendars.instance('julian').newDate(2014, 12, 25) */ + $.extend(Calendars.prototype, { + + /** Obtain a calendar implementation and localisation. + @memberof Calendars + @param {string} [name='gregorian'] The name of the calendar, e.g. 'gregorian', 'persian', 'islamic'. + @param {string} [language=''] The language code to use for localisation (default is English). + @return {Calendar} The calendar and localisation. + @throws Error if calendar not found. + @example $.calendars.instance() +$.calendars.instance('persian') +$.calendars.instance('hebrew', 'he') */ + instance: function(name, language) { + name = (name || 'gregorian').toLowerCase(); + language = language || ''; + var cal = this._localCals[name + '-' + language]; + if (!cal && this.calendars[name]) { + cal = new this.calendars[name](language); + this._localCals[name + '-' + language] = cal; + } + if (!cal) { + throw (this.local.invalidCalendar || this.regionalOptions[''].invalidCalendar). + replace(/\{0\}/, name); + } + return cal; + }, + + /** Create a new date - for today if no other parameters given. + @memberof Calendars + @param {CDate|number} [year] The date to copy or the year for the date. + @param {number} [month] The month for the date (if numeric year specified above). + @param {number} [day] The day for the date (if numeric year specified above). + @param {BaseCalendar|string} [calendar='gregorian'] The underlying calendar or the name of the calendar. + @param {string} [language=''] The language to use for localisation (default English). + @return {CDate} The new date. + @throws Error if an invalid date. + @example $.calendars.newDate() +$.calendars.newDate(otherDate) +$.calendars.newDate(2001, 1, 1) +$.calendars.newDate(1379, 10, 12, 'persian') */ + newDate: function(year, month, day, calendar, language) { + calendar = ((typeof year !== 'undefined' && year !== null) && year.year ? year.calendar() : + (typeof calendar === 'string' ? this.instance(calendar, language) : calendar)) || this.instance(); + return calendar.newDate(year, month, day); + }, + + /** A simple digit substitution function for localising numbers via the + {@linkcode GregorianCalendar.regionalOptions|Calendar digits} option. + @memberof Calendars + @param {string[]} digits The substitute digits, for 0 through 9. + @return {CalendarsDigits} The substitution function. + @example digits: $.calendars.substituteDigits(['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']) */ + substituteDigits: function(digits) { + return function(value) { + return (value + '').replace(/[0-9]/g, function(digit) { + return digits[digit]; + }); + }; + }, + + /** Digit substitution function for localising Chinese style numbers via the + {@linkcode GregorianCalendar.regionalOptions|Calendar digits} option. + @memberof Calendars + @param {string[]} digits The substitute digits, for 0 through 9. + @param {string[]} powers The characters denoting powers of 10, i.e. 1, 10, 100, 1000. + @return {CalendarsDigits} The substitution function. + @example digits: $.calendars.substituteChineseDigits( + ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'], ['', '十', '百', '千']) */ + substituteChineseDigits: function(digits, powers) { + return function(value) { + var localNumber = ''; + var power = 0; + while (value > 0) { + var units = value % 10; + localNumber = (units === 0 ? '' : digits[units] + powers[power]) + localNumber; + power++; + value = Math.floor(value / 10); + } + if (localNumber.indexOf(digits[1] + powers[1]) === 0) { + localNumber = localNumber.substr(1); + } + return localNumber || digits[0]; + }; + } + }); + + /** Generic date, based on a particular calendar. + @class CDate + @param {BaseCalendar} calendar The underlying calendar implementation. + @param {number} year The year for this date. + @param {number} month The month for this date. + @param {number} day The day for this date. + @return {CDate} The date object. + @throws Error if an invalid date. */ + function CDate(calendar, year, month, day) { + this._calendar = calendar; + this._year = year; + this._month = month; + this._day = day; + if (this._calendar._validateLevel === 0 && + !this._calendar.isValid(this._year, this._month, this._day)) { + throw ($.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate). + replace(/\{0\}/, this._calendar.local.name); + } + } + + /** Pad a numeric value with leading zeroes. + @private + @param {number} value The number to format. + @param {number} length The minimum length. + @return {string} The formatted number. */ + function pad(value, length) { + value = '' + value; + return '000000'.substring(0, length - value.length) + value; + } + + $.extend(CDate.prototype, { + + /** Create a new date. + @memberof CDate + @param {CDate|number} [year] The date to copy or the year for the date (default to this date). + @param {number} [month] The month for the date (if numeric year specified above). + @param {number} [day] The day for the date (if numeric year specified above). + @return {CDate} The new date. + @throws Error if an invalid date. + @example date.newDate() +date.newDate(otherDate) +date.newDate(2001, 1, 1) */ + newDate: function(year, month, day) { + return this._calendar.newDate((typeof year === 'undefined' || year === null ? this : year), month, day); + }, + + /** Set or retrieve the year for this date. + @memberof CDate + @param {number} [year] The year for the date. + @return {number|CDate} The date's year (if no parameter) or the updated date. + @throws Error if an invalid date. + @example date.year(2001) +var year = date.year() */ + year: function(year) { + return (arguments.length === 0 ? this._year : this.set(year, 'y')); + }, + + /** Set or retrieve the month for this date. + @memberof CDate + @param {number} [month] The month for the date. + @return {number|CDate} The date's month (if no parameter) or the updated date. + @throws Error if an invalid date. + @example date.month(1) +var month = date.month() */ + month: function(month) { + return (arguments.length === 0 ? this._month : this.set(month, 'm')); + }, + + /** Set or retrieve the day for this date. + @memberof CDate + @param {number} [day] The day for the date. + @return {number|CData} The date's day (if no parameter) or the updated date. + @throws Error if an invalid date. + @example date.day(1) +var day = date.day() */ + day: function(day) { + return (arguments.length === 0 ? this._day : this.set(day, 'd')); + }, + + /** Set new values for this date. + @memberof CDate + @param {number} year The year for the date. + @param {number} month The month for the date. + @param {number} day The day for the date. + @return {CDate} The updated date. + @throws Error if an invalid date. + @example date.date(2001, 1, 1) */ + date: function(year, month, day) { + if (!this._calendar.isValid(year, month, day)) { + throw ($.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate). + replace(/\{0\}/, this._calendar.local.name); + } + this._year = year; + this._month = month; + this._day = day; + return this; + }, + + /** Determine whether this date is in a leap year. + @memberof CDate + @return {boolean} true if this is a leap year, false if not. + @example if (date.leapYear()) ...*/ + leapYear: function() { + return this._calendar.leapYear(this); + }, + + /** Retrieve the epoch designator for this date, e.g. BCE or CE. + @memberof CDate + @return {string} The current epoch. + @example var epoch = date.epoch() */ + epoch: function() { + return this._calendar.epoch(this); + }, + + /** Format the year, if not a simple sequential number. + @memberof CDate + @return {string} The formatted year. + @example var year = date.formatYear() */ + formatYear: function() { + return this._calendar.formatYear(this); + }, + + /** Retrieve the month of the year for this date, + i.e. the month's position within a numbered year. + @memberof CDate + @return {number} The month of the year: minMonth to months per year. + @example var month = date.monthOfYear() */ + monthOfYear: function() { + return this._calendar.monthOfYear(this); + }, + + /** Retrieve the week of the year for this date. + @memberof CDate + @return {number} The week of the year: 1 to weeks per year. + @example var week = date.weekOfYear() */ + weekOfYear: function() { + return this._calendar.weekOfYear(this); + }, + + /** Retrieve the number of days in the year for this date. + @memberof CDate + @return {number} The number of days in this year. + @example var days = date.daysInYear() */ + daysInYear: function() { + return this._calendar.daysInYear(this); + }, + + /** Retrieve the day of the year for this date. + @memberof CDate + @return {number} The day of the year: 1 to days per year. + @example var doy = date.dayOfYear() */ + dayOfYear: function() { + return this._calendar.dayOfYear(this); + }, + + /** Retrieve the number of days in the month for this date. + @memberof CDate + @return {number} The number of days. + @example var days = date.daysInMonth() */ + daysInMonth: function() { + return this._calendar.daysInMonth(this); + }, + + /** Retrieve the day of the week for this date. + @memberof CDate + @return {number} The day of the week: 0 to number of days - 1. + @example var dow = date.dayOfWeek() */ + dayOfWeek: function() { + return this._calendar.dayOfWeek(this); + }, + + /** Determine whether this date is a week day. + @memberof CDate + @return {boolean} true if a week day, false if not. + @example if (date.weekDay()) ... */ + weekDay: function() { + return this._calendar.weekDay(this); + }, + + /** Retrieve additional information about this date. + @memberof CDate + @return {object} Additional information - contents depends on calendar. + @example var info = date.extraInfo() */ + extraInfo: function() { + return this._calendar.extraInfo(this); + }, + + /** Add period(s) to a date. + @memberof CDate + @param {number} offset The number of periods to adjust by. + @param {string} period One of 'y' for years, 'm' for months, 'w' for weeks, 'd' for days. + @return {CDate} The updated date. + @example date.add(10, 'd') */ + add: function(offset, period) { + return this._calendar.add(this, offset, period); + }, + + /** Set a portion of the date. + @memberof CDate + @param {number} value The new value for the period. + @param {string} period One of 'y' for year, 'm' for month, 'd' for day. + @return {CDate} The updated date. + @throws Error if not a valid date. + @example date.set(10, 'd') */ + set: function(value, period) { + return this._calendar.set(this, value, period); + }, + + /** Compare this date to another date. + @memberof CDate + @param {CDate} date The other date. + @return {number} -1 if this date is before the other date, + 0 if they are equal, or +1 if this date is after the other date. + @example if (date1.compareTo(date2) < 0) ... */ + compareTo: function(date) { + if (this._calendar.name !== date._calendar.name) { + throw ($.calendars.local.differentCalendars || $.calendars.regionalOptions[''].differentCalendars). + replace(/\{0\}/, this._calendar.local.name).replace(/\{1\}/, date._calendar.local.name); + } + var c = (this._year !== date._year ? this._year - date._year : + this._month !== date._month ? this.monthOfYear() - date.monthOfYear() : + this._day - date._day); + return (c === 0 ? 0 : (c < 0 ? -1 : +1)); + }, + + /** Retrieve the calendar backing this date. + @memberof CDate + @return {BaseCalendar} The calendar implementation. + @example var cal = date.calendar() */ + calendar: function() { + return this._calendar; + }, + + /** Retrieve the Julian date equivalent for this date, + i.e. days since January 1, 4713 BCE Greenwich noon. + @memberof CDate + @return {number} The equivalent Julian date. + @example var jd = date.toJD() */ + toJD: function() { + return this._calendar.toJD(this); + }, + + /** Create a new date from a Julian date. + @memberof CDate + @param {number} jd The Julian date to convert. + @return {CDate} The equivalent date. + @example var date2 = date1.fromJD(jd) */ + fromJD: function(jd) { + return this._calendar.fromJD(jd); + }, + + /** Convert this date to a standard (Gregorian) JavaScript Date. + @memberof CDate + @return {Date} The equivalent JavaScript date. + @example var jsd = date.toJSDate() */ + toJSDate: function() { + return this._calendar.toJSDate(this); + }, + + /** Create a new date from a standard (Gregorian) JavaScript Date. + @memberof CDate + @param {Date} jsd The JavaScript date to convert. + @return {CDate} The equivalent date. + @example var date2 = date1.fromJSDate(jsd) */ + fromJSDate: function(jsd) { + return this._calendar.fromJSDate(jsd); + }, + + /** Convert to a string for display. + @memberof CDate + @return {string} This date as a string. */ + toString: function() { + return (this.year() < 0 ? '-' : '') + pad(Math.abs(this.year()), 4) + + '-' + pad(this.month(), 2) + '-' + pad(this.day(), 2); + } + }); + + /** Basic functionality for all calendars. + Other calendars should extend this: +
OtherCalendar.prototype = new BaseCalendar();
+ @class BaseCalendar */ + function BaseCalendar() { + this.shortYearCutoff = '+10'; + } + + $.extend(BaseCalendar.prototype, { + _validateLevel: 0, // "Stack" to turn validation on/off + + /** Create a new date within this calendar - today if no parameters given. + @memberof BaseCalendar + @param {CDate|number} year The date to duplicate or the year for the date. + @param {number} [month] The month for the date (if numeric year specified above). + @param {number} [day] The day for the date (if numeric year specified above). + @return {CDate} The new date. + @throws Error if not a valid date or a different calendar is used. + @example var date = calendar.newDate(2014, 1, 26) +var date2 = calendar.newDate(date1) +var today = calendar.newDate() */ + newDate: function(year, month, day) { + if (typeof year === 'undefined' || year === null) { + return this.today(); + } + if (year.year) { + this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + day = year.day(); + month = year.month(); + year = year.year(); + } + return new CDate(this, year, month, day); + }, + + /** Create a new date for today. + @memberof BaseCalendar + @return {CDate} Today's date. + @example var today = calendar.today() */ + today: function() { + return this.fromJSDate(new Date()); + }, + + /** Retrieve the epoch designator for this date. + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {string} The current epoch. + @throws Error if an invalid year or a different calendar is used. + @example var epoch = calendar.epoch(date) +var epoch = calendar.epoch(2014) */ + epoch: function(year) { + var date = this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + return (date.year() < 0 ? this.local.epochs[0] : this.local.epochs[1]); + }, + + /** Format the year, if not a simple sequential number + @memberof BaseCalendar + @param {CDate|number} year The date to format or the year to format. + @return {string} The formatted year. + @throws Error if an invalid year or a different calendar is used. + @example var year = calendar.formatYear(date) +var year = calendar.formatYear(2014) */ + formatYear: function(year) { + var date = this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + return (date.year() < 0 ? '-' : '') + pad(Math.abs(date.year()), 4); + }, + + /** Retrieve the number of months in a year. + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {number} The number of months. + @throws Error if an invalid year or a different calendar is used. + @example var months = calendar.monthsInYear(date) +var months = calendar.monthsInYear(2014) */ + monthsInYear: function(year) { + this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + return 12; + }, + + /** Calculate the month's ordinal position within the year - + for those calendars that don't start at month 1! + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if numeric year specified above). + @return {number} The ordinal position, starting from minMonth. + @throws Error if an invalid year/month or a different calendar is used. + @example var pos = calendar.monthOfYear(date) +var pos = calendar.monthOfYear(2014, 7) */ + monthOfYear: function(year, month) { + var date = this._validate(year, month, this.minDay, + $.calendars.local.invalidMonth || $.calendars.regionalOptions[''].invalidMonth); + return (date.month() + this.monthsInYear(date) - this.firstMonth) % + this.monthsInYear(date) + this.minMonth; + }, + + /** Calculate actual month from ordinal position, starting from minMonth. + @memberof BaseCalendar + @param {number} year The year to examine. + @param {number} ord The month's ordinal position. + @return {number} The month's number. + @throws Error if an invalid year/month. + @example var month = calendar.fromMonthOfYear(2014, 7) */ + fromMonthOfYear: function(year, ord) { + var m = (ord + this.firstMonth - 2 * this.minMonth) % + this.monthsInYear(year) + this.minMonth; + this._validate(year, m, this.minDay, + $.calendars.local.invalidMonth || $.calendars.regionalOptions[''].invalidMonth); + return m; + }, + + /** Retrieve the number of days in a year. + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {number} The number of days. + @throws Error if an invalid year or a different calendar is used. + @example var days = calendar.daysInYear(date) +var days = calendar.daysInYear(2014) */ + daysInYear: function(year) { + var date = this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + return (this.leapYear(date) ? 366 : 365); + }, + + /** Retrieve the day of the year for a date. + @memberof BaseCalendar + @param {CDate|number} year The date to convert or the year to convert. + @param {number} [month] The month to convert (if numeric year specified above). + @param {number} [day] The day to convert (if numeric year specified above). + @return {number} The day of the year: 1 to days per year. + @throws Error if an invalid date or a different calendar is used. + @example var doy = calendar.dayOfYear(date) +var doy = calendar.dayOfYear(2014, 7, 1) */ + dayOfYear: function(year, month, day) { + var date = this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + return date.toJD() - this.newDate(date.year(), + this.fromMonthOfYear(date.year(), this.minMonth), this.minDay).toJD() + 1; + }, + + /** Retrieve the number of days in a week. + @memberof BaseCalendar + @return {number} The number of days. + @example var days = calendar.daysInWeek() */ + daysInWeek: function() { + return 7; + }, + + /** Retrieve the day of the week for a date. + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if numeric year specified above). + @param {number} [day] The day to examine (if numeric year specified above). + @return {number} The day of the week: 0 to number of days - 1. + @throws Error if an invalid date or a different calendar is used. + @example var dow = calendar.dayOfWeek(date) +var dow = calendar.dayOfWeek(2014, 1, 26) */ + dayOfWeek: function(year, month, day) { + var date = this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + return (Math.floor(this.toJD(date)) + 2) % this.daysInWeek(); + }, + + /** Retrieve additional information about a date. + @memberof BaseCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if numeric year specified above). + @param {number} [day] The day to examine (if numeric year specified above). + @return {object} Additional information - content depends on calendar. + @throws Error if an invalid date or a different calendar is used. + @example var info = calendar.extraInfo(date) +var info = calendar.extraInfo(2014, 1, 26) */ + extraInfo: function(year, month, day) { + this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + return {}; + }, + + /** Add period(s) to a date. + Cater for no year zero. + @memberof BaseCalendar + @param {CDate} date The starting date. + @param {number} offset The number of periods to adjust by. + @param {string} period One of 'y' for years, 'm' for months, 'w' for weeks, 'd' for days. + @return {CDate} The updated date. + @throws Error if a different calendar is used. + @example calendar.add(date, 10, 'd') */ + add: function(date, offset, period) { + this._validate(date, this.minMonth, this.minDay, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + return this._correctAdd(date, this._add(date, offset, period), offset, period); + }, + + /** Add period(s) to a date. + @memberof BaseCalendar + @private + @param {CDate} date The starting date. + @param {number} offset The number of periods to adjust by. + @param {string} period One of 'y' for years, 'm' for months, 'w' for weeks, 'd' for days. + @return {number[]} The updated date as year, month, and day. */ + _add: function(date, offset, period) { + this._validateLevel++; + var d; + if (period === 'd' || period === 'w') { + var jd = date.toJD() + offset * (period === 'w' ? this.daysInWeek() : 1); + d = date.calendar().fromJD(jd); + this._validateLevel--; + return [d.year(), d.month(), d.day()]; + } + try { + var y = date.year() + (period === 'y' ? offset : 0); + var m = date.monthOfYear() + (period === 'm' ? offset : 0); + d = date.day(); + var resyncYearMonth = function(calendar) { + while (m < calendar.minMonth) { + y--; + m += calendar.monthsInYear(y); + } + var yearMonths = calendar.monthsInYear(y); + while (m > yearMonths - 1 + calendar.minMonth) { + y++; + m -= yearMonths; + yearMonths = calendar.monthsInYear(y); + } + }; + if (period === 'y') { + if (date.month() !== this.fromMonthOfYear(y, m)) { // Hebrew + m = this.newDate(y, date.month(), this.minDay).monthOfYear(); + } + m = Math.min(m, this.monthsInYear(y)); + d = Math.min(d, this.daysInMonth(y, this.fromMonthOfYear(y, m))); + } + else if (period === 'm') { + resyncYearMonth(this); + d = Math.min(d, this.daysInMonth(y, this.fromMonthOfYear(y, m))); + } + var ymd = [y, this.fromMonthOfYear(y, m), d]; + this._validateLevel--; + return ymd; + } + catch (e) { + this._validateLevel--; + throw e; + } + }, + + /** Correct a candidate date after adding period(s) to a date. + Handle no year zero if necessary. + @memberof BaseCalendar + @private + @param {CDate} date The starting date. + @param {number[]} ymd The added date. + @param {number} offset The number of periods to adjust by. + @param {string} period One of 'y' for years, 'm' for months, 'w' for weeks, 'd' for days. + @return {CDate} The updated date. */ + _correctAdd: function(date, ymd, offset, period) { + if (!this.hasYearZero && (period === 'y' || period === 'm')) { + if (ymd[0] === 0 || // In year zero + (date.year() > 0) !== (ymd[0] > 0)) { // Crossed year zero + var adj = {y: [1, 1, 'y'], m: [1, this.monthsInYear(-1), 'm'], + w: [this.daysInWeek(), this.daysInYear(-1), 'd'], + d: [1, this.daysInYear(-1), 'd']}[period]; + var dir = (offset < 0 ? -1 : +1); + ymd = this._add(date, offset * adj[0] + dir * adj[1], adj[2]); + } + } + return date.date(ymd[0], ymd[1], ymd[2]); + }, + + /** Set a portion of the date. + @memberof BaseCalendar + @param {CDate} date The starting date. + @param {number} value The new value for the period. + @param {string} period One of 'y' for year, 'm' for month, 'd' for day. + @return {CDate} The updated date. + @throws Error if an invalid date or a different calendar is used. + @example calendar.set(date, 10, 'd') */ + set: function(date, value, period) { + this._validate(date, this.minMonth, this.minDay, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + var y = (period === 'y' ? value : date.year()); + var m = (period === 'm' ? value : date.month()); + var d = (period === 'd' ? value : date.day()); + if (period === 'y' || period === 'm') { + d = Math.min(d, this.daysInMonth(y, m)); + } + return date.date(y, m, d); + }, + + /** Determine whether a date is valid for this calendar. + @memberof BaseCalendar + @param {number} year The year to examine. + @param {number} month The month to examine. + @param {number} day The day to examine. + @return {boolean} true if a valid date, false if not. + @example if (calendar.isValid(2014, 2, 31)) ... */ + isValid: function(year, month, day) { + this._validateLevel++; + var valid = (this.hasYearZero || year !== 0); + if (valid) { + var date = this.newDate(year, month, this.minDay); + valid = (month >= this.minMonth && month - this.minMonth < this.monthsInYear(date)) && + (day >= this.minDay && day - this.minDay < this.daysInMonth(date)); + } + this._validateLevel--; + return valid; + }, + + /** Convert the date to a standard (Gregorian) JavaScript Date. + @memberof BaseCalendar + @param {CDate|number} year The date to convert or the year to convert. + @param {number} [month] The month to convert (if numeric year specified above). + @param {number} [day] The day to convert (if numeric year specified above). + @return {Date} The equivalent JavaScript date. + @throws Error if an invalid date or a different calendar is used. + @example var jsd = calendar.toJSDate(date) +var jsd = calendar.toJSDate(2014, 1, 26) */ + toJSDate: function(year, month, day) { + var date = this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + return $.calendars.instance().fromJD(this.toJD(date)).toJSDate(); + }, + + /** Convert the date from a standard (Gregorian) JavaScript Date. + @memberof BaseCalendar + @param {Date} jsd The JavaScript date. + @return {CDate} The equivalent calendar date. + @example var date = calendar.fromJSDate(jsd) */ + fromJSDate: function(jsd) { + return this.fromJD($.calendars.instance().fromJSDate(jsd).toJD()); + }, + + /** Check that a candidate date is from the same calendar and is valid. + @memberof BaseCalendar + @private + @param {CDate|number} year The date to validate or the year to validate. + @param {number} [month] The month to validate (if numeric year specified above). + @param {number} [day] The day to validate (if numeric year specified above). + @param {string} error Error message if invalid. + @throws Error if an invalid date or a different calendar is used. */ + _validate: function(year, month, day, error) { + if (year.year) { + if (this._validateLevel === 0 && this.name !== year.calendar().name) { + throw ($.calendars.local.differentCalendars || $.calendars.regionalOptions[''].differentCalendars). + replace(/\{0\}/, this.local.name).replace(/\{1\}/, year.calendar().local.name); + } + return year; + } + try { + this._validateLevel++; + if (this._validateLevel === 1 && !this.isValid(year, month, day)) { + throw error.replace(/\{0\}/, this.local.name); + } + var date = this.newDate(year, month, day); + this._validateLevel--; + return date; + } + catch (e) { + this._validateLevel--; + throw e; + } + } + }); + + /** Implementation of the Proleptic Gregorian Calendar. + See http://en.wikipedia.org/wiki/Gregorian_calendar + and http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar. + @class GregorianCalendar + @augments BaseCalendar + @param {string} [language=''] The language code (default English) for localisation. */ + function GregorianCalendar(language) { + this.local = this.regionalOptions[language] || this.regionalOptions['']; + } + + GregorianCalendar.prototype = new BaseCalendar(); + + $.extend(GregorianCalendar.prototype, { + /** The calendar name. + @memberof GregorianCalendar */ + name: 'Gregorian', + /** Julian date of start of Gregorian epoch: 1 January 0001 CE. + @memberof GregorianCalendar */ + jdEpoch: 1721425.5, + /** Days per month in a common year. + @memberof GregorianCalendar */ + daysPerMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + /** true if has a year zero, false if not. + @memberof GregorianCalendar */ + hasYearZero: false, + /** The minimum month number. + @memberof GregorianCalendar */ + minMonth: 1, + /** The first month in the year. + @memberof GregorianCalendar */ + firstMonth: 1, + /** The minimum day number. + @memberof GregorianCalendar */ + minDay: 1, + + /** Convert a number into a localised form. + @callback CalendarsDigits + @param {number} value The number to convert. + @return {string} The localised number. + @example digits: $.calendars.substituteDigits(['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']) */ + + /** Localisations for the plugin. + Entries are objects indexed by the language code ('' being the default US/English). + Each object has the following attributes. + @memberof GregorianCalendar + @property {string} [name='Gregorian'] The calendar name. + @property {string[]} [epochs=['BCE','CE']] The epoch names. + @property {string[]} [monthNames=[...]] The long names of the months of the year. + @property {string[]} [monthNamesShort=[...]] The short names of the months of the year. + @property {string[]} [dayNames=[...]] The long names of the days of the week. + @property {string[]} [dayNamesShort=[...]] The short names of the days of the week. + @property {string[]} [dayNamesMin=[...]] The minimal names of the days of the week. + @property {CalendarsDigits} [digits=null] Convert numbers to localised versions. + @property {string} [dateFormat='mm/dd/yyyy'] The date format for this calendar. + See the options on {@linkcode BaseCalendar.formatDate|formatDate} for details. + @property {number} [firstDay=0] The number of the first day of the week, starting at 0. + @property {boolean} [isRTL=false] true if this localisation reads right-to-left. */ + regionalOptions: { // Localisations + '': { + name: 'Gregorian', + epochs: ['BCE', 'CE'], + monthNames: ['January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + digits: null, + dateFormat: 'mm/dd/yyyy', + firstDay: 0, + isRTL: false + } + }, + + /** Determine whether this date is in a leap year. + @memberof GregorianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @return {boolean} true if this is a leap year, false if not. + @throws Error if an invalid year or a different calendar is used. */ + leapYear: function(year) { + var date = this._validate(year, this.minMonth, this.minDay, + $.calendars.local.invalidYear || $.calendars.regionalOptions[''].invalidYear); + year = date.year() + (date.year() < 0 ? 1 : 0); // No year zero + return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); + }, + + /** Determine the week of the year for a date - ISO 8601. + @memberof GregorianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if numeric year specified above). + @param {number} [day] The day to examine (if numeric year specified above). + @return {number} The week of the year, starting from 1. + @throws Error if an invalid date or a different calendar is used. */ + weekOfYear: function(year, month, day) { + // Find Thursday of this week starting on Monday + var checkDate = this.newDate(year, month, day); + checkDate.add(4 - (checkDate.dayOfWeek() || 7), 'd'); + return Math.floor((checkDate.dayOfYear() - 1) / 7) + 1; + }, + + /** Retrieve the number of days in a month. + @memberof GregorianCalendar + @param {CDate|number} year The date to examine or the year of the month. + @param {number} [month] The month (if numeric year specified above). + @return {number} The number of days in this month. + @throws Error if an invalid month/year or a different calendar is used. */ + daysInMonth: function(year, month) { + var date = this._validate(year, month, this.minDay, + $.calendars.local.invalidMonth || $.calendars.regionalOptions[''].invalidMonth); + return this.daysPerMonth[date.month() - 1] + + (date.month() === 2 && this.leapYear(date.year()) ? 1 : 0); + }, + + /** Determine whether this date is a week day. + @memberof GregorianCalendar + @param {CDate|number} year The date to examine or the year to examine. + @param {number} [month] The month to examine (if numeric year specified above). + @param {number} [day] The day to examine (if numeric year specified above). + @return {boolean} true if a week day, false if not. + @throws Error if an invalid date or a different calendar is used. */ + weekDay: function(year, month, day) { + return (this.dayOfWeek(year, month, day) || 7) < 6; + }, + + /** Retrieve the Julian date equivalent for this date, + i.e. days since January 1, 4713 BCE Greenwich noon. + @memberof GregorianCalendar + @param {CDate|number} year The date to convert or the year to convert. + @param {number} [month] The month to convert (if numeric year specified above). + @param {number} [day] The day to convert (if numeric year specified above). + @return {number} The equivalent Julian date. + @throws Error if an invalid date or a different calendar is used. */ + toJD: function(year, month, day) { + var date = this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + year = date.year(); + month = date.month(); + day = date.day(); + if (year < 0) { year++; } // No year zero + // Jean Meeus algorithm, "Astronomical Algorithms", 1991 + if (month < 3) { + month += 12; + year--; + } + var a = Math.floor(year / 100); + var b = 2 - a + Math.floor(a / 4); + return Math.floor(365.25 * (year + 4716)) + + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5; + }, + + /** Create a new date from a Julian date. + @memberof GregorianCalendar + @param {number} jd The Julian date to convert. + @return {CDate} The equivalent date. */ + fromJD: function(jd) { + // Jean Meeus algorithm, "Astronomical Algorithms", 1991 + var z = Math.floor(jd + 0.5); + var a = Math.floor((z - 1867216.25) / 36524.25); + a = z + 1 + a - Math.floor(a / 4); + var b = a + 1524; + var c = Math.floor((b - 122.1) / 365.25); + var d = Math.floor(365.25 * c); + var e = Math.floor((b - d) / 30.6001); + var day = b - d - Math.floor(e * 30.6001); + var month = e - (e > 13.5 ? 13 : 1); + var year = c - (month > 2.5 ? 4716 : 4715); + if (year <= 0) { year--; } // No year zero + return this.newDate(year, month, day); + }, + + /** Convert this date to a standard (Gregorian) JavaScript Date. + @memberof GregorianCalendar + @param {CDate|number} year The date to convert or the year to convert. + @param {number} [month] The month to convert (if numeric year specified above). + @param {number} [day] The day to convert (if numeric year specified above). + @return {Date} The equivalent JavaScript date. + @throws Error if an invalid date or a different calendar is used. */ + toJSDate: function(year, month, day) { + var date = this._validate(year, month, day, + $.calendars.local.invalidDate || $.calendars.regionalOptions[''].invalidDate); + var jsd = new Date(date.year(), date.month() - 1, date.day()); + jsd.setHours(0); + jsd.setMinutes(0); + jsd.setSeconds(0); + jsd.setMilliseconds(0); + // Hours may be non-zero on daylight saving cut-over: + // > 12 when midnight changeover, but then cannot generate + // midnight datetime, so jump to 1AM, otherwise reset. + jsd.setHours(jsd.getHours() > 12 ? jsd.getHours() + 2 : 0); + return jsd; + }, + + /** Create a new date from a standard (Gregorian) JavaScript Date. + @memberof GregorianCalendar + @param {Date} jsd The JavaScript date to convert. + @return {CDate} The equivalent date. */ + fromJSDate: function(jsd) { + return this.newDate(jsd.getFullYear(), jsd.getMonth() + 1, jsd.getDate()); + } + }); + + // Singleton manager + $.calendars = new Calendars(); + + // Date template + $.calendars.cdate = CDate; + + // Base calendar template + $.calendars.baseCalendar = BaseCalendar; + + // Gregorian calendar implementation + $.calendars.calendars.gregorian = GregorianCalendar; + +})(jQuery); diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.picker.js b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.picker.js new file mode 100644 index 000000000..899448f82 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.picker.js @@ -0,0 +1,1946 @@ +/* http://keith-wood.name/calendars.html + Calendars date picker for jQuery v2.1.0. + Written by Keith Wood (wood.keith{at}optusnet.com.au) August 2009. + Available under the MIT (http://keith-wood.name/licence.html) license. + Please attribute the author if you use it. */ + +(function($) { // Hide scope, no $ conflict + 'use strict'; + + var pluginName = 'calendarsPicker'; + + /** Create the calendars datepicker plugin. +

Sets an input field to popup a calendar for date entry, + or a div or span to show an inline calendar.

+

Expects HTML like:

+
<input type="text"> or <div></div>
+

Provide inline configuration like:

+
<input type="text" data-calendarsPicker="name: 'value'"/>
+ @class CalendarsPicker + @augments JQPlugin + @example $(selector).calendarsPicker() +$(selector).calendarsPicker({minDate: 0, maxDate: '+1m +1w'}) */ + $.JQPlugin.createPlugin({ + + /** The name of the plugin. + @memberof CalendarsPicker + @default 'calendarsPicker' */ + name: pluginName, + + /** Default template for generating a datepicker. + Insert anywhere: +
    +
  • '{l10n:name}' to insert localised value for name,
  • +
  • '{link:name}' to insert a link trigger for command name,
  • +
  • '{button:name}' to insert a button trigger for command name,
  • +
  • '{popup:start}...{popup:end}' to mark a section for inclusion in a popup datepicker only,
  • +
  • '{inline:start}...{inline:end}' to mark a section for inclusion in an inline datepicker only.
  • +
+ @memberof CalendarsPicker + @property {string} picker Overall structure: '{months}' to insert calendar months. + @property {string} monthRow One row of months: '{months}' to insert calendar months. + @property {string} month A single month: '{monthHeader:dateFormat}' to insert the month header - + dateFormat is optional and defaults to 'MM yyyy', + '{weekHeader}' to insert a week header, '{weeks}' to insert the month's weeks. + @property {string} weekHeader A week header: '{days}' to insert individual day names. + @property {string} dayHeader Individual day header: '{day}' to insert day name. + @property {string} week One week of the month: '{days}' to insert the week's days, + '{weekOfYear}' to insert week of year. + @property {string} day An individual day: '{day}' to insert day value. + @property {string} monthSelector jQuery selector, relative to picker, for a single month. + @property {string} daySelector jQuery selector, relative to picker, for individual days. + @property {string} rtlClass Class for right-to-left (RTL) languages. + @property {string} multiClass Class for multi-month datepickers. + @property {string} defaultClass Class for selectable dates. + @property {string} selectedClass Class for currently selected dates. + @property {string} highlightedClass Class for highlighted dates. + @property {string} todayClass Class for today. + @property {string} otherMonthClass Class for days from other months. + @property {string} weekendClass Class for days on weekends. + @property {string} commandClass Class prefix for commands. + @property {string} commandButtonClass Extra class(es) for commands that are buttons. + @property {string} commandLinkClass Extra class(es) for commands that are links. + @property {string} disabledClass Class for disabled commands. */ + defaultRenderer: { + picker: '
' + + '
{link:prev}{link:today}{link:next}
{months}' + + '{popup:start}
{link:clear}{link:close}
{popup:end}' + + '
', + monthRow: '
{months}
', + month: '
{monthHeader}
' + + '{weekHeader}{weeks}
', + weekHeader: '{days}', + dayHeader: '{day}', + week: '{days}', + day: '{day}', + monthSelector: '.calendars-month', + daySelector: 'td', + rtlClass: 'calendars-rtl', + multiClass: 'calendars-multi', + defaultClass: '', + selectedClass: 'calendars-selected', + highlightedClass: 'calendars-highlight', + todayClass: 'calendars-today', + otherMonthClass: 'calendars-other-month', + weekendClass: 'calendars-weekend', + commandClass: 'calendars-cmd', + commandButtonClass: '', + commandLinkClass: '', + disabledClass: 'calendars-disabled' + }, + + /** Command actions that may be added to a layout by name. +
    +
  • prev - Show the previous month (based on monthsToStep option) - PageUp
  • +
  • prevJump - Show the previous year (based on monthsToJump option) - Ctrl+PageUp
  • +
  • next - Show the next month (based on monthsToStep option) - PageDown
  • +
  • nextJump - Show the next year (based on monthsToJump option) - Ctrl+PageDown
  • +
  • current - Show the currently selected month or today's if none selected - Ctrl+Home
  • +
  • today - Show today's month - Ctrl+Home
  • +
  • clear - Erase the date and close the datepicker popup - Ctrl+End
  • +
  • close - Close the datepicker popup - Esc
  • +
  • prevWeek - Move the cursor to the previous week - Ctrl+Up
  • +
  • prevDay - Move the cursor to the previous day - Ctrl+Left
  • +
  • nextDay - Move the cursor to the next day - Ctrl+Right
  • +
  • nextWeek - Move the cursor to the next week - Ctrl+Down
  • +
+ The command name is the key name and is used to add the command to a layout + with '{button:name}' or '{link:name}'. Each has the following attributes. + @memberof CalendarsPicker + @property {string} text The field in the regional settings for the displayed text. + @property {string} status The field in the regional settings for the status text. + @property {object} keystroke The keystroke to trigger the action, with attributes: + @property {number} keystroke.keyCode the code for the keystroke, + @property {boolean} [keystroke.ctrlKey] true if Ctrl is required, + @property {boolean} [keystroke.altKey] true if Alt is required, + @property {boolean} [keystroke.shiftKey] true if Shift is required. + @property {CalendarsPickerCommandEnabled} enabled The function that indicates the command is enabled. + @property {CalendarsPickerCommandDate} date The function to get the date associated with this action. + @property {CalendarsPickerCommandAction} action The function that implements the action. */ + commands: { + prev: { + text: 'prevText', + status: 'prevStatus', // Previous month + keystroke: {keyCode: 33}, // Page up + enabled: function(inst) { + var minDate = inst.curMinDate(); + return (!minDate || inst.drawDate.newDate(). + add(1 - inst.options.monthsToStep - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay).add(-1, 'd').compareTo(minDate) !== -1); + }, + date: function(inst) { + return inst.drawDate.newDate(). + add(-inst.options.monthsToStep - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay); + }, + action: function(inst) { + plugin.changeMonth(this, -inst.options.monthsToStep); + } + }, + prevJump: { + text: 'prevJumpText', + status: 'prevJumpStatus', // Previous year + keystroke: {keyCode: 33, ctrlKey: true}, // Ctrl + Page up + enabled: function(inst) { + var minDate = inst.curMinDate(); + return (!minDate || inst.drawDate.newDate(). + add(1 - inst.options.monthsToJump - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay).add(-1, 'd').compareTo(minDate) !== -1); + }, + date: function(inst) { + return inst.drawDate.newDate(). + add(-inst.options.monthsToJump - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay); + }, + action: function(inst) { + plugin.changeMonth(this, -inst.options.monthsToJump); + } + }, + next: { + text: 'nextText', + status: 'nextStatus', // Next month + keystroke: {keyCode: 34}, // Page down + enabled: function(inst) { + var maxDate = inst.get('maxDate'); + return (!maxDate || inst.drawDate.newDate(). + add(inst.options.monthsToStep - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay).compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.drawDate.newDate(). + add(inst.options.monthsToStep - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay); + }, + action: function(inst) { + plugin.changeMonth(this, inst.options.monthsToStep); + } + }, + nextJump: { + text: 'nextJumpText', + status: 'nextJumpStatus', // Next year + keystroke: {keyCode: 34, ctrlKey: true}, // Ctrl + Page down + enabled: function(inst) { + var maxDate = inst.get('maxDate'); + return (!maxDate || inst.drawDate.newDate(). + add(inst.options.monthsToJump - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay).compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.drawDate.newDate(). + add(inst.options.monthsToJump - inst.options.monthsOffset, 'm'). + day(inst.options.calendar.minDay); + }, + action: function(inst) { + plugin.changeMonth(this, inst.options.monthsToJump); + } + }, + current: { + text: 'currentText', + status: 'currentStatus', // Current month + keystroke: {keyCode: 36, ctrlKey: true}, // Ctrl + Home + enabled: function(inst) { + var minDate = inst.curMinDate(); + var maxDate = inst.get('maxDate'); + var curDate = inst.selectedDates[0] || inst.options.calendar.today(); + return (!minDate || curDate.compareTo(minDate) !== -1) && + (!maxDate || curDate.compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.selectedDates[0] || inst.options.calendar.today(); + }, + action: function(inst) { + var curDate = inst.selectedDates[0] || inst.options.calendar.today(); + plugin.showMonth(this, curDate.year(), curDate.month()); + } + }, + today: { + text: 'todayText', + status: 'todayStatus', // Today's month + keystroke: {keyCode: 36, ctrlKey: true}, // Ctrl + Home + enabled: function(inst) { + var minDate = inst.curMinDate(); + var maxDate = inst.get('maxDate'); + return (!minDate || inst.options.calendar.today().compareTo(minDate) !== -1) && + (!maxDate || inst.options.calendar.today().compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.options.calendar.today(); + }, + action: function() { + plugin.showMonth(this); + } + }, + clear: { + text: 'clearText', + status: 'clearStatus', // Clear the datepicker + keystroke: {keyCode: 35, ctrlKey: true}, // Ctrl + End + enabled: function() { return true; }, + date: function() { return null; }, + action: function() { plugin.clear(this); } + }, + close: { + text: 'closeText', + status: 'closeStatus', // Close the datepicker + keystroke: {keyCode: 27}, // Escape + enabled: function() { return true; }, + date: function() { return null; }, + action: function() { plugin.hide(this); } + }, + prevWeek: { + text: 'prevWeekText', + status: 'prevWeekStatus', // Previous week + keystroke: {keyCode: 38, ctrlKey: true}, // Ctrl + Up + enabled: function(inst) { + var minDate = inst.curMinDate(); + return (!minDate || inst.drawDate.newDate(). + add(-inst.options.calendar.daysInWeek(), 'd').compareTo(minDate) !== -1); + }, + date: function(inst) { + return inst.drawDate.newDate().add(-inst.options.calendar.daysInWeek(), 'd'); + }, + action: function(inst) { + plugin.changeDay(this, -inst.options.calendar.daysInWeek()); + } + }, + prevDay: { + text: 'prevDayText', + status: 'prevDayStatus', // Previous day + keystroke: {keyCode: 37, ctrlKey: true}, // Ctrl + Left + enabled: function(inst) { + var minDate = inst.curMinDate(); + return (!minDate || inst.drawDate.newDate().add(-1, 'd').compareTo(minDate) !== -1); + }, + date: function(inst) { + return inst.drawDate.newDate().add(-1, 'd'); + }, + action: function() { + plugin.changeDay(this, -1); + } + }, + nextDay: { + text: 'nextDayText', + status: 'nextDayStatus', // Next day + keystroke: {keyCode: 39, ctrlKey: true}, // Ctrl + Right + enabled: function(inst) { + var maxDate = inst.get('maxDate'); + return (!maxDate || inst.drawDate.newDate().add(1, 'd').compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.drawDate.newDate().add(1, 'd'); + }, + action: function() { + plugin.changeDay(this, 1); + } + }, + nextWeek: { + text: 'nextWeekText', + status: 'nextWeekStatus', // Next week + keystroke: {keyCode: 40, ctrlKey: true}, // Ctrl + Down + enabled: function(inst) { + var maxDate = inst.get('maxDate'); + return (!maxDate || inst.drawDate.newDate(). + add(inst.options.calendar.daysInWeek(), 'd').compareTo(maxDate) !== +1); + }, + date: function(inst) { + return inst.drawDate.newDate().add(inst.options.calendar.daysInWeek(), 'd'); + }, + action: function(inst) { + plugin.changeDay(this, inst.options.calendar.daysInWeek()); + } + } + }, + + /** Determine whether a command is enabled. + @callback CalendarsPickerCommandEnabled + @param {object} inst The current instance settings. + @return {boolean} true if this command is enabled, false if not. + @example enabled: function(inst) { + return !!inst.curMinDate(); +} */ + + /** Calculate the representative date for a command. + @callback CalendarsPickerCommandDate + @param {object} inst The current instance settings. + @return {CDate} A date appropriate for this command. + @example date: function(inst) { + return inst.curMinDate(); +} */ + + /** Perform the action for a command. + @callback CalendarsPickerCommandAction + @param {object} inst The current instance settings. + @example date: function(inst) { + $.datepick.setDate(inst.elem, inst.curMinDate()); +} */ + + /** Calculate the week of the year for a date. + @callback CalendarsPickerCalculateWeek + @param {CDate} date The date to evaluate. + @return {number} The week of the year. + @example calculateWeek: function(date) { + var startYear = date.newDate(date.year(), 1, 1); + return Math.floor((date.dayOfYear() - startYear.dayOfYear()) / 7) + 1; +} */ + + /** Provide information about an individual date shown in the calendar. + @callback CalendarsPickerOnDate + @param {CDate} date The date to evaluate. + @return {object} Information about that date, with the properties above. + @property {boolean} selectable true if this date can be selected. + @property {string} dateClass Class(es) to be applied to the date. + @property {string} content The date cell content. + @property {string} tooltip A popup tooltip for the date. + @example onDate: function(date) { + return {selectable: date.day() > 0 && date.day() < 5, + dateClass: date.day() === 4 ? 'last-day' : ''}; +} */ + + /** Update the datepicker display. + @callback CalendarsPickerOnShow + @param {jQuery} picker The datepicker div to be shown. + @param {object} inst The current instance settings. + @example onShow: function(picker, inst) { + picker.append(''). + find('button:last').click(function() { + alert('Hi!'); + }); +} */ + + /** React to navigating through the months/years. + @callback CalendarsPickerOnChangeMonthYear + @param {number} year The new year. + @param {number} month The new month (calendar minimum month to maximum month). + @example onChangeMonthYear: function(year, month) { + alert('Now in ' + month + '/' + year); +} */ + + /** Datepicker on select callback. + Triggered when a date is selected. + @callback CalendarsPickerOnSelect + @param {CDate[]} dates The selected date(s). + @example onSelect: function(dates) { + alert('Selected ' + dates); +} */ + + /** Datepicker on close callback. + Triggered when a popup calendar is closed. + @callback CalendarsPickerOnClose + @param {CDate[]} dates The selected date(s). + @example onClose: function(dates) { + alert('Selected ' + dates); +} */ + + /** Default settings for the plugin. + @memberof CalendarsPicker + @property {Calendar} [calendar=$.calendars.instance()] The calendar for this datepicker. + @property {string} [pickerClass=''] CSS class to add to this instance of the datepicker. + @property {boolean} [showOnFocus=true] true for popup on focus, false for not. + @property {string|Element|jQuery} [showTrigger=null] Element to be cloned for a trigger, + null for none. + @property {string} [showAnim='show'] Name of jQuery animation for popup, '' for no animation. + @property {object} [showOptions=null] Options for enhanced animations. + @property {string|number} [showSpeed='normal'] Duration of display/closure, named or in milliseconds. + @property {string|Element|jQuery} [popupContainer=null] The element to which a popup calendar is added, + null for body. + @property {string} [alignment='bottom'] Alignment of popup - with nominated corner of input: + 'top' or 'bottom' aligns depending on language direction, + 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'. + @property {boolean} [fixedWeeks=false] true to always show 6 weeks, + false to only show as many as are needed. + @property {number} [firstDay=null] First day of the week, 0 = Sunday, 1 = Monday, etc., + null for calendar default. + @property {CalendarsPickerCalculateWeek} [calculateWeek=null] Calculate week of the year from a date, + null for calendar default. + @property {boolean} [localNumbers=false] true to localise numbers (if available), + false to use normal Arabic numerals. + @property {number|number[]} [monthsToShow=1] How many months to show, cols or [rows, cols]. + @property {number} [monthsOffset=0] How many months to offset the primary month by; + may be a function that takes the date and returns the offset. + @property {number} [monthsToStep=1] How many months to move when prev/next clicked. + @property {number} [monthsToJump=12] How many months to move when large prev/next clicked. + @property {boolean} [useMouseWheel=true] true to use mousewheel if available, + false to never use it. + @property {boolean} [changeMonth=true] true to change month/year via drop-down, + false for navigation only. + @property {string} [yearRange='c-10:c+10'] Range of years to show in drop-down: 'any' for direct text entry + or 'start:end', where start/end are '+-nn' for relative to today + or 'c+-nn' for relative to the currently selected date + or 'nnnn' for an absolute year. + @property {boolean} [showOtherMonths=false] true to show dates from other months, + false to not show them. + @property {boolean} [selectOtherMonths=false] true to allow selection of dates + from other months too. + @property {string|number|CDate} [defaultDate=null] Date to show if no other selected. + @property {boolean} [selectDefaultDate=false] true to pre-select the default date + if no other is chosen. + @property {string|number|CDate} [minDate=null] The minimum selectable date. + @property {string|number|CDate} [maxDate=null] The maximum selectable date. + @property {string} [dateFormat='mm/dd/yyyy'] Format for dates. + @property {boolean} [autoSize=false] true to size the input field according to the date format. + @property {boolean} [rangeSelect=false] Allows for selecting a date range on one date picker. + @property {string} [rangeSeparator=' - '] Text between two dates in a range. + @property {number} [multiSelect=0] Maximum number of selectable dates, zero for single select. + @property {string} [multiSeparator=','] Text between multiple dates. + @property {CalendarsPickerOnDate} [onDate=null] Callback as a date is added to the datepicker. + @property {CalendarsPickerOnShow} [onShow=null] Callback just before a datepicker is shown. + @property {CalendarsPickerOnChangeMonthYear} [onChangeMonthYear=null] Callback when a new month/year + is selected. + @property {CalendarsPickerOnSelect} [onSelect=null] Callback when a date is selected. + @property {CalendarsPickerOnClose} [onClose=null] Callback when a datepicker is closed. + @property {string|Element|jQuery} [altField=null] Alternate field to update in synch with the datepicker. + @property {string} [altFormat=null] Date format for alternate field, defaults to dateFormat. + @property {boolean} [constrainInput=true] true to constrain typed input to + dateFormat allowed characters. + @property {boolean} [commandsAsDateFormat=false] true to apply + formatDate to the command texts. + @property {object} [commands=this.commands] Command actions that may be added to a layout by name. + @example $(selector).calendarsPicker({calendar: $.calendars.instance('persian')}) +$(selector).calendarsPicker({monthsToShow: [2, 3], monthsToStep: 6}) +$(selector).calendarsPicker({minDate: $.calendars.newDate(2001, 1, 1), + maxDate: $.calendars.newDate(2010, 12, 31)}) */ + defaultOptions: { + calendar: $.calendars.instance(), + pickerClass: '', + showOnFocus: true, + showTrigger: null, + showAnim: 'show', + showOptions: {}, + showSpeed: 'normal', + popupContainer: null, + alignment: 'bottom', + fixedWeeks: false, + firstDay: null, + calculateWeek: null, + localNumbers: false, + monthsToShow: 1, + monthsOffset: 0, + monthsToStep: 1, + monthsToJump: 12, + useMouseWheel: true, + changeMonth: true, + yearRange: 'c-10:c+10', + showOtherMonths: false, + selectOtherMonths: false, + defaultDate: null, + selectDefaultDate: false, + minDate: null, + maxDate: null, + dateFormat: null, + autoSize: false, + rangeSelect: false, + rangeSeparator: ' - ', + multiSelect: 0, + multiSeparator: ',', + onDate: null, + onShow: null, + onChangeMonthYear: null, + onSelect: null, + onClose: null, + altField: null, + altFormat: null, + constrainInput: true, + commandsAsDateFormat: false, + commands: {} // this.commands + }, + + /** Localisations for the plugin. + Entries are objects indexed by the language code ('' being the default US/English). + Each object has the following attributes. + @memberof CalendarsPicker + @property {string} [renderer=this.defaultRenderer] The rendering templates. + @property {string} [prevText='<Prev'] Text for the previous month command. + @property {string} [prevStatus='Show the previous month'] Status text for the + previous month command. + @property {string} [prevJumpText='<<'] Text for the previous year command. + @property {string} [prevJumpStatus='Show the previous year'] Status text for the + previous year command. + @property {string} [nextText='Next>'] Text for the next month command. + @property {string} [nextStatus='Show the next month'] Status text for the next month command. + @property {string} [nextJumpText='>>'] Text for the next year command. + @property {string} [nextJumpStatus='Show the next year'] Status text for the + next year command. + @property {string} [currentText='Current'] Text for the current month command. + @property {string} [currentStatus='Show the current month'] Status text for the + current month command. + @property {string} [todayText='Today'] Text for the today's month command. + @property {string} [todayStatus='Show today\'s month'] Status text for the today's month command. + @property {string} [clearText='Clear'] Text for the clear command. + @property {string} [clearStatus='Clear all the dates'] Status text for the clear command. + @property {string} [closeText='Close'] Text for the close command. + @property {string} [closeStatus='Close the datepicker'] Status text for the close command. + @property {string} [yearStatus='Change the year'] Status text for year selection. + @property {string} [earlierText='  ▲'] Text for earlier years. + @property {string} [laterText='  ▼'] Text for later years. + @property {string} [monthStatus='Change the month'] Status text for month selection. + @property {string} [weekText='Wk'] Text for week of the year column header. + @property {string} [weekStatus='Week of the year'] Status text for week of the year + column header. + @property {string} [dayStatus='Select DD, M d, yyyy'] Status text for selectable days. + @property {string} [defaultStatus='Select a date'] Status text shown by default. + @property {boolean} [isRTL=false] true if language is right-to-left. */ + regionalOptions: { // Available regional settings, indexed by language/country code + '': { // Default regional settings - English/US + renderer: {}, // this.defaultRenderer + prevText: '<Prev', + prevStatus: 'Show the previous month', + prevJumpText: '<<', + prevJumpStatus: 'Show the previous year', + nextText: 'Next>', + nextStatus: 'Show the next month', + nextJumpText: '>>', + nextJumpStatus: 'Show the next year', + currentText: 'Current', + currentStatus: 'Show the current month', + todayText: 'Today', + todayStatus: 'Show today\'s month', + clearText: 'Clear', + clearStatus: 'Clear all the dates', + closeText: 'Close', + closeStatus: 'Close the datepicker', + yearStatus: 'Change the year', + earlierText: '  ▲', + laterText: '  ▼', + monthStatus: 'Change the month', + weekText: 'Wk', + weekStatus: 'Week of the year', + dayStatus: 'Select DD, M d, yyyy', + defaultStatus: 'Select a date', + isRTL: false + } + }, + + _disabled: [], + + _popupClass: 'calendars-popup', // Marker for popup division + _triggerClass: 'calendars-trigger', // Marker for trigger element + _disableClass: 'calendars-disable', // Marker for disabled element + _monthYearClass: 'calendars-month-year', // Marker for month/year inputs + _curMonthClass: 'calendars-month-', // Marker for current month/year + _anyYearClass: 'calendars-any-year', // Marker for year direct input + _curDoWClass: 'calendars-dow-', // Marker for day of week + + _init: function() { + this.defaultOptions.commands = this.commands; + this.regionalOptions[''].renderer = this.defaultRenderer; + this._super(); + }, + + _instSettings: function(elem, options) { // jshint unused:false + return {selectedDates: [], drawDate: null, pickingRange: false, + inline: ($.inArray(elem[0].nodeName.toLowerCase(), ['div', 'span']) > -1), + get: function(name) { // Get a setting value, computing if necessary + if ($.inArray(name, ['defaultDate', 'minDate', 'maxDate']) > -1) { // Decode date settings + return this.options.calendar.determineDate(this.options[name], null, + this.selectedDates[0], this.get('dateFormat'), this.getConfig()); + } + if (name === 'dateFormat') { + return this.options.dateFormat || this.options.calendar.local.dateFormat; + } + return this.options[name]; + }, + curMinDate: function() { + return (this.pickingRange ? this.selectedDates[0] : this.get('minDate')); + }, + getConfig: function() { + return {dayNamesShort: this.options.dayNamesShort, dayNames: this.options.dayNames, + monthNamesShort: this.options.monthNamesShort, monthNames: this.options.monthNames, + calculateWeek: this.options.calculateWeek, shortYearCutoff: this.options.shortYearCutoff}; + } + }; + }, + + _postAttach: function(elem, inst) { + if (inst.inline) { + inst.drawDate = plugin._checkMinMax((inst.selectedDates[0] || + inst.get('defaultDate') || inst.options.calendar.today()).newDate(), inst); + inst.prevDate = inst.drawDate.newDate(); + this._update(elem[0]); + if ($.fn.mousewheel) { + elem.mousewheel(this._doMouseWheel); + } + } + else { + this._attachments(elem, inst); + elem.on('keydown.' + inst.name, this._keyDown).on('keypress.' + inst.name, this._keyPress). + on('keyup.' + inst.name, this._keyUp); + if (elem.attr('disabled')) { + this.disable(elem[0]); + } + } + }, + + _optionsChanged: function(elem, inst, options) { + if (options.calendar && options.calendar !== inst.options.calendar) { + var discardDate = function(name) { + return (typeof inst.options[name] === 'object' ? null : inst.options[name]); + }; + options = $.extend({defaultDate: discardDate('defaultDate'), + minDate: discardDate('minDate'), maxDate: discardDate('maxDate')}, options); + inst.selectedDates = []; + inst.drawDate = null; + } + var dates = inst.selectedDates; + $.extend(inst.options, options); + this.setDate(elem[0], dates, null, false, true); + inst.pickingRange = false; + var calendar = inst.options.calendar; + var defaultDate = inst.get('defaultDate'); + inst.drawDate = this._checkMinMax((defaultDate ? defaultDate : inst.drawDate) || + defaultDate || calendar.today(), inst).newDate(); + if (!inst.inline) { + this._attachments(elem, inst); + } + if (inst.inline || inst.div) { + this._update(elem[0]); + } + }, + + /** Attach events and trigger, if necessary. + @memberof CalendarsPicker + @private + @param {jQuery} elem The control to affect. + @param {object} inst The current instance settings. */ + _attachments: function(elem, inst) { + elem.off('focus.' + inst.name); + if (inst.options.showOnFocus) { + elem.on('focus.' + inst.name, this.show); + } + if (inst.trigger) { + inst.trigger.remove(); + } + var trigger = inst.options.showTrigger; + inst.trigger = (!trigger ? $([]) : + $(trigger).clone().removeAttr('id').addClass(this._triggerClass) + [inst.options.isRTL ? 'insertBefore' : 'insertAfter'](elem). + click(function() { + if (!plugin.isDisabled(elem[0])) { + plugin[plugin.curInst === inst ? 'hide' : 'show'](elem[0]); + } + })); + this._autoSize(elem, inst); + var dates = this._extractDates(inst, elem.val()); + if (dates) { + this.setDate(elem[0], dates, null, true); + } + var defaultDate = inst.get('defaultDate'); + if (inst.options.selectDefaultDate && defaultDate && inst.selectedDates.length === 0) { + this.setDate(elem[0], (defaultDate || inst.options.calendar.today()).newDate()); + } + }, + + /** Apply the maximum length for the date format. + @memberof CalendarsPicker + @private + @param {jQuery} elem The control to affect. + @param {object} inst The current instance settings. */ + _autoSize: function(elem, inst) { + if (inst.options.autoSize && !inst.inline) { + var calendar = inst.options.calendar; + var date = calendar.newDate(2009, 10, 20); // Ensure double digits + var dateFormat = inst.get('dateFormat'); + if (dateFormat.match(/[DM]/)) { + var findMax = function(names) { + var max = 0; + var maxI = 0; + for (var i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.month(findMax(calendar.local[dateFormat.match(/MM/) ? // Longest month + 'monthNames' : 'monthNamesShort']) + 1); + date.day(findMax(calendar.local[dateFormat.match(/DD/) ? // Longest day + 'dayNames' : 'dayNamesShort']) + 20 - date.dayOfWeek()); + } + inst.elem.attr('size', date.formatDate(dateFormat, + {localNumbers: inst.options.localnumbers}).length); + } + }, + + _preDestroy: function(elem, inst) { + if (inst.trigger) { + inst.trigger.remove(); + } + elem.empty().off('.' + inst.name); + if (inst.inline && $.fn.mousewheel) { + elem.unmousewheel(); + } + if (!inst.inline && inst.options.autoSize) { + elem.removeAttr('size'); + } + }, + + /** Apply multiple event functions. + @memberof CalendarsPicker + @param {function} fns The functions to apply. + @example onShow: multipleEvents(fn1, fn2, ...) */ + multipleEvents: function(fns) { // jshint unused:false + var funcs = arguments; + return function() { + for (var i = 0; i < funcs.length; i++) { + funcs[i].apply(this, arguments); + } + }; + }, + + /** Enable the control. + @memberof CalendarsPicker + @param {Element} elem The control to affect. + @example $(selector).datepick('enable') */ + enable: function(elem) { + elem = $(elem); + if (!elem.hasClass(this._getMarker())) { + return; + } + var inst = this._getInst(elem); + if (inst.inline) { + elem.children('.' + this._disableClass).remove().end(). + find('button,select').prop('disabled', false).end(). + find('a').attr('href', '#'); + } + else { + elem.prop('disabled', false); + inst.trigger.filter('button.' + this._triggerClass).prop('disabled', false).end(). + filter('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''}); + } + this._disabled = $.map(this._disabled, + function(value) { return (value === elem[0] ? null : value); }); // Delete entry + }, + + /** Disable the control. + @memberof CalendarsPicker + @param {Element} elem The control to affect. + @example $(selector).datepick('disable') */ + disable: function(elem) { + elem = $(elem); + if (!elem.hasClass(this._getMarker())) { + return; + } + var inst = this._getInst(elem); + if (inst.inline) { + var inline = elem.children(':last'); + var offset = inline.offset(); + var relOffset = {left: 0, top: 0}; + inline.parents().each(function() { + if ($(this).css('position') === 'relative') { + relOffset = $(this).offset(); + return false; + } + }); + var zIndex = elem.css('zIndex'); + zIndex = (zIndex === 'auto' ? 0 : parseInt(zIndex, 10)) + 1; + elem.prepend('
'). + find('button,select').prop('disabled', true).end(). + find('a').removeAttr('href'); + } + else { + elem.prop('disabled', true); + inst.trigger.filter('button.' + this._triggerClass).prop('disabled', true).end(). + filter('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'}); + } + this._disabled = $.map(this._disabled, + function(value) { return (value === elem[0] ? null : value); }); // Delete entry + this._disabled.push(elem[0]); + }, + + /** Is the first field in a jQuery collection disabled as a datepicker? + @memberof CalendarsPicker + @param {Element} elem The control to examine. + @return {boolean} true if disabled, false if enabled. + @example if ($(selector).datepick('isDisabled')) {...} */ + isDisabled: function(elem) { + return (elem && $.inArray(elem, this._disabled) > -1); + }, + + /** Show a popup datepicker. + @memberof CalendarsPicker + @param {Event|Element} elem a focus event or the control to use. + @example $(selector).datepick('show') */ + show: function(elem) { + elem = $(elem.target || elem); + var inst = plugin._getInst(elem); + if (plugin.curInst === inst) { + return; + } + if (plugin.curInst) { + plugin.hide(plugin.curInst, true); + } + if (!$.isEmptyObject(inst)) { + // Retrieve existing date(s) + inst.lastVal = null; + inst.selectedDates = plugin._extractDates(inst, elem.val()); + inst.pickingRange = false; + inst.drawDate = plugin._checkMinMax((inst.selectedDates[0] || + inst.get('defaultDate') || inst.options.calendar.today()).newDate(), inst); + inst.prevDate = inst.drawDate.newDate(); + plugin.curInst = inst; + // Generate content + plugin._update(elem[0], true); + // Adjust position before showing + var offset = plugin._checkOffset(inst); + inst.div.css({left: offset.left, top: offset.top}); + // And display + var showAnim = inst.options.showAnim; + var showSpeed = inst.options.showSpeed; + showSpeed = (showSpeed === 'normal' && $.ui && + parseInt($.ui.version.substring(2)) >= 8 ? '_default' : showSpeed); + if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) { + var data = inst.div.data(); // Update old effects data + for (var key in data) { + if (key.match(/^ec\.storage\./)) { + data[key] = inst._mainDiv.css(key.replace(/ec\.storage\./, '')); + } + } + inst.div.data(data).show(showAnim, inst.options.showOptions, showSpeed); + } + else { + inst.div[showAnim || 'show'](showAnim ? showSpeed : 0); + } + } + }, + + /** Extract possible dates from a string. + @memberof CalendarsPicker + @private + @param {object} inst The current instance settings. + @param {string} text The text to extract from. + @return {CDate[]} The extracted dates. */ + _extractDates: function(inst, datesText) { + if (datesText === inst.lastVal) { + return; + } + inst.lastVal = datesText; + datesText = datesText.split(inst.options.multiSelect ? inst.options.multiSeparator : + (inst.options.rangeSelect ? inst.options.rangeSeparator : '\x00')); + var dates = []; + for (var i = 0; i < datesText.length; i++) { + try { + var date = inst.options.calendar.parseDate(inst.get('dateFormat'), datesText[i]); + if (date) { + var found = false; + for (var j = 0; j < dates.length; j++) { + if (dates[j].compareTo(date) === 0) { + found = true; + break; + } + } + if (!found) { + dates.push(date); + } + } + } + catch (e) { + // Ignore + } + } + dates.splice(inst.options.multiSelect || (inst.options.rangeSelect ? 2 : 1), dates.length); + if (inst.options.rangeSelect && dates.length === 1) { + dates[1] = dates[0]; + } + return dates; + }, + + /** Update the datepicker display. + @memberof CalendarsPicker + @private + @param {Event|Element} elem A focus event or the control to use. + @param {boolean} hidden true to initially hide the datepicker. */ + _update: function(elem, hidden) { + elem = $(elem.target || elem); + var inst = plugin._getInst(elem); + if (!$.isEmptyObject(inst)) { + if (inst.inline || plugin.curInst === inst) { + if ($.isFunction(inst.options.onChangeMonthYear) && (!inst.prevDate || + inst.prevDate.year() !== inst.drawDate.year() || + inst.prevDate.month() !== inst.drawDate.month())) { + inst.options.onChangeMonthYear.apply(elem[0], + [inst.drawDate.year(), inst.drawDate.month()]); + } + } + if (inst.inline) { + var index = $('a, :input', elem).index($(':focus', elem)); + elem.html(this._generateContent(elem[0], inst)); + var focus = elem.find('a, :input'); + focus.eq(Math.max(Math.min(index, focus.length - 1), 0)).focus(); + } + else if (plugin.curInst === inst) { + if (!inst.div) { + inst.div = $('
').addClass(this._popupClass). + css({display: (hidden ? 'none' : 'static'), position: 'absolute', + left: elem.offset().left, top: elem.offset().top + elem.outerHeight()}). + appendTo($(inst.options.popupContainer || 'body')); + if ($.fn.mousewheel) { + inst.div.mousewheel(this._doMouseWheel); + } + } + inst.div.html(this._generateContent(elem[0], inst)); + elem.focus(); + } + } + }, + + /** Update the input field and any alternate field with the current dates. + @memberof CalendarsPicker + @private + @param {Element} elem The control to use. + @param {boolean} keyUp true if coming from keyUp processing (internal). */ + _updateInput: function(elem, keyUp) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst)) { + var value = ''; + var altValue = ''; + var sep = (inst.options.multiSelect ? inst.options.multiSeparator : + inst.options.rangeSeparator); + var calendar = inst.options.calendar; + var dateFormat = inst.get('dateFormat'); + var altFormat = inst.options.altFormat || dateFormat; + var settings = {localNumbers: inst.options.localNumbers}; + for (var i = 0; i < inst.selectedDates.length; i++) { + value += (keyUp ? '' : (i > 0 ? sep : '') + + calendar.formatDate(dateFormat, inst.selectedDates[i], settings)); + altValue += (i > 0 ? sep : '') + + calendar.formatDate(altFormat, inst.selectedDates[i], settings); + } + if (!inst.inline && !keyUp) { + $(elem).val(value); + } + $(inst.options.altField).val(altValue); + if ($.isFunction(inst.options.onSelect) && !keyUp && !inst.inSelect) { + inst.inSelect = true; // Prevent endless loops + inst.options.onSelect.apply(elem, [inst.selectedDates]); + inst.inSelect = false; + } + $(elem).change(); + } + }, + + /** Retrieve the size of left and top borders for an element. + @memberof CalendarsPicker + @private + @param {jQuery} elem The element of interest. + @return {number[]} The left and top borders. */ + _getBorders: function(elem) { + var convert = function(value) { + return {thin: 1, medium: 3, thick: 5}[value] || value; + }; + return [parseFloat(convert(elem.css('border-left-width'))), + parseFloat(convert(elem.css('border-top-width')))]; + }, + + /** Check positioning to remain on the screen. + @memberof CalendarsPicker + @private + @param {object} inst The current instance settings. + @return {object} The updated offset for the datepicker. */ + _checkOffset: function(inst) { + var base = (inst.elem.is(':hidden') && inst.trigger ? inst.trigger : inst.elem); + var offset = base.offset(); + var browserWidth = $(window).width(); + var browserHeight = $(window).height(); + if (browserWidth === 0) { + return offset; + } + var isFixed = false; + $(inst.elem).parents().each(function() { + isFixed = isFixed || $(this).css('position') === 'fixed'; + return !isFixed; + }); + var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + var scrollY = document.documentElement.scrollTop || document.body.scrollTop; + var above = offset.top - (isFixed ? scrollY : 0) - inst.div.outerHeight(); + var below = offset.top - (isFixed ? scrollY : 0) + base.outerHeight(); + var alignL = offset.left - (isFixed ? scrollX : 0); + var alignR = offset.left - (isFixed ? scrollX : 0) + base.outerWidth() - inst.div.outerWidth(); + var tooWide = (offset.left - scrollX + inst.div.outerWidth()) > browserWidth; + var tooHigh = (offset.top - scrollY + inst.elem.outerHeight() + + inst.div.outerHeight()) > browserHeight; + inst.div.css('position', isFixed ? 'fixed' : 'absolute'); + var alignment = inst.options.alignment; + if (alignment === 'topLeft') { + offset = {left: alignL, top: above}; + } + else if (alignment === 'topRight') { + offset = {left: alignR, top: above}; + } + else if (alignment === 'bottomLeft') { + offset = {left: alignL, top: below}; + } + else if (alignment === 'bottomRight') { + offset = {left: alignR, top: below}; + } + else if (alignment === 'top') { + offset = {left: (inst.options.isRTL || tooWide ? alignR : alignL), top: above}; + } + else { // bottom + offset = {left: (inst.options.isRTL || tooWide ? alignR : alignL), + top: (tooHigh ? above : below)}; + } + offset.left = Math.max((isFixed ? 0 : scrollX), offset.left); + offset.top = Math.max((isFixed ? 0 : scrollY), offset.top); + return offset; + }, + + /** Close date picker if clicked elsewhere. + @memberof CalendarsPicker + @private + @param {MouseEvent} event The mouse click to check. */ + _checkExternalClick: function(event) { + if (!plugin.curInst) { + return; + } + var elem = $(event.target); + if (elem.closest('.' + plugin._popupClass + ',.' + plugin._triggerClass).length === 0 && + !elem.hasClass(plugin._getMarker())) { + plugin.hide(plugin.curInst); + } + }, + + /** Hide a popup datepicker. + @memberof CalendarsPicker + @param {Element|object} elem The control to use or the current instance settings. + @param {boolean} immediate true to close immediately without animation (internal). + @example $(selector).datepick('hide') */ + hide: function(elem, immediate) { + if (!elem) { + return; + } + var inst = this._getInst(elem); + if ($.isEmptyObject(inst)) { + inst = elem; + } + if (inst && inst === plugin.curInst) { + var showAnim = (immediate ? '' : inst.options.showAnim); + var showSpeed = inst.options.showSpeed; + showSpeed = (showSpeed === 'normal' && $.ui && + parseInt($.ui.version.substring(2)) >= 8 ? '_default' : showSpeed); + var postProcess = function() { + if (!inst.div) { + return; + } + inst.div.remove(); + inst.div = null; + plugin.curInst = null; + if ($.isFunction(inst.options.onClose)) { + inst.options.onClose.apply(elem, [inst.selectedDates]); + } + }; + inst.div.stop(); + if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) { + inst.div.hide(showAnim, inst.options.showOptions, showSpeed, postProcess); + } + else { + var hideAnim = (showAnim === 'slideDown' ? 'slideUp' : + (showAnim === 'fadeIn' ? 'fadeOut' : 'hide')); + inst.div[hideAnim]((showAnim ? showSpeed : ''), postProcess); + } + if (!showAnim) { + postProcess(); + } + } + }, + + /** Handle keystrokes in the datepicker. + @memberof CalendarsPicker + @private + @param {KeyEvent} event The keystroke. + @return {boolean} true if not handled, false if handled. */ + _keyDown: function(event) { + var elem = (event.data && event.data.elem) || event.target; + var inst = plugin._getInst(elem); + var handled = false; + var command; + if (inst.inline || inst.div) { + if (event.keyCode === 9) { // Tab - close + plugin.hide(elem); + } + else if (event.keyCode === 13) { // Enter - select + plugin.selectDate(elem, + $('a.' + inst.options.renderer.highlightedClass, inst.div)[0]); + handled = true; + } + else { // Command keystrokes + var commands = inst.options.commands; + for (var name in commands) { + if (inst.options.commands.hasOwnProperty(name)) { + command = commands[name]; + /* jshint -W018 */ // Dislikes !! + if (command.keystroke.keyCode === event.keyCode && + !!command.keystroke.ctrlKey === !!(event.ctrlKey || event.metaKey) && + !!command.keystroke.altKey === event.altKey && + !!command.keystroke.shiftKey === event.shiftKey) { + /* jshint +W018 */ + plugin.performAction(elem, name); + handled = true; + break; + } + } + } + } + } + else { // Show on 'current' keystroke + command = inst.options.commands.current; + /* jshint -W018 */ // Dislikes !! + if (command.keystroke.keyCode === event.keyCode && + !!command.keystroke.ctrlKey === !!(event.ctrlKey || event.metaKey) && + !!command.keystroke.altKey === event.altKey && + !!command.keystroke.shiftKey === event.shiftKey) { + /* jshint +W018 */ + plugin.show(elem); + handled = true; + } + } + inst.ctrlKey = ((event.keyCode < 48 && event.keyCode !== 32) || event.ctrlKey || event.metaKey); + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + return !handled; + }, + + /** Filter keystrokes in the datepicker. + @memberof CalendarsPicker + @private + @param {KeyEvent} event The keystroke. + @return {boolean} true if allowed, false if not allowed. */ + _keyPress: function(event) { + var inst = plugin._getInst((event.data && event.data.elem) || event.target); + if (!$.isEmptyObject(inst) && inst.options.constrainInput) { + var ch = String.fromCharCode(event.keyCode || event.charCode); + var allowedChars = plugin._allowedChars(inst); + return (event.metaKey || inst.ctrlKey || ch < ' ' || + !allowedChars || allowedChars.indexOf(ch) > -1); + } + return true; + }, + + /** Determine the set of characters allowed by the date format. + @memberof CalendarsPicker + @private + @param {object} inst The current instance settings. + @return {string} The set of allowed characters, or null if anything allowed. */ + _allowedChars: function(inst) { + var allowedChars = (inst.options.multiSelect ? inst.options.multiSeparator : + (inst.options.rangeSelect ? inst.options.rangeSeparator : '')); + var literal = false; + var hasNum = false; + var dateFormat = inst.get('dateFormat'); + for (var i = 0; i < dateFormat.length; i++) { + var ch = dateFormat.charAt(i); + if (literal) { + if (ch === '\'' && dateFormat.charAt(i + 1) !== '\'') { + literal = false; + } + else { + allowedChars += ch; + } + } + else { + switch (ch) { + case 'd': + case 'm': + case 'o': + case 'w': + allowedChars += (hasNum ? '' : '0123456789'); + hasNum = true; + break; + case 'y': + case '@': + case '!': + allowedChars += (hasNum ? '' : '0123456789') + '-'; + hasNum = true; + break; + case 'J': + allowedChars += (hasNum ? '' : '0123456789') + '-.'; + hasNum = true; + break; + case 'D': + case 'M': + case 'Y': + return null; // Accept anything + case '\'': + if (dateFormat.charAt(i + 1) === '\'') { + allowedChars += '\''; + } + else { + literal = true; + } + break; + default: + allowedChars += ch; + } + } + } + return allowedChars; + }, + + /** Synchronise datepicker with the field. + @memberof CalendarsPicker + @private + @param {KeyEvent} event The keystroke. + @return {boolean} true if allowed, false if not allowed. */ + _keyUp: function(event) { + var elem = (event.data && event.data.elem) || event.target; + var inst = plugin._getInst(elem); + if (!$.isEmptyObject(inst) && !inst.ctrlKey && inst.lastVal !== inst.elem.val()) { + try { + var dates = plugin._extractDates(inst, inst.elem.val()); + if (dates.length > 0) { + plugin.setDate(elem, dates, null, true); + } + } + catch (e) { + // Ignore + } + } + return true; + }, + + /** Increment/decrement month/year on mouse wheel activity. + @memberof CalendarsPicker + @private + @param {event} event The mouse wheel event. + @param {number} delta The amount of change. */ + _doMouseWheel: function(event, delta) { + var elem = (plugin.curInst && plugin.curInst.elem[0]) || + $(event.target).closest('.' + plugin._getMarker())[0]; + if (plugin.isDisabled(elem)) { + return; + } + var inst = plugin._getInst(elem); + if (inst.options.useMouseWheel) { + delta = (delta < 0 ? -1 : +1); + plugin.changeMonth(elem, -inst.options[event.ctrlKey ? 'monthsToJump' : 'monthsToStep'] * delta); + } + event.preventDefault(); + }, + + /** Clear an input and close a popup datepicker. + @memberof CalendarsPicker + @param {Element} elem The control to use. + @example $(selector).datepick('clear') */ + clear: function(elem) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst)) { + inst.selectedDates = []; + this.hide(elem); + var defaultDate = inst.get('defaultDate'); + if (inst.options.selectDefaultDate && defaultDate) { + this.setDate(elem, (defaultDate || inst.options.calendar.today()).newDate()); + } + else { + this._updateInput(elem); + } + } + }, + + /** Retrieve the selected date(s) for a datepicker. + @memberof CalendarsPicker + @param {Element} elem The control to examine. + @return {CDate[]} The selected date(s). + @example var dates = $(selector).datepick('getDate') */ + getDate: function(elem) { + var inst = this._getInst(elem); + return (!$.isEmptyObject(inst) ? inst.selectedDates : []); + }, + + /** Set the selected date(s) for a datepicker. + @memberof CalendarsPicker + @param {Element} elem The control to examine. + @param {CDate|number|string|array} dates The selected date(s). + @param {CDate|number|string} [endDate] The ending date for a range. + @param {boolean} [keyUp] true if coming from keyUp processing (internal). + @param {boolean} [setOpt] true if coming from option processing (internal). + @example $(selector).datepick('setDate', new Date(2014, 12-1, 25)) +$(selector).datepick('setDate', '12/25/2014', '01/01/2015') +$(selector).datepick('setDate', [date1, date2, date3]) */ + setDate: function(elem, dates, endDate, keyUp, setOpt) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst)) { + if (!$.isArray(dates)) { + dates = [dates]; + if (endDate) { + dates.push(endDate); + } + } + var minDate = inst.get('minDate'); + var maxDate = inst.get('maxDate'); + var curDate = inst.selectedDates[0]; + inst.selectedDates = []; + for (var i = 0; i < dates.length; i++) { + var date = inst.options.calendar.determineDate( + dates[i], null, curDate, inst.get('dateFormat'), inst.getConfig()); + if (date) { + if ((!minDate || date.compareTo(minDate) !== -1) && + (!maxDate || date.compareTo(maxDate) !== +1)) { + var found = false; + for (var j = 0; j < inst.selectedDates.length; j++) { + if (inst.selectedDates[j].compareTo(date) === 0) { + found = true; + break; + } + } + if (!found) { + inst.selectedDates.push(date); + } + } + } + } + inst.selectedDates.splice(inst.options.multiSelect || + (inst.options.rangeSelect ? 2 : 1), inst.selectedDates.length); + if (inst.options.rangeSelect) { + switch (inst.selectedDates.length) { + case 1: + inst.selectedDates[1] = inst.selectedDates[0]; + break; + case 2: + inst.selectedDates[1] = (inst.selectedDates[0].compareTo(inst.selectedDates[1]) === +1 ? + inst.selectedDates[0] : inst.selectedDates[1]); + break; + } + inst.pickingRange = false; + } + inst.prevDate = (inst.drawDate ? inst.drawDate.newDate() : null); + inst.drawDate = this._checkMinMax((inst.selectedDates[0] || + inst.get('defaultDate') || inst.options.calendar.today()).newDate(), inst); + if (!setOpt) { + this._update(elem); + this._updateInput(elem, keyUp); + } + } + }, + + /** Determine whether a date is selectable for this datepicker. + @memberof CalendarsPicker + @private + @param {Element} elem The control to check. + @param {CDate|string|number} date The date to check. + @return {boolean} true if selectable, false if not. + @example var selectable = $(selector).datepick('isSelectable', date) */ + isSelectable: function(elem, date) { + var inst = this._getInst(elem); + if ($.isEmptyObject(inst)) { + return false; + } + date = inst.options.calendar.determineDate(date, + inst.selectedDates[0] || inst.options.calendar.today(), null, + inst.options.dateFormat, inst.getConfig()); + return this._isSelectable(elem, date, inst.options.onDate, + inst.get('minDate'), inst.get('maxDate')); + }, + + /** Internally determine whether a date is selectable for this datepicker. + @memberof CalendarsPicker + @private + @param {Element} elem The control to check. + @param {CDate} date The date to check. + @param {function|boolean} onDate Any onDate callback or callback.selectable. + @param {CDate} minDate The minimum allowed date. + @param {CDate} maxDate The maximum allowed date. + @return {boolean} true if selectable, false if not. */ + _isSelectable: function(elem, date, onDate, minDate, maxDate) { + var dateInfo = (typeof onDate === 'boolean' ? {selectable: onDate} : + (!$.isFunction(onDate) ? {} : onDate.apply(elem, [date, true]))); + return (dateInfo.selectable !== false) && + (!minDate || date.toJD() >= minDate.toJD()) && (!maxDate || date.toJD() <= maxDate.toJD()); + }, + + /** Perform a named action for a datepicker. + @memberof CalendarsPicker + @param {element} elem The control to affect. + @param {string} action The name of the {@link CalendarsPicker.commands|action}. + @example $(selector).calendarsPicker('performAction', 'next') */ + performAction: function(elem, action) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst) && !this.isDisabled(elem)) { + var commands = inst.options.commands; + if (commands[action] && commands[action].enabled.apply(elem, [inst])) { + commands[action].action.apply(elem, [inst]); + } + } + }, + + /** Set the currently shown month, defaulting to today's. + @memberof CalendarsPicker + @param {Element} elem The control to affect. + @param {number} [year] The year to show. + @param {number} [month] The month to show (calendar minimum month to maximum month). + @param {number} [day] The day to show. + @example $(selector).datepick('showMonth', 2014, 12, 25) */ + showMonth: function(elem, year, month, day) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst) && ((typeof day !== 'undefined' && day !== null) || + inst.drawDate.year() !== year || inst.drawDate.month() !== month)) { + inst.prevDate = inst.drawDate.newDate(); + var calendar = inst.options.calendar; + var show = this._checkMinMax(typeof year !== 'undefined' && year !== null ? + calendar.newDate(year, month, 1) : calendar.today(), inst); + inst.drawDate.date(show.year(), show.month(), + typeof day !== 'undefined' && day !== null ? day : Math.min(inst.drawDate.day(), + calendar.daysInMonth(show.year(), show.month()))); + this._update(elem); + } + }, + + /** Adjust the currently shown month. + @memberof CalendarsPicker + @param {Element} elem The control to affect. + @param {number} offset The number of months to change by. + @example $(selector).datepick('changeMonth', 2)*/ + changeMonth: function(elem, offset) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst)) { + var date = inst.drawDate.newDate().add(offset, 'm'); + this.showMonth(elem, date.year(), date.month()); + } + }, + + /** Adjust the currently shown day. + @memberof CalendarsPicker + @param {Element} elem The control to affect. + @param {number} offset The number of days to change by. + @example $(selector).datepick('changeDay', 7)*/ + changeDay: function(elem, offset) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst)) { + var date = inst.drawDate.newDate().add(offset, 'd'); + this.showMonth(elem, date.year(), date.month(), date.day()); + } + }, + + /** Restrict a date to the minimum/maximum specified. + @memberof CalendarsPicker + @private + @param {CDate} date The date to check. + @param {object} inst The current instance settings. */ + _checkMinMax: function(date, inst) { + var minDate = inst.get('minDate'); + var maxDate = inst.get('maxDate'); + date = (minDate && date.compareTo(minDate) === -1 ? minDate.newDate() : date); + date = (maxDate && date.compareTo(maxDate) === +1 ? maxDate.newDate() : date); + return date; + }, + + /** Retrieve the date associated with an entry in the datepicker. + @memberof CalendarsPicker + @param {Element} elem The control to examine. + @param {Element} target The selected datepicker element. + @return {CDate} The corresponding date, or null. + @example var date = $(selector).datepick('retrieveDate', + $('div.datepick-popup a:contains(10)')[0]) */ + retrieveDate: function(elem, target) { + var inst = this._getInst(elem); + return ($.isEmptyObject(inst) ? null : inst.options.calendar.fromJD( + parseFloat(target.className.replace(/^.*jd(\d+\.5).*$/, '$1')))); + }, + + /** Select a date for this datepicker. + @memberof CalendarsPicker + @param {Element} elem The control to examine. + @param {Element} target The selected datepicker element. + @example $(selector).datepick('selectDate', $('div.datepick-popup a:contains(10)')[0]) */ + selectDate: function(elem, target) { + var inst = this._getInst(elem); + if (!$.isEmptyObject(inst) && !this.isDisabled(elem)) { + var date = this.retrieveDate(elem, target); + if (inst.options.multiSelect) { + var found = false; + for (var i = 0; i < inst.selectedDates.length; i++) { + if (date.compareTo(inst.selectedDates[i]) === 0) { + inst.selectedDates.splice(i, 1); + found = true; + break; + } + } + if (!found && inst.selectedDates.length < inst.options.multiSelect) { + inst.selectedDates.push(date); + } + } + else if (inst.options.rangeSelect) { + if (inst.pickingRange) { + inst.selectedDates[1] = date; + } + else { + inst.selectedDates = [date, date]; + } + inst.pickingRange = !inst.pickingRange; + } + else { + inst.selectedDates = [date]; + } + inst.prevDate = inst.drawDate = date.newDate(); + this._updateInput(elem); + if (inst.inline || inst.pickingRange || inst.selectedDates.length < + (inst.options.multiSelect || (inst.options.rangeSelect ? 2 : 1))) { + this._update(elem); + } + else { + this.hide(elem); + } + } + }, + + /** Generate the datepicker content for this control. + @memberof CalendarsPicker + @private + @param {Element} elem The control to affect. + @param {object} inst The current instance settings. + @return {jQuery} The datepicker content */ + _generateContent: function(elem, inst) { + var monthsToShow = inst.options.monthsToShow; + monthsToShow = ($.isArray(monthsToShow) ? monthsToShow : [1, monthsToShow]); + inst.drawDate = this._checkMinMax( + inst.drawDate || inst.get('defaultDate') || inst.options.calendar.today(), inst); + var drawDate = inst.drawDate.newDate().add(-inst.options.monthsOffset, 'm'); + // Generate months + var monthRows = ''; + for (var row = 0; row < monthsToShow[0]; row++) { + var months = ''; + for (var col = 0; col < monthsToShow[1]; col++) { + months += this._generateMonth(elem, inst, drawDate.year(), + drawDate.month(), inst.options.calendar, inst.options.renderer, (row === 0 && col === 0)); + drawDate.add(1, 'm'); + } + monthRows += this._prepare(inst.options.renderer.monthRow, inst).replace(/\{months\}/, months); + } + var picker = this._prepare(inst.options.renderer.picker, inst).replace(/\{months\}/, monthRows). + replace(/\{weekHeader\}/g, this._generateDayHeaders(inst, inst.options.calendar, inst.options.renderer)); + // Add commands + var addCommand = function(type, open, close, name, classes) { + if (picker.indexOf('{' + type + ':' + name + '}') === -1) { + return; + } + var command = inst.options.commands[name]; + var date = (inst.options.commandsAsDateFormat ? command.date.apply(elem, [inst]) : null); + picker = picker.replace(new RegExp('\\{' + type + ':' + name + '\\}', 'g'), + '<' + open + (command.status ? ' title="' + inst.options[command.status] + '"' : '') + + ' class="' + inst.options.renderer.commandClass + ' ' + + inst.options.renderer.commandClass + '-' + name + ' ' + classes + + (command.enabled(inst) ? '' : ' ' + inst.options.renderer.disabledClass) + '">' + + (date ? date.formatDate(inst.options[command.text], {localNumbers: inst.options.localNumbers}) : + inst.options[command.text]) + ''); + }; + for (var name in inst.options.commands) { + if (inst.options.commands.hasOwnProperty(name)) { + addCommand('button', 'button type="button"', 'button', name, + inst.options.renderer.commandButtonClass); + addCommand('link', 'a href="javascript:void(0)"', 'a', name, + inst.options.renderer.commandLinkClass); + } + } + picker = $(picker); + if (monthsToShow[1] > 1) { + var count = 0; + $(inst.options.renderer.monthSelector, picker).each(function() { + var nth = ++count % monthsToShow[1]; + $(this).addClass(nth === 1 ? 'first' : (nth === 0 ? 'last' : '')); + }); + } + // Add datepicker behaviour + var self = this; + function removeHighlight(elem) { + (inst.inline ? $(elem).closest('.' + self._getMarker()) : inst.div). + find(inst.options.renderer.daySelector + ' a'). + removeClass(inst.options.renderer.highlightedClass); + } + picker.find(inst.options.renderer.daySelector + ' a').hover( + function() { + removeHighlight(this); + $(this).addClass(inst.options.renderer.highlightedClass); + }, + function() { + removeHighlight(this); + }). + click(function() { + self.selectDate(elem, this); + }).end(). + find('select.' + this._monthYearClass + ':not(.' + this._anyYearClass + ')'). + change(function() { + var monthYear = $(this).val().split('/'); + self.showMonth(elem, parseInt(monthYear[1], 10), parseInt(monthYear[0], 10)); + }).end(). + find('select.' + this._anyYearClass).click(function() { + $(this).css('visibility', 'hidden'). + next('input').css({left: this.offsetLeft, top: this.offsetTop, + width: this.offsetWidth, height: this.offsetHeight}).show().focus(); + }).end(). + find('input.' + self._monthYearClass).change(function() { + try { + var year = parseInt($(this).val(), 10); + year = (isNaN(year) ? inst.drawDate.year() : year); + self.showMonth(elem, year, inst.drawDate.month(), inst.drawDate.day()); + } + catch (e) { + // Ignore + } + }).keydown(function(event) { + if (event.keyCode === 13) { // Enter + $(event.elem).change(); + } + else if (event.keyCode === 27) { // Escape + $(event.elem).hide().prev('select').css('visibility', 'visible'); + inst.elem.focus(); + } + }); + // Add keyboard handling + var data = {elem: inst.elem[0]}; + picker.keydown(data, this._keyDown).keypress(data, this._keyPress).keyup(data, this._keyUp); + // Add command behaviour + picker.find('.' + inst.options.renderer.commandClass).click(function() { + if (!$(this).hasClass(inst.options.renderer.disabledClass)) { + var action = this.className.replace( + new RegExp('^.*' + inst.options.renderer.commandClass + '-([^ ]+).*$'), '$1'); + plugin.performAction(elem, action); + } + }); + // Add classes + if (inst.options.isRTL) { + picker.addClass(inst.options.renderer.rtlClass); + } + if (monthsToShow[0] * monthsToShow[1] > 1) { + picker.addClass(inst.options.renderer.multiClass); + } + if (inst.options.pickerClass) { + picker.addClass(inst.options.pickerClass); + } + // Resize + $('body').append(picker); + var width = 0; + picker.find(inst.options.renderer.monthSelector).each(function() { + width += $(this).outerWidth(); + }); + picker.width(width / monthsToShow[0]); + // Pre-show customisation + if ($.isFunction(inst.options.onShow)) { + inst.options.onShow.apply(elem, [picker, inst.options.calendar, inst]); + } + return picker; + }, + + /** Generate the content for a single month. + @memberof CalendarsPicker + @private + @param {Element} elem The control to affect. + @param {object} inst The current instance settings. + @param {number} year The year to generate. + @param {number} month The month to generate. + @param {BaseCalendar} calendar The current calendar. + @param {object} renderer The rendering templates. + @param {boolean} first true if first of multiple months. + @return {string} The month content. */ + _generateMonth: function(elem, inst, year, month, calendar, renderer, first) { + var daysInMonth = calendar.daysInMonth(year, month); + var monthsToShow = inst.options.monthsToShow; + monthsToShow = ($.isArray(monthsToShow) ? monthsToShow : [1, monthsToShow]); + var fixedWeeks = inst.options.fixedWeeks || (monthsToShow[0] * monthsToShow[1] > 1); + var firstDay = inst.options.firstDay; + firstDay = (typeof firstDay === 'undefined' || firstDay === null ? calendar.local.firstDay : firstDay); + var leadDays = (calendar.dayOfWeek(year, month, calendar.minDay) - + firstDay + calendar.daysInWeek()) % calendar.daysInWeek(); + var numWeeks = (fixedWeeks ? 6 : Math.ceil((leadDays + daysInMonth) / calendar.daysInWeek())); + var selectOtherMonths = inst.options.selectOtherMonths && inst.options.showOtherMonths; + var minDate = (inst.pickingRange ? inst.selectedDates[0] : inst.get('minDate')); + var maxDate = inst.get('maxDate'); + var showWeeks = renderer.week.indexOf('{weekOfYear}') > -1; + var today = calendar.today(); + var drawDate = calendar.newDate(year, month, calendar.minDay); + drawDate.add(-leadDays - (fixedWeeks && + (drawDate.dayOfWeek() === firstDay || drawDate.daysInMonth() < calendar.daysInWeek())? + calendar.daysInWeek() : 0), 'd'); + var jd = drawDate.toJD(); + // Localise numbers if requested and available + var localiseNumbers = function(value) { + return (inst.options.localNumbers && calendar.local.digits ? calendar.local.digits(value) : value); + }; + // Generate weeks + var weeks = ''; + for (var week = 0; week < numWeeks; week++) { + var weekOfYear = (!showWeeks ? '' : '' + + ($.isFunction(inst.options.calculateWeek) ? + inst.options.calculateWeek(drawDate) : drawDate.weekOfYear()) + ''); + var days = ''; + for (var day = 0; day < calendar.daysInWeek(); day++) { + var selected = false; + if (inst.options.rangeSelect && inst.selectedDates.length > 0) { + selected = drawDate.compareTo(inst.selectedDates[0]) !== -1 && + drawDate.compareTo(inst.selectedDates[1]) !== +1; + } + else { + for (var i = 0; i < inst.selectedDates.length; i++) { + if (inst.selectedDates[i].compareTo(drawDate) === 0) { + selected = true; + break; + } + } + } + var dateInfo = (!$.isFunction(inst.options.onDate) ? {} : + inst.options.onDate.apply(elem, [drawDate, drawDate.month() === month])); + var selectable = (selectOtherMonths || drawDate.month() === month) && + this._isSelectable(elem, drawDate, dateInfo.selectable, minDate, maxDate); + days += this._prepare(renderer.day, inst).replace(/\{day\}/g, + (selectable ? '' + + (inst.options.showOtherMonths || drawDate.month() === month ? + dateInfo.content || localiseNumbers(drawDate.day()) : ' ') + + (selectable ? '' : '')); + drawDate.add(1, 'd'); + jd++; + } + weeks += this._prepare(renderer.week, inst).replace(/\{days\}/g, days). + replace(/\{weekOfYear\}/g, weekOfYear); + } + var monthHeader = this._prepare(renderer.month, inst).match(/\{monthHeader(:[^\}]+)?\}/); + monthHeader = (monthHeader[0].length <= 13 ? 'MM yyyy' : + monthHeader[0].substring(13, monthHeader[0].length - 1)); + monthHeader = (first ? this._generateMonthSelection( + inst, year, month, minDate, maxDate, monthHeader, calendar, renderer) : + calendar.formatDate(monthHeader, calendar.newDate(year, month, calendar.minDay), + {localNumbers: inst.options.localNumbers})); + var weekHeader = this._prepare(renderer.weekHeader, inst). + replace(/\{days\}/g, this._generateDayHeaders(inst, calendar, renderer)); + return this._prepare(renderer.month, inst).replace(/\{monthHeader(:[^\}]+)?\}/g, monthHeader). + replace(/\{weekHeader\}/g, weekHeader).replace(/\{weeks\}/g, weeks); + }, + + /** Generate the HTML for the day headers. + @memberof CalendarsPicker + @private + @param {object} inst The current instance settings. + @param {BaseCalendar} calendar The current calendar. + @param {object} renderer The rendering templates. + @return {string} A week's worth of day headers. */ + _generateDayHeaders: function(inst, calendar, renderer) { + var firstDay = inst.options.firstDay; + firstDay = (typeof firstDay === 'undefined' || firstDay === null ? calendar.local.firstDay : firstDay); + var header = ''; + for (var day = 0; day < calendar.daysInWeek(); day++) { + var dow = (day + firstDay) % calendar.daysInWeek(); + header += this._prepare(renderer.dayHeader, inst).replace(/\{day\}/g, + '' + calendar.local.dayNamesMin[dow] + ''); + } + return header; + }, + + /** Generate the selection controls for a month. + @memberof CalendarsPicker + @private + @param {object} inst The current instance settings. + @param {number} year The year to generate. + @param {number} month The month to generate. + @param {CDate} minDate The minimum date allowed. + @param {CDate} maxDate The maximum date allowed. + @param {string} monthHeader The month/year format. + @param {BaseCalendar} calendar The current calendar. + @return {string} The month selection content. */ + _generateMonthSelection: function(inst, year, month, minDate, maxDate, monthHeader, calendar) { + if (!inst.options.changeMonth) { + return calendar.formatDate(monthHeader, calendar.newDate(year, month, 1), + {localNumbers: inst.options.localNumbers}); + } + // Months + var monthNames = calendar.local[ + 'monthNames' + (monthHeader.match(/mm/i) ? '' : 'Short')]; + var html = monthHeader.replace(/m+/i, '\\x2E').replace(/y+/i, '\\x2F'); + var selector = ''; + html = html.replace(/\\x2E/, selector); + // Years + var localiseNumbers = function(value) { + return (inst.options.localNumbers && calendar.local.digits ? calendar.local.digits(value) : value); + }; + var yearRange = inst.options.yearRange; + if (yearRange === 'any') { + selector = '' + + ''; + } + else { + yearRange = yearRange.split(':'); + var todayYear = calendar.today().year(); + var start = (yearRange[0].match('c[+-].*') ? year + parseInt(yearRange[0].substring(1), 10) : + ((yearRange[0].match('[+-].*') ? todayYear : 0) + parseInt(yearRange[0], 10))); + var end = (yearRange[1].match('c[+-].*') ? year + parseInt(yearRange[1].substring(1), 10) : + ((yearRange[1].match('[+-].*') ? todayYear : 0) + parseInt(yearRange[1], 10))); + selector = ''; + } + html = html.replace(/\\x2F/, selector); + return html; + }, + + /** Prepare a render template for use. + Exclude popup/inline sections that are not applicable. + Localise text of the form: {l10n:name}. + @memberof CalendarsPicker + @private + @param {string} text The text to localise. + @param {object} inst The current instance settings. + @return {string} The localised text. */ + _prepare: function(text, inst) { + var replaceSection = function(type, retain) { + while (true) { + var start = text.indexOf('{' + type + ':start}'); + if (start === -1) { + return; + } + var end = text.substring(start).indexOf('{' + type + ':end}'); + if (end > -1) { + text = text.substring(0, start) + + (retain ? text.substr(start + type.length + 8, end - type.length - 8) : '') + + text.substring(start + end + type.length + 6); + } + } + }; + replaceSection('inline', inst.inline); + replaceSection('popup', !inst.inline); + var pattern = /\{l10n:([^\}]+)\}/; + var matches = pattern.exec(text); + while (matches) { + text = text.replace(matches[0], inst.options[matches[1]]); + matches = pattern.exec(text); + } + return text; + } + }); + + var plugin = $.calendarsPicker; // Singleton instance + + $(function() { + $(document).on('mousedown.' + pluginName, plugin._checkExternalClick). + on('resize.' + pluginName, function() { plugin.hide(plugin.curInst); }); + }); + +})(jQuery); diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.plus.js b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.plus.js new file mode 100644 index 000000000..f3014705e --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.calendars.plus.js @@ -0,0 +1,463 @@ +/* http://keith-wood.name/calendars.html + Calendars extras for jQuery v2.1.0. + Written by Keith Wood (wood.keith{at}optusnet.com.au) August 2009. + Available under the MIT (http://keith-wood.name/licence.html) license. + Please attribute the author if you use it. */ + +(function($) { // Hide scope, no $ conflict + 'use strict'; + + $.extend($.calendars.regionalOptions[''], { + invalidArguments: 'Invalid arguments', + invalidFormat: 'Cannot format a date from another calendar', + missingNumberAt: 'Missing number at position {0}', + unknownNameAt: 'Unknown name at position {0}', + unexpectedLiteralAt: 'Unexpected literal at position {0}', + unexpectedText: 'Additional text found at end' + }); + $.calendars.local = $.calendars.regionalOptions['']; + + $.extend($.calendars.cdate.prototype, { + + /** Format this date. + Found in the jquery.calendars.plus.js module. + @memberof CDate + @param {string} [format] The date format to use (see {@linkcode BaseCalendar.formatDate|formatDate}). + @param {object} [settings] Options for the formatDate function. + @return {string} The formatted date. */ + formatDate: function(format, settings) { + if (typeof format !== 'string') { + settings = format; + format = ''; + } + return this._calendar.formatDate(format || '', this, settings); + } + }); + + $.extend($.calendars.baseCalendar.prototype, { + + UNIX_EPOCH: $.calendars.instance().newDate(1970, 1, 1).toJD(), + SECS_PER_DAY: 24 * 60 * 60, + TICKS_EPOCH: $.calendars.instance().jdEpoch, // 1 January 0001 CE + TICKS_PER_DAY: 24 * 60 * 60 * 10000000, + + /** Date format for ATOM (RFC 3339/ISO 8601) - 'yyyy-mm-dd'. + @memberof BaseCalendar */ + ATOM: 'yyyy-mm-dd', + /** Date format for cookies - 'D, dd M yyyy'. + @memberof BaseCalendar */ + COOKIE: 'D, dd M yyyy', + /** Date format for the full date - 'DD, MM d, yyyy'. + @memberof BaseCalendar */ + FULL: 'DD, MM d, yyyy', + /** Date format for ISO 8601 - 'yyyy-mm-dd'. + @memberof BaseCalendar */ + ISO_8601: 'yyyy-mm-dd', + /** Date format for Julian date - days since January 1, 4713 BCE Greenwich noon. + @memberof BaseCalendar */ + JULIAN: 'J', + /** Date format for RFC 822 - 'D, d M yy'. + @memberof BaseCalendar */ + RFC_822: 'D, d M yy', + /** Date format for RFC 850 - 'DD, dd-M-yy'. + @memberof BaseCalendar */ + RFC_850: 'DD, dd-M-yy', + /** Date format for RFC 1036 - 'D, d M yy'. + @memberof BaseCalendar */ + RFC_1036: 'D, d M yy', + /** Date format for RFC 1123 - 'D, d M yyyy'. + @memberof BaseCalendar */ + RFC_1123: 'D, d M yyyy', + /** Date format for RFC 2822 - 'D, d M yyyy'. + @memberof BaseCalendar */ + RFC_2822: 'D, d M yyyy', + /** Date format for RSS (RFC 822) - 'D, d M yy'. + @memberof BaseCalendar */ + RSS: 'D, d M yy', + /** Date format for Windows ticks - number of 100-nanosecond ticks since 1 January 0001 00:00:00 UTC. + @memberof BaseCalendar */ + TICKS: '!', + /** Date format for Unix timestamp - number of seconds elapsed since the + start of the Unix epoch at 1 January 1970 00:00:00 UTC. + @memberof BaseCalendar */ + TIMESTAMP: '@', + /** Date format for W3C (ISO 8601) - 'yyyy-mm-dd'. + @memberof BaseCalendar */ + W3C: 'yyyy-mm-dd', + + /** Format a date object into a string value. + The format can be combinations of the following: +
    +
  • d - day of month (no leading zero)
  • +
  • dd - day of month (two digit)
  • +
  • o - day of year (no leading zeros)
  • +
  • oo - day of year (three digit)
  • +
  • D - day name short
  • +
  • DD - day name long
  • +
  • w - week of year (no leading zero)
  • +
  • ww - week of year (two digit)
  • +
  • m - month of year (no leading zero)
  • +
  • mm - month of year (two digit)
  • +
  • M - month name short
  • +
  • MM - month name long
  • +
  • yy - year (two digit)
  • +
  • yyyy - year (four digit)
  • +
  • YYYY - formatted year
  • +
  • J - Julian date (days since January 1, 4713 BCE Greenwich noon)
  • +
  • @ - Unix timestamp (s since 01/01/1970)
  • +
  • ! - Windows ticks (100ns since 01/01/0001)
  • +
  • '...' - literal text
  • +
  • '' - single quote
  • +
+ Found in the jquery.calendars.plus.js module. + @memberof BaseCalendar + @param {string} [format] The desired format of the date (defaults to calendar format). + @param {CDate} date The date value to format. + @param {object} [settings] Addition options, whose attributes include: + @param {string[]} [settings.dayNamesShort] Abbreviated names of the days from day 0 (Sunday). + @param {string[]} [settings.dayNames] Names of the days from day 0 (Sunday). + @param {string[]} [settings.monthNamesShort] Abbreviated names of the months. + @param {string[]} [settings.monthNames] Names of the months. + @param {boolean} [settings.localNumbers=false] true to localise numbers (if available), + false to use normal Arabic numerals. + @return {string} The date in the above format. + @throws Errors if the date is from a different calendar. */ + formatDate: function(format, date, settings) { + if (typeof format !== 'string') { + settings = date; + date = format; + format = ''; + } + if (!date) { + return ''; + } + if (date.calendar() !== this) { + throw $.calendars.local.invalidFormat || $.calendars.regionalOptions[''].invalidFormat; + } + format = format || this.local.dateFormat; + settings = settings || {}; + var dayNamesShort = settings.dayNamesShort || this.local.dayNamesShort; + var dayNames = settings.dayNames || this.local.dayNames; + var monthNamesShort = settings.monthNamesShort || this.local.monthNamesShort; + var monthNames = settings.monthNames || this.local.monthNames; + var localNumbers = settings.localNumbers || this.local.localNumbers; + // Check whether a format character is doubled + var doubled = function(match, step) { + var matches = 1; + while (iFormat + matches < format.length && format.charAt(iFormat + matches) === match) { + matches++; + } + iFormat += matches - 1; + return Math.floor(matches / (step || 1)) > 1; + }; + // Format a number, with leading zeroes if necessary + var formatNumber = function(match, value, len, step) { + var num = '' + value; + if (doubled(match, step)) { + while (num.length < len) { + num = '0' + num; + } + } + return num; + }; + // Format a name, short or long as requested + var formatName = function(match, value, shortNames, longNames) { + return (doubled(match) ? longNames[value] : shortNames[value]); + }; + // Localise numbers if requested and available + var localiseNumbers = localNumbers && this.local.digits ? + this.local.digits : function(value) { return value; }; + var output = ''; + var literal = false; + for (var iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === '\'' && !doubled('\'')) { + literal = false; + } + else { + output += format.charAt(iFormat); + } + } + else { + switch (format.charAt(iFormat)) { + case 'd': + output += localiseNumbers(formatNumber('d', date.day(), 2)); + break; + case 'D': + output += formatName('D', date.dayOfWeek(), dayNamesShort, dayNames); + break; + case 'o': + output += formatNumber('o', date.dayOfYear(), 3); + break; + case 'w': + output += formatNumber('w', date.weekOfYear(), 2); + break; + case 'm': + output += localiseNumbers(formatNumber('m', date.month(), 2)); + break; + case 'M': + output += formatName('M', date.month() - this.minMonth, monthNamesShort, monthNames); + break; + case 'y': + output += localiseNumbers(doubled('y', 2) ? date.year() : + (date.year() % 100 < 10 ? '0' : '') + date.year() % 100); + break; + case 'Y': + doubled('Y', 2); + output += date.formatYear(); + break; + case 'J': + output += date.toJD(); + break; + case '@': + output += (date.toJD() - this.UNIX_EPOCH) * this.SECS_PER_DAY; + break; + case '!': + output += (date.toJD() - this.TICKS_EPOCH) * this.TICKS_PER_DAY; + break; + case '\'': + if (doubled('\'')) { + output += '\''; + } + else { + literal = true; + } + break; + default: + output += format.charAt(iFormat); + } + } + } + return output; + }, + + /** Parse a string value into a date object. + See {@linkcode BaseCalendar.formatDate|formatDate} for the possible formats, plus: +
    +
  • * - ignore rest of string
  • +
+ Found in the jquery.calendars.plus.js module. + @memberof BaseCalendar + @param {string} format The expected format of the date ('' for default calendar format). + @param {string} value The date in the above format. + @param {object} [settings] Additional options whose attributes include: + @param {number} [settings.shortYearCutoff] The cutoff year for determining the century. + @param {string[]} [settings.dayNamesShort] Abbreviated names of the days from day 0 (Sunday). + @param {string[]} [settings.dayNames] Names of the days from day 0 (Sunday). + @param {string[]} [settings.monthNamesShort] Abbreviated names of the months. + @param {string[]} [settings.monthNames] Names of the months. + @return {CDate} The extracted date value or null if value is blank. + @throws Errors if the format and/or value are missing, + if the value doesn't match the format, or if the date is invalid. */ + parseDate: function(format, value, settings) { + if (typeof value === 'undefined' || value === null) { + throw $.calendars.local.invalidArguments || $.calendars.regionalOptions[''].invalidArguments; + } + value = (typeof value === 'object' ? value.toString() : value + ''); + if (value === '') { + return null; + } + format = format || this.local.dateFormat; + settings = settings || {}; + var shortYearCutoff = settings.shortYearCutoff || this.shortYearCutoff; + shortYearCutoff = (typeof shortYearCutoff !== 'string' ? shortYearCutoff : + this.today().year() % 100 + parseInt(shortYearCutoff, 10)); + var dayNamesShort = settings.dayNamesShort || this.local.dayNamesShort; + var dayNames = settings.dayNames || this.local.dayNames; + var monthNamesShort = settings.monthNamesShort || this.local.monthNamesShort; + var monthNames = settings.monthNames || this.local.monthNames; + var jd = -1; + var year = -1; + var month = -1; + var day = -1; + var doy = -1; + var shortYear = false; + var literal = false; + // Check whether a format character is doubled + var doubled = function(match, step) { + var matches = 1; + while (iFormat + matches < format.length && format.charAt(iFormat + matches) === match) { + matches++; + } + iFormat += matches - 1; + return Math.floor(matches / (step || 1)) > 1; + }; + // Extract a number from the string value + var getNumber = function(match, step) { + var isDoubled = doubled(match, step); + var size = [2, 3, isDoubled ? 4 : 2, isDoubled ? 4 : 2, 10, 11, 20]['oyYJ@!'.indexOf(match) + 1]; + var digits = new RegExp('^-?\\d{1,' + size + '}'); + var num = value.substring(iValue).match(digits); + if (!num) { + throw ($.calendars.local.missingNumberAt || $.calendars.regionalOptions[''].missingNumberAt). + replace(/\{0\}/, iValue); + } + iValue += num[0].length; + return parseInt(num[0], 10); + }; + // Extract a name from the string value and convert to an index + var calendar = this; + var getName = function(match, shortNames, longNames, step) { + var names = (doubled(match, step) ? longNames : shortNames); + for (var i = 0; i < names.length; i++) { + if (value.substr(iValue, names[i].length).toLowerCase() === names[i].toLowerCase()) { + iValue += names[i].length; + return i + calendar.minMonth; + } + } + throw ($.calendars.local.unknownNameAt || $.calendars.regionalOptions[''].unknownNameAt). + replace(/\{0\}/, iValue); + }; + // Confirm that a literal character matches the string value + var checkLiteral = function() { + if (value.charAt(iValue) !== format.charAt(iFormat)) { + throw ($.calendars.local.unexpectedLiteralAt || + $.calendars.regionalOptions[''].unexpectedLiteralAt).replace(/\{0\}/, iValue); + } + iValue++; + }; + var iValue = 0; + for (var iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === '\'' && !doubled('\'')) { + literal = false; + } + else { + checkLiteral(); + } + } + else { + switch (format.charAt(iFormat)) { + case 'd': + day = getNumber('d'); + break; + case 'D': + getName('D', dayNamesShort, dayNames); + break; + case 'o': + doy = getNumber('o'); + break; + case 'w': + getNumber('w'); + break; + case 'm': + month = getNumber('m'); + break; + case 'M': + month = getName('M', monthNamesShort, monthNames); + break; + case 'y': + var iSave = iFormat; + shortYear = !doubled('y', 2); + iFormat = iSave; + year = getNumber('y', 2); + break; + case 'Y': + year = getNumber('Y', 2); + break; + case 'J': + jd = getNumber('J') + 0.5; + if (value.charAt(iValue) === '.') { + iValue++; + getNumber('J'); + } + break; + case '@': + jd = getNumber('@') / this.SECS_PER_DAY + this.UNIX_EPOCH; + break; + case '!': + jd = getNumber('!') / this.TICKS_PER_DAY + this.TICKS_EPOCH; + break; + case '*': + iValue = value.length; + break; + case '\'': + if (doubled('\'')) { + checkLiteral(); + } + else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + if (iValue < value.length) { + throw $.calendars.local.unexpectedText || $.calendars.regionalOptions[''].unexpectedText; + } + if (year === -1) { + year = this.today().year(); + } + else if (year < 100 && shortYear) { + year += (shortYearCutoff === -1 ? 1900 : this.today().year() - + this.today().year() % 100 - (year <= shortYearCutoff ? 0 : 100)); + } + if (doy > -1) { + month = 1; + day = doy; + for (var dim = this.daysInMonth(year, month); day > dim; dim = this.daysInMonth(year, month)) { + month++; + day -= dim; + } + } + return (jd > -1 ? this.fromJD(jd) : this.newDate(year, month, day)); + }, + + /** A date may be specified as an exact value or a relative one. + Found in the jquery.calendars.plus.js module. + @memberof BaseCalendar + @param {CDate|number|string} dateSpec The date as an object or string in the given format or + an offset - numeric days from today, or string amounts and periods, e.g. '+1m +2w'. + @param {CDate} defaultDate The date to use if no other supplied, may be null. + @param {CDate} [currentDate=null] The current date as a possible basis for relative dates, + if null today is used. + @param {string} [dateFormat] The expected date format - + see {@linkcode BaseCalendar.formatDate|formatDate}. Use '' for the calendar default format. + @param {object} [settings] Additional options whose attributes include: + @param {number} [settings.shortYearCutoff] The cutoff year for determining the century. + @param {string[]} [settings.dayNamesShort] Abbreviated names of the days from day 0 (Sunday). + @param {string[]} [settings.dayNames] Names of the days from day 0 (Sunday). + @param {string[]} [settings.monthNamesShort] Abbreviated names of the months. + @param {string[]} [settings.monthNames] Names of the months. + @return {CDate} The decoded date. */ + determineDate: function(dateSpec, defaultDate, currentDate, dateFormat, settings) { + if (currentDate && typeof currentDate !== 'object') { + settings = dateFormat; + dateFormat = currentDate; + currentDate = null; + } + if (typeof dateFormat !== 'string') { + settings = dateFormat; + dateFormat = ''; + } + var calendar = this; + var offsetString = function(offset) { + try { + return calendar.parseDate(dateFormat, offset, settings); + } + catch (e) { + // Ignore + } + offset = offset.toLowerCase(); + var date = (offset.match(/^c/) && currentDate ? + currentDate.newDate() : null) || calendar.today(); + var pattern = /([+-]?[0-9]+)\s*(d|w|m|y)?/g; + var matches = pattern.exec(offset); + while (matches) { + date.add(parseInt(matches[1], 10), matches[2] || 'd'); + matches = pattern.exec(offset); + } + return date; + }; + defaultDate = (defaultDate ? defaultDate.newDate() : null); + dateSpec = (typeof dateSpec === 'undefined' || dateSpec === null ? defaultDate : + (typeof dateSpec === 'string' ? offsetString(dateSpec) : (typeof dateSpec === 'number' ? + (isNaN(dateSpec) || dateSpec === Infinity || dateSpec === -Infinity ? defaultDate : + calendar.today().add(dateSpec, 'd')) : calendar.newDate(dateSpec)))); + return dateSpec; + } + }); + +})(jQuery); diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.plugin.js b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.plugin.js new file mode 100644 index 000000000..179f9e2a7 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/js/jquery.plugin.js @@ -0,0 +1,389 @@ +/* globals JQClass */ +/*! Simple JavaScript Inheritance + * By John Resig http://ejohn.org/ + * MIT Licensed. + */ +// Inspired by base2 and Prototype +import $ from "@/shared/common/jquery-global"; +(function(){ + 'use strict'; + var initializing = false; + + // The base JQClass implementation (does nothing) + window.JQClass = function(){}; + + // Collection of derived classes + JQClass.classes = {}; + + // Create a new JQClass that inherits from this class + JQClass.extend = function extender(prop) { + var base = this.prototype; + + // Instantiate a base class (but only create the instance, don't run the init constructor) + initializing = true; + var prototype = new this(); + initializing = false; + + // Copy the properties over onto the new prototype + for (var name in prop) { // jshint loopfunc:true + // Check if we're overwriting an existing function + if (typeof prop[name] === 'function' && typeof base[name] === 'function') { + prototype[name] = (function (name, fn) { + return function () { + var __super = this._super; + // Add a new ._super() method that is the same method but on the super-class + this._super = function (args) { + return base[name].apply(this, args || []); + }; + var ret = fn.apply(this, arguments); + // The method only needs to be bound temporarily, so we remove it when we're done executing + this._super = __super; + return ret; + }; + })(name, prop[name]); + // Check if we're overwriting existing default options. + } else if (typeof prop[name] === 'object' && typeof base[name] === 'object' && name === 'defaultOptions') { + var obj1 = base[name]; + var obj2 = prop[name]; + var obj3 = {}; + var key; + for (key in obj1) { // jshint forin:false + obj3[key] = obj1[key]; + } + for (key in obj2) { // jshint forin:false + obj3[key] = obj2[key]; + } + prototype[name] = obj3; + } else { + prototype[name] = prop[name]; + } + } + + // The dummy class constructor + function JQClass() { + // All construction is actually done in the init method + if (!initializing && this._init) { + this._init.apply(this, arguments); + } + } + + // Populate our constructed prototype object + JQClass.prototype = prototype; + + // Enforce the constructor to be what we expect + JQClass.prototype.constructor = JQClass; + + // And make this class extendable + JQClass.extend = extender; + + return JQClass; + }; +})(); +/*! Abstract base class for collection plugins v1.0.2. + Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013. + Licensed under the MIT license (http://keith-wood.name/licence.html). */ +(function($) { // Ensure $, encapsulate + 'use strict'; + + /**

Abstract base class for collection plugins v1.0.2.

+

Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013.

+

Licensed under the MIT license (http://keith-wood.name/licence.html).

+

Use {@link $.JQPlugin.createPlugin} to create new plugins using this framework.

+

This base class provides common functionality such as:

+
    +
  • Creates jQuery bridge - allowing you to invoke your plugin on a collection of elements.
  • +
  • Handles initialisation including reading settings from metadata - + an instance object is attached to the affected element(s) containing all the necessary data.
  • +
  • Handles option retrieval and update - options can be set through default values, + through inline metadata, or through instantiation settings.
    + Metadata is specified as an attribute on the element: + data-<pluginName>="<option name>: '<value>', ...". + Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
  • +
  • Handles method calling - inner functions starting with '_'are inaccessible, + whereas others can be called via $(selector).pluginName('functionName').
  • +
  • Handles plugin destruction - removing all trace of the plugin.
  • +
+ @module JQPlugin + @abstract */ + JQClass.classes.JQPlugin = JQClass.extend({ + + /** Name to identify this plugin. + @example name: 'tabs' */ + name: 'plugin', + + /** Default options for instances of this plugin (default: {}). + @example defaultOptions: { + selectedClass: 'selected', + triggers: 'click' +} */ + defaultOptions: {}, + + /** Options dependent on the locale. + Indexed by language and (optional) country code, with '' denoting the default language (English/US). + Normally additional languages would be provided as separate files to all them to be included as needed. + @example regionalOptions: { + '': { + greeting: 'Hi' + } +} */ + regionalOptions: {}, + + /** Whether or not a deep merge should be performed when accumulating options. + The default is true but can be overridden in a sub-class. */ + deepMerge: true, + + /** Retrieve a marker class for affected elements. + In the format: is-<pluginName>. + @protected + @return {string} The marker class. */ + _getMarker: function() { + return 'is-' + this.name; + }, + + /** Initialise the plugin. + Create the jQuery bridge - plugin name xyz + produces singleton $.xyz and collection function $.fn.xyz. + @protected */ + _init: function() { + // Apply default localisations + $.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {}); + // Camel-case the name + var jqName = camelCase(this.name); + // Expose jQuery singleton manager + $[jqName] = this; + // Expose jQuery collection plugin + $.fn[jqName] = function(options) { + var otherArgs = Array.prototype.slice.call(arguments, 1); + var inst = this; + var returnValue = this; + this.each(function () { + if (typeof options === 'string') { + if (options[0] === '_' || !$[jqName][options]) { + throw 'Unknown method: ' + options; + } + var methodValue = $[jqName][options].apply($[jqName], [this].concat(otherArgs)); + if (methodValue !== inst && methodValue !== undefined) { + returnValue = methodValue; + return false; + } + } else { + $[jqName]._attach(this, options); + } + }); + return returnValue; + }; + }, + + /** Set default options for all subsequent instances. + @param {object} options The new default options. + @example $.pluginName.setDefaults({name: value, ...}) */ + setDefaults: function(options) { + $.extend(this.defaultOptions, options || {}); + }, + + /** Initialise an element. Called internally only. + Adds an instance object as data named for the plugin. + Override {@linkcode module:JQPlugin~_postAttach|_postAttach} for plugin-specific processing. + @private + @param {Element} elem The element to enhance. + @param {object} options Overriding settings. */ + _attach: function(elem, options) { + elem = $(elem); + if (elem.hasClass(this._getMarker())) { + return; + } + elem.addClass(this._getMarker()); + options = $.extend(this.deepMerge, {}, this.defaultOptions, this._getMetadata(elem), options || {}); + var inst = $.extend({name: this.name, elem: elem, options: options}, this._instSettings(elem, options)); + elem.data(this.name, inst); // Save instance against element + this._postAttach(elem, inst); + this.option(elem, options); + }, + + /** Retrieve additional instance settings. + Override this in a sub-class to provide extra settings. + These are added directly to the instance object. + Default attributes of an instance object are shown as properties below: + @protected + @param {jQuery} elem The current jQuery element. + @param {object} options The instance options. + @return {object} Any extra instance values. + @property {Element} elem The element to which this instance applies. + @property {string} name The name of this plugin. + @property {object} options The accumulated options for this instance. + @example _instSettings: function(elem, options) { + return {nav: elem.find(options.navSelector)}; +} */ + _instSettings: function(elem, options) { // jshint unused:false + return {}; + }, + + /** Plugin specific post initialisation. + Override this in a sub-class to perform extra activities. + This is where you would implement your plugin's main functionality. + @protected + @param {jQuery} elem The current jQuery element. + @param {object} inst The instance settings. + @example _postAttach: function(elem, inst) { + elem.on('click.' + this.name, function() { + ... + }); +} */ + _postAttach: function(elem, inst) { // jshint unused:false + }, + + /** Retrieve metadata configuration from the element. + Metadata is specified as an attribute: + data-<pluginName>="<option name>: '<value>', ...". + Dates should be specified as strings in this format: 'new Date(y, m-1, d)'. + @private + @param {jQuery} elem The source element. + @return {object} The inline configuration or {}. */ + _getMetadata: function(elem) { + try { + var data = elem.data(this.name.toLowerCase()) || ''; + data = data.replace(/(\\?)'/g, function(e, t) { + return t ? '\'' : '"'; + }).replace(/([a-zA-Z0-9]+):/g, function(match, group, i) { + var count = data.substring(0, i).match(/"/g); // Handle embedded ':' + return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':'); + }).replace(/\\:/g, ':'); + data = $.parseJSON('{' + data + '}'); + for (var key in data) { + if (data.hasOwnProperty(key)) { + var value = data[key]; + if (typeof value === 'string' && value.match(/^new Date\(([-0-9,\s]*)\)$/)) { // Convert dates + data[key] = eval(value); // jshint ignore:line + } + } + } + return data; + } + catch (e) { + return {}; + } + }, + + /** Retrieve the instance data for element. + @protected + @param {Element} elem The source element. + @return {object} The instance data or {} if none. */ + _getInst: function(elem) { + return $(elem).data(this.name) || {}; + }, + + /** Retrieve or reconfigure the settings for a plugin. + If new settings are provided they are applied to the instance options. + If an option name only is provided the value of that option is returned. + If no name or value is provided, all options are returned. + Override {@linkcode module:JQPlugin~_optionsChanged|_optionsChanged} + for plugin-specific processing when option values change. + @param {Element} elem The source element. + @param {object|string} [name] The collection of new option values or the name of a single option. + @param {any} [value] The value for a single named option. + @return {any|object} If retrieving a single value or all options. + @example $(selector).plugin('option', 'name', value) // Set one option +$(selector).plugin('option', {name: value, ...}) // Set multiple options +var value = $(selector).plugin('option', 'name') // Get one option +var options = $(selector).plugin('option') // Get all options */ + option: function(elem, name, value) { + elem = $(elem); + var inst = elem.data(this.name); + var options = name || {}; + if (!name || (typeof name === 'string' && typeof value === 'undefined')) { + options = (inst || {}).options; + return (options && name ? options[name] : options); + } + if (!elem.hasClass(this._getMarker())) { + return; + } + if (typeof name === 'string') { + options = {}; + options[name] = value; + } + this._optionsChanged(elem, inst, options); + $.extend(inst.options, options); + }, + + /** Plugin specific options processing. + Old value available in inst.options[name], new value in options[name]. + Override this in a sub-class to perform extra activities. + @protected + @param {jQuery} elem The current jQuery element. + @param {object} inst The instance settings. + @param {object} options The new options. + @example _optionsChanged: function(elem, inst, options) { + if (options.name != inst.options.name) { + elem.removeClass(inst.options.name).addClass(options.name); + } +} */ + _optionsChanged: function(elem, inst, options) { // jshint unused:false + }, + + /** Remove all trace of the plugin. + Override {@linkcode module:JQPlugin~_preDestroy|_preDestroy} for plugin-specific processing. + @param {Element} elem The source element. + @example $(selector).plugin('destroy') */ + destroy: function(elem) { + elem = $(elem); + if (!elem.hasClass(this._getMarker())) { + return; + } + this._preDestroy(elem, this._getInst(elem)); + elem.removeData(this.name).removeClass(this._getMarker()); + }, + + /** Plugin specific pre destruction. + It is invoked as part of the {@linkcode module:JQPlugin~destroy|destroy} processing. + Override this in a sub-class to perform extra activities and undo everything that was + done in the {@linkcode module:JQPlugin~_postAttach|_postAttach} or + {@linkcode module:JQPlugin~_optionsChanged|_optionsChanged} functions. + @protected + @param {jQuery} elem The current jQuery element. + @param {object} inst The instance settings. + @example _preDestroy: function(elem, inst) { + elem.off('.' + this.name); +} */ + _preDestroy: function(elem, inst) { // jshint unused:false + } + }); + + /** Convert names from hyphenated to camel-case. + @private + @param {string} value The original hyphenated name. + @return {string} The camel-case version. */ + function camelCase(name) { + return name.replace(/-([a-z])/g, function(match, group) { + return group.toUpperCase(); + }); + } + + /** Expose the plugin base. + @namespace $.JQPlugin */ + $.JQPlugin = { + + /** Create a new collection plugin. + @memberof $.JQPlugin + @param {string} [superClass='JQPlugin'] The name of the parent class to inherit from. + @param {object} overrides The property/function overrides for the new class. + See {@link module:JQPlugin|JQPlugin} for the base functionality. + @example $.JQPlugin.createPlugin({ // Define the plugin + name: 'tabs', + defaultOptions: {selectedClass: 'selected'}, + _initSettings: function(elem, options) { return {...}; }, + _postAttach: function(elem, inst) { ... } +}); +$('selector').tabs(); // And instantiate it */ + createPlugin: function(superClass, overrides) { + if (typeof superClass === 'object') { + overrides = superClass; + superClass = 'JQPlugin'; + } + superClass = camelCase(superClass); + var className = camelCase(overrides.name); + JQClass.classes[className] = JQClass.classes[superClass].extend(overrides); + new JQClass.classes[className](); // jshint ignore:line + } + }; + +})(jQuery); \ No newline at end of file diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/localizedName.ts b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/localizedName.ts new file mode 100644 index 000000000..cfa1ba2a1 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/localizedName.ts @@ -0,0 +1,21 @@ +import { useCallback } from "react"; +import { useTranslation } from "react-i18next"; + +export type LocalizedText = { + am?: string; + en?: string; +}; + +export const useLocalizedName = (language?: string) => { + const { i18n } = useTranslation(); + const currentLanguage = language || i18n.language; + return useCallback( + (name?: LocalizedText): string => { + if (!name) return ""; + const am = name.am?.trim() ?? ""; + const en = name.en?.trim() ?? ""; + return (currentLanguage.startsWith("am") ? am || en : en || am) || ""; + }, + [currentLanguage], + ); +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/FayidaInput.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/FayidaInput.tsx new file mode 100644 index 000000000..8144409db --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/FayidaInput.tsx @@ -0,0 +1,29 @@ +import * as React from "react"; +import { Input } from "@/shared/common/ui/input"; // your Input component + +interface FaydaInputProps { + faydaValue: string; + setFaydaValue: (value: string) => void; // make sure it's not optional +} + +export const FaydaInput: React.FC = ({ + faydaValue, + setFaydaValue, +}) => { + return ( +
+ +
+ ); +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/LoadingOverlay.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/LoadingOverlay.tsx new file mode 100644 index 000000000..56c5cb688 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/LoadingOverlay.tsx @@ -0,0 +1,20 @@ +import { Progress } from "@/shared/common/ui/progress"; + +interface LoadingOverlayProps { + progress?: number; + text?: string; +} + +export function LoadingOverlay({ + progress = 50, + text = "Processing...", +}: LoadingOverlayProps) { + return ( +
+
+ {text} +
+ +
+ ); +} diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/SliderUI.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/SliderUI.tsx new file mode 100644 index 000000000..7fb80e885 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/SliderUI.tsx @@ -0,0 +1,53 @@ +import { FC } from "react"; +// @ts-ignore - Module types not available +import * as SliderPrimitive from "@radix-ui/react-slider"; + +interface SliderUIProps { + id?: string; + label: string; + description?: string; + value: number[]; + onChange: (value: number) => void; + min?: number; + max?: number; + step?: number; + required?: boolean; + disabled?: boolean; +} + +export const SliderUI: FC = ({ + id, + label, + description, + value, + onChange, + min = 0, + max = 100, + step = 1, + required = false, + disabled = false, +}) => { + return ( +
+ + {description &&

{description}

} + onChange(val[0])} + min={min} + max={max} + step={step} + disabled={disabled} + className="relative flex w-full touch-none select-none items-center h-5"> + + + + + +
{value}
+
+ ); +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/Text.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/Text.tsx new file mode 100644 index 000000000..6c241106a --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/Text.tsx @@ -0,0 +1,25 @@ +// src/shared/common/ui/text.tsx +import React from "react"; + +type TextProps = React.HTMLAttributes & { + fw?: number | string; + color?: string; + size?: string | number; +}; + +export const Text: React.FC = ({ + fw, + color, + size, + style, + children, + ...props +}) => { + return ( + + {children} + + ); +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/accordion.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/accordion.tsx new file mode 100644 index 000000000..5ccc88336 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/accordion.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDownIcon } from "lucide-react"; + +import { cn } from "@/shared/lib/utils"; + +function Accordion({ + ...props +}: React.ComponentProps) { + return ; +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + + ); +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ); +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert-dialog.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert-dialog.tsx new file mode 100644 index 000000000..131445477 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert-dialog.tsx @@ -0,0 +1,155 @@ +import * as React from "react"; +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; + +import { cn } from "@/shared/lib/utils"; +import { buttonVariants } from "@/shared/common/ui/button"; + +function AlertDialog({ + ...props +}: React.ComponentProps) { + return ; +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogPortal({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ); +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +}; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert.tsx new file mode 100644 index 000000000..af7130e7f --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/alert.tsx @@ -0,0 +1,58 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/super-admin/lib/utils"; + +const alertVariants = cva( + "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + } +); + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)); +Alert.displayName = "Alert"; + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +AlertTitle.displayName = "AlertTitle"; + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +AlertDescription.displayName = "AlertDescription"; + +export { Alert, AlertTitle, AlertDescription }; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/avatar.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/avatar.tsx new file mode 100644 index 000000000..812e64e47 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/avatar.tsx @@ -0,0 +1,53 @@ +"use client"; + +import * as React from "react"; +import * as AvatarPrimitive from "@radix-ui/react-avatar"; + +import { cn } from "@/super-admin/lib/utils"; + +function Avatar({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AvatarImage({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AvatarFallback({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/badge.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/badge.tsx new file mode 100644 index 000000000..c9c016ee7 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/badge.tsx @@ -0,0 +1,62 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/shared/lib/utils"; +//the status edit +const badgeVariants = cva( + "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", + { + variants: { + variant: { + //draft and forward + default: + "bg-blue-100 text-blue-800 text-sm font-medium me-2 px-3 py-0.5 rounded-full dark:bg-blue-900 dark:text-blue-300", + secondary: + "bg-indigo-100 text-indigo-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-indigo-900 dark:text-indigo-300", + destructive: + "bg-gray-100 text-gray-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-sm dark:bg-gray-700 dark:text-gray-300", + outline: + "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + info: "border-transparent bg-info text-info-foreground [a&]:hover:bg-info/90", + purple: + "bg-purple-100 text-purple-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-purple-900 dark:text-purple-300", + warning: + "bg-pink-100 text-pink-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-pink-900 dark:text-pink-300", + //approved + success: + "bg-green-100 text-green-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-green-900 dark:text-green-300", + danger: + "bg-red-100 text-red-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-red-900 dark:text-red-300", + danger2: + "bg-yellow-100 text-yellow-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-yellow-900 dark:text-yellow-300", + forward: + "bg-orange-100 text-orange-800 text-sm font-medium me-2 px-3 py-0.5 rounded-full dark:bg-orange-900 dark:text-orange-300", + dispatched: + "bg-green-100 text-green-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-green-900 dark:text-green-300", + }, + }, + defaultVariants: { + variant: "default", + }, + } +); +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<"span"> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : "span"; + + return ( + + ); +} + +export { Badge, badgeVariants }; diff --git a/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/breadcrumb.tsx b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/breadcrumb.tsx new file mode 100644 index 000000000..d1bb88e84 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/new-user-management-ui/shared/common/ui/breadcrumb.tsx @@ -0,0 +1,109 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; + +import { cn } from "@/shared/lib/utils"; + +function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { + return