@anzusystems/common-admin 2.0.0-rc.5 → 2.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AnzuSystemsCommonAdmin.d.ts +42 -32
- package/dist/AnzuSystemsCommonAdmin.js.map +1 -1
- package/dist/common-admin.css +1 -1
- package/dist/common-admin.js +282 -282
- package/dist/domains/anzuUser/api/anzuUserApi.d.ts +9 -12
- package/dist/domains/anzuUser/api/anzuUserApi.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserDatatable.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue.d.ts +38 -44
- package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserFilter.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserFilter.vue.d.ts +12 -13
- package/dist/domains/anzuUser/components/AAnzuUserFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserForm.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserForm.vue.d.ts +18 -20
- package/dist/domains/anzuUser/components/AAnzuUserForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.js.map +1 -1
- package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserBulkActionDialog.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserBulkActionDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue.d.ts +2 -3
- package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserCreateInSystemButton.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue.d.ts +9 -15
- package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserEnabledSwitch.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue.d.ts +8 -7
- package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserManageButton.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserManageButton.vue.d.ts +0 -1
- package/dist/domains/anzuUser/components/AUserManageButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserMetadataForm.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserMetadataForm.vue.d.ts +8 -9
- package/dist/domains/anzuUser/components/AUserMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserOtherSystemsTable.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue.d.ts +1 -2
- package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemOverview.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemOverview.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemPanel.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemPanel.vue.d.ts +2 -2
- package/dist/domains/anzuUser/components/AUserSystemPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemStatusChip.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserSystemStatusChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserTabsShell.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserTabsShell.vue.d.ts +17 -22
- package/dist/domains/anzuUser/components/AUserTabsShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/anzuUser/composables/anzuUserActions.d.ts +5 -9
- package/dist/domains/anzuUser/composables/anzuUserActions.js.map +1 -1
- package/dist/domains/anzuUser/composables/anzuUserValidations.d.ts +4 -6
- package/dist/domains/anzuUser/composables/anzuUserValidations.js.map +1 -1
- package/dist/domains/anzuUser/composables/cachedAnzuUsers.d.ts +3 -3
- package/dist/domains/anzuUser/composables/cachedAnzuUsers.js.map +1 -1
- package/dist/domains/anzuUser/composables/userCrossSystemSearch.d.ts +2 -4
- package/dist/domains/anzuUser/composables/userCrossSystemSearch.js.map +1 -1
- package/dist/domains/anzuUser/composables/userCrossSystemWrites.d.ts +5 -11
- package/dist/domains/anzuUser/composables/userCrossSystemWrites.js.map +1 -1
- package/dist/domains/anzuUser/composables/userSystemDescriptor.d.ts +33 -57
- package/dist/domains/anzuUser/composables/userSystemDescriptor.js.map +1 -1
- package/dist/domains/anzuUser/composables/userSystemProbe.d.ts +7 -27
- package/dist/domains/anzuUser/composables/userSystemProbe.js.map +1 -1
- package/dist/domains/anzuUser/filter/anzuUserFilter.d.ts +6 -16
- package/dist/domains/anzuUser/filter/anzuUserFilter.js.map +1 -1
- package/dist/domains/anzuUser/store/anzuUserStore.d.ts +1 -5
- package/dist/domains/anzuUser/store/anzuUserStore.js.map +1 -1
- package/dist/domains/anzuUser/store/userCrossSystemStore.d.ts +3 -14
- package/dist/domains/anzuUser/store/userCrossSystemStore.js.map +1 -1
- package/dist/domains/anzuUser/utils/userMetadataDiff.d.ts +7 -19
- package/dist/domains/anzuUser/utils/userMetadataDiff.js.map +1 -1
- package/dist/domains/anzuUser/utils/userSystemState.d.ts +12 -30
- package/dist/domains/anzuUser/utils/userSystemState.js.map +1 -1
- package/dist/domains/anzuUser/utils/userTabs.d.ts +1 -3
- package/dist/domains/anzuUser/utils/userTabs.js.map +1 -1
- package/dist/domains/api/composables/defineApiClient.d.ts +4 -8
- package/dist/domains/api/composables/defineApiClient.js.map +1 -1
- package/dist/domains/api/composables/request.d.ts +18 -48
- package/dist/domains/api/composables/request.js.map +1 -1
- package/dist/domains/api/composables/useApiFetchByIds.d.ts +7 -21
- package/dist/domains/api/composables/useApiFetchByIds.js.map +1 -1
- package/dist/domains/api/composables/useApiFetchItems.d.ts +18 -57
- package/dist/domains/api/composables/useApiFetchItems.js.map +1 -1
- package/dist/domains/api/composables/useApiFetchList.d.ts +7 -23
- package/dist/domains/api/composables/useApiFetchList.js.map +1 -1
- package/dist/domains/api/composables/useApiFetchListBatch.d.ts +5 -22
- package/dist/domains/api/composables/useApiFetchListBatch.js.map +1 -1
- package/dist/domains/api/composables/useApiQueryBuilder.js.map +1 -1
- package/dist/domains/api/composables/useApiRequest.d.ts +16 -39
- package/dist/domains/api/composables/useApiRequest.js.map +1 -1
- package/dist/domains/api/utils/apiErrors.d.ts +28 -55
- package/dist/domains/api/utils/apiErrors.js.map +1 -1
- package/dist/domains/api/utils/listBody.d.ts +22 -43
- package/dist/domains/api/utils/listBody.js.map +1 -1
- package/dist/domains/auth/components/Acl.js.map +1 -1
- package/dist/domains/auth/components/Acl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/auth/composables/aclAllowed.d.ts +2 -3
- package/dist/domains/auth/composables/aclAllowed.js.map +1 -1
- package/dist/domains/auth/composables/defineAuth.js.map +1 -1
- package/dist/domains/auth/composables/refreshSession.d.ts +10 -13
- package/dist/domains/auth/composables/refreshSession.js.map +1 -1
- package/dist/domains/cached/components/ACachedChip.js.map +1 -1
- package/dist/domains/cached/components/ACachedChip.vue.d.ts +13 -11
- package/dist/domains/cached/components/ACachedChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/cached/components/ACachedUserChip.js +1 -1
- package/dist/domains/cached/components/ACachedUserChip.js.map +1 -1
- package/dist/domains/cached/components/ACachedUserChip.vue.d.ts +3 -3
- package/dist/domains/cached/components/ACachedUserChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/cached/composables/createUserAndTimeTrackingFields.d.ts +9 -9
- package/dist/domains/cached/composables/createUserAndTimeTrackingFields.js.map +1 -1
- package/dist/domains/cached/composables/defineCached.d.ts +13 -11
- package/dist/domains/cached/composables/defineCached.js.map +1 -1
- package/dist/domains/cached/composables/useCachedItem.d.ts +7 -8
- package/dist/domains/cached/composables/useCachedItem.js.map +1 -1
- package/dist/domains/collab/components/ACollabLockedByUser.js.map +1 -1
- package/dist/domains/collab/components/ACollabLockedByUser.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/collab/composables/collabAnyDataChange.js.map +1 -1
- package/dist/domains/collab/composables/collabField.d.ts +5 -3
- package/dist/domains/collab/composables/collabField.js.map +1 -1
- package/dist/domains/collab/composables/collabInit.js +58 -54
- package/dist/domains/collab/composables/collabInit.js.map +1 -1
- package/dist/domains/collab/composables/collabRecovery.d.ts +49 -0
- package/dist/domains/collab/composables/collabRecovery.js +99 -0
- package/dist/domains/collab/composables/collabRecovery.js.map +1 -0
- package/dist/domains/collab/composables/collabRoom.js +106 -106
- package/dist/domains/collab/composables/collabRoom.js.map +1 -1
- package/dist/domains/collab/composables/collabState.d.ts +11 -4
- package/dist/domains/collab/composables/collabState.js +34 -25
- package/dist/domains/collab/composables/collabState.js.map +1 -1
- package/dist/domains/collab/composables/commonAdminCollabOptions.d.ts +4 -2
- package/dist/domains/collab/types/Collab.d.ts +31 -5
- package/dist/domains/collab/types/Collab.js +23 -11
- package/dist/domains/collab/types/Collab.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataForm.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataForm.vue.d.ts +7 -5
- package/dist/domains/customDataForm/components/ACustomDataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataFormElement.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataFormElement.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue.d.ts +5 -3
- package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/customDataForm/composables/useCustomDataForm.js.map +1 -1
- package/dist/domains/customDataForm/types/CustomDataForm.d.ts +4 -1
- package/dist/domains/dam/api/damAssetApi.d.ts +7 -7
- package/dist/domains/dam/api/damAssetApi.js.map +1 -1
- package/dist/domains/dam/api/damAssetLicenceApi.d.ts +1 -1
- package/dist/domains/dam/api/damAssetLicenceApi.js.map +1 -1
- package/dist/domains/dam/api/damConstants.js.map +1 -1
- package/dist/domains/dam/api/damEndPoints.js.map +1 -1
- package/dist/domains/dam/api/damImageApi.js.map +1 -1
- package/dist/domains/dam/api/uploadApi.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue.d.ts +7 -5
- package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialog.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue.d.ts +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsWrapper.vue.d.ts +5 -3
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue.d.ts +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetImage.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetImage.vue.d.ts +1 -1
- package/dist/domains/dam/assetDetail/components/AssetImage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue.d.ts +2 -2
- package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetInfobox.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetInfobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetMetadata.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.d.ts +5 -6
- package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.js.map +1 -1
- package/dist/domains/dam/assetDetail/composables/assetDetailView.d.ts +10 -10
- package/dist/domains/dam/assetDetail/composables/assetDetailView.js.map +1 -1
- package/dist/domains/dam/assetDetail/store/assetDetailStore.js.map +1 -1
- package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.d.ts +4 -3
- package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.js.map +1 -1
- package/dist/domains/dam/assetSelect/api/damPodcastApi.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetListInner.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetListInner.vue.d.ts +789 -787
- package/dist/domains/dam/assetSelect/components/AAssetListInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetSelect.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetSelect.vue.d.ts +395 -393
- package/dist/domains/dam/assetSelect/components/AAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue.d.ts +14 -12
- package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListBar.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue.d.ts +9 -7
- package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/composables/assetSelectListActions.js.map +1 -1
- package/dist/domains/dam/assetSelect/store/assetSelectStore.js.map +1 -1
- package/dist/domains/dam/author/api/authorApi.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorCreateButton.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorCreateButton.vue.d.ts +1 -1
- package/dist/domains/dam/author/components/AuthorCreateButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue.d.ts +9 -6
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue.d.ts +2 -2
- package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue.d.ts +1 -1
- package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/author/composables/cachedAuthors.d.ts +5 -4
- package/dist/domains/dam/author/composables/cachedAuthors.js.map +1 -1
- package/dist/domains/dam/author/composables/cachedUsers.d.ts +5 -4
- package/dist/domains/dam/author/composables/cachedUsers.js.map +1 -1
- package/dist/domains/dam/author/composables/damAuthorConfig.d.ts +2 -2
- package/dist/domains/dam/author/composables/damAuthorConfig.js.map +1 -1
- package/dist/domains/dam/components/DamAdminAssetLink.js.map +1 -1
- package/dist/domains/dam/components/DamAdminAssetLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/composables/commonAdminCoreDamOptions.d.ts +10 -8
- package/dist/domains/dam/composables/commonAdminCoreDamOptions.js.map +1 -1
- package/dist/domains/dam/composables/damConfigName.d.ts +8 -9
- package/dist/domains/dam/composables/damConfigName.js.map +1 -1
- package/dist/domains/dam/composables/damNotifications.d.ts +9 -9
- package/dist/domains/dam/composables/damNotifications.js.map +1 -1
- package/dist/domains/dam/composables/damNotificationsConnection.d.ts +4 -4
- package/dist/domains/dam/composables/damNotificationsConnection.js.map +1 -1
- package/dist/domains/dam/composables/damNotificationsEventBus.d.ts +2 -2
- package/dist/domains/dam/composables/damNotificationsEventBus.js.map +1 -1
- package/dist/domains/dam/composables/extSystemIdForCached.d.ts +5 -4
- package/dist/domains/dam/composables/extSystemIdForCached.js.map +1 -1
- package/dist/domains/dam/config/api/damAssetCustomFormApi.js.map +1 -1
- package/dist/domains/dam/config/api/damConfigApi.js.map +1 -1
- package/dist/domains/dam/config/composables/damConfigState.d.ts +5 -5
- package/dist/domains/dam/config/composables/damConfigState.js.map +1 -1
- package/dist/domains/dam/config/store/damConfigStore.d.ts +5 -4
- package/dist/domains/dam/config/store/damConfigStore.js.map +1 -1
- package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.d.ts +3 -1
- package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.js.map +1 -1
- package/dist/domains/dam/cropper/components/ACropper.js.map +1 -1
- package/dist/domains/dam/cropper/components/ACropper.vue.d.ts +8 -16
- package/dist/domains/dam/cropper/components/ACropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.js.map +1 -1
- package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/cropper/store/imageRoiStore.d.ts +9 -12
- package/dist/domains/dam/cropper/store/imageRoiStore.js.map +1 -1
- package/dist/domains/dam/cropper/utils/cropperGeometry.d.ts +24 -38
- package/dist/domains/dam/cropper/utils/cropperGeometry.js.map +1 -1
- package/dist/domains/dam/cropper/utils/cropperJsService.d.ts +3 -7
- package/dist/domains/dam/cropper/utils/cropperJsService.js +10 -3
- package/dist/domains/dam/cropper/utils/cropperJsService.js.map +1 -1
- package/dist/domains/dam/cropper/utils/cropperTypes.d.ts +3 -6
- package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.d.ts +5 -5
- package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageMediaWidget.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageMediaWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImagePublicInput.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImagePublicInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidget.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidgetSimple.vue.d.ts +43 -41
- package/dist/domains/dam/imageWidget/components/AMediaWidgetSimple.vue.d.ts +31 -29
- package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue.d.ts +29 -27
- package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageMassOperations.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue.d.ts +1 -1
- package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue.d.ts +68 -66
- package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetInner.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue.d.ts +402 -400
- package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue.d.ts +384 -382
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/MediaWidgetSimpleDialog.vue.d.ts +7 -5
- package/dist/domains/dam/imageWidget/composables/commonAdminImageOptions.js.map +1 -1
- package/dist/domains/dam/imageWidget/composables/imageApiCms.js.map +1 -1
- package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.d.ts +11 -13
- package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.js.map +1 -1
- package/dist/domains/dam/imageWidget/composables/useImageMassOperations.js.map +1 -1
- package/dist/domains/dam/imageWidget/store/imageMediaWidgetStore.js.map +1 -1
- package/dist/domains/dam/imageWidget/store/imageStore.js.map +1 -1
- package/dist/domains/dam/imageWidget/utils/damImage.d.ts +5 -6
- package/dist/domains/dam/imageWidget/utils/damImage.js.map +1 -1
- package/dist/domains/dam/imageWidget/utils/fieldLockTurns.d.ts +1 -2
- package/dist/domains/dam/imageWidget/utils/fieldLockTurns.js.map +1 -1
- package/dist/domains/dam/imageWidget/utils/imageSaves.d.ts +10 -14
- package/dist/domains/dam/imageWidget/utils/imageSaves.js.map +1 -1
- package/dist/domains/dam/imageWidget/utils/metadataToImageMap.js.map +1 -1
- package/dist/domains/dam/imageWidget/utils/waitLimit.d.ts +4 -6
- package/dist/domains/dam/imageWidget/utils/waitLimit.js.map +1 -1
- package/dist/domains/dam/keyword/api/keywordApi.js.map +1 -1
- package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue.d.ts +1 -1
- package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.js.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue.d.ts +8 -5
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue.d.ts +2 -2
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/keyword/composables/cachedKeywords.d.ts +5 -4
- package/dist/domains/dam/keyword/composables/cachedKeywords.js.map +1 -1
- package/dist/domains/dam/keyword/composables/damKeywordConfig.d.ts +2 -2
- package/dist/domains/dam/keyword/composables/damKeywordConfig.js.map +1 -1
- package/dist/domains/dam/types/Asset.d.ts +1 -1
- package/dist/domains/dam/types/Asset.js.map +1 -1
- package/dist/domains/dam/types/UploadQueue.d.ts +5 -4
- package/dist/domains/dam/types/UploadQueue.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue.d.ts +2 -2
- package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue.d.ts +6 -4
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue.d.ts +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue.d.ts +6 -6
- package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue.d.ts +13 -13
- package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.d.ts +13 -13
- package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.js.map +1 -1
- package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.d.ts +2 -2
- package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.js.map +1 -1
- package/dist/domains/dam/uploadQueue/composables/uploadMeter.d.ts +12 -12
- package/dist/domains/dam/uploadQueue/composables/uploadMeter.js.map +1 -1
- package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.d.ts +5 -5
- package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.js.map +1 -1
- package/dist/domains/dam/uploadQueue/composables/uploadService.d.ts +2 -3
- package/dist/domains/dam/uploadQueue/composables/uploadService.js.map +1 -1
- package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.d.ts +5 -4
- package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.js.map +1 -1
- package/dist/domains/dam/uploadQueue/core/uploadQueueCore.d.ts +3 -2
- package/dist/domains/dam/uploadQueue/core/uploadQueueCore.js.map +1 -1
- package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.d.ts +8 -5
- package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.js.map +1 -1
- package/dist/domains/dam/uploadQueue/core/uploadQueueFill.d.ts +3 -3
- package/dist/domains/dam/uploadQueue/core/uploadQueueFill.js.map +1 -1
- package/dist/domains/dam/uploadQueue/presets/queuePresets.d.ts +8 -5
- package/dist/domains/dam/uploadQueue/presets/queuePresets.js.map +1 -1
- package/dist/domains/dam/uploadQueue/presets/uploadPresets.d.ts +15 -13
- package/dist/domains/dam/uploadQueue/presets/uploadPresets.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.d.ts +7 -7
- package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadPoller.d.ts +4 -4
- package/dist/domains/dam/uploadQueue/settlement/uploadPoller.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadSettle.d.ts +28 -30
- package/dist/domains/dam/uploadQueue/settlement/uploadSettle.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.d.ts +2 -2
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.d.ts +2 -2
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.js.map +1 -1
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.d.ts +63 -73
- package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.js.map +1 -1
- package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.d.ts +8 -9
- package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.js.map +1 -1
- package/dist/domains/dam/user/api/userApi.d.ts +2 -2
- package/dist/domains/dam/user/api/userApi.js.map +1 -1
- package/dist/domains/dam/user/components/DamDistributionServiceSelect.js.map +1 -1
- package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue.d.ts +1 -1
- package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.js.map +1 -1
- package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue.d.ts +1 -1
- package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue.d.ts +1 -1
- package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/user/composables/damUserSelectActions.d.ts +1 -1
- package/dist/domains/dam/user/composables/damUserSelectActions.js.map +1 -1
- package/dist/domains/dam/user/types/DamDistributionServiceType.d.ts +2 -2
- package/dist/domains/dam/user/types/DamDistributionServiceType.js.map +1 -1
- package/dist/domains/dam/user/types/DamExternalProviderAssetType.d.ts +1 -1
- package/dist/domains/dam/user/types/DamExternalProviderAssetType.js.map +1 -1
- package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.js.map +1 -1
- package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/bookmarks/store/bookmarksStore.d.ts +3 -3
- package/dist/domains/filters/bookmarks/store/bookmarksStore.js.map +1 -1
- package/dist/domains/filters/components/AFilterDatetimePicker.js.map +1 -1
- package/dist/domains/filters/components/AFilterDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterInteger.js.map +1 -1
- package/dist/domains/filters/components/AFilterInteger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterString.js.map +1 -1
- package/dist/domains/filters/components/AFilterString.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterTimeInterval.js +1 -1
- package/dist/domains/filters/components/AFilterTimeInterval.js.map +1 -1
- package/dist/domains/filters/components/AFilterTimeInterval.vue.d.ts +5 -3
- package/dist/domains/filters/components/AFilterTimeInterval.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.js.map +1 -1
- package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterWrapper.vue.d.ts +17 -15
- package/dist/domains/filters/components/AFilterWrapperSidebar.vue.d.ts +5 -3
- package/dist/domains/filters/components/FiltersSelected.js.map +1 -1
- package/dist/domains/filters/components/FiltersSelected.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/composables/filterFactory.d.ts +16 -26
- package/dist/domains/filters/composables/filterFactory.js +38 -31
- package/dist/domains/filters/composables/filterFactory.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatableOrdering.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatablePagination.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js +2 -4
- package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/utils/filterInjectionKeys.js.map +1 -1
- package/dist/domains/form/components/AFormDatetimePicker.js.map +1 -1
- package/dist/domains/form/components/AFormDatetimePicker.vue.d.ts +7 -5
- package/dist/domains/form/components/AFormDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormFlagDatetimePicker.js.map +1 -1
- package/dist/domains/form/components/AFormFlagDatetimePicker.vue.d.ts +7 -5
- package/dist/domains/form/components/AFormFlagDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormSwitch.vue.d.ts +7 -5
- package/dist/domains/form/components/AFormTextField.js.map +1 -1
- package/dist/domains/form/components/AFormTextField.vue.d.ts +9 -7
- package/dist/domains/form/components/AFormTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormTextarea.vue.d.ts +13 -11
- package/dist/domains/form/components/AFormValueObjectOptionsSelect.vue.d.ts +7 -5
- package/dist/domains/form/components/ASystemEntityScope.vue.d.ts +5 -3
- package/dist/domains/job/api/jobApi.js.map +1 -1
- package/dist/domains/job/components/AJobDetailCommon.vue.d.ts +5 -3
- package/dist/domains/listEditor/components/AListEditor.js.map +1 -1
- package/dist/domains/listEditor/components/AListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/ANestedSortableListEditor.js.map +1 -1
- package/dist/domains/listEditor/components/ANestedSortableListEditor.vue.d.ts +2 -3
- package/dist/domains/listEditor/components/ANestedSortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/ASortableListEditor.js.map +1 -1
- package/dist/domains/listEditor/components/ASortableListEditor.vue.d.ts +2 -3
- package/dist/domains/listEditor/components/ASortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/composables/useListEditorController.d.ts +4 -5
- package/dist/domains/listEditor/composables/useListEditorController.js.map +1 -1
- package/dist/domains/listEditor/composables/useNestedListEditor.d.ts +3 -4
- package/dist/domains/listEditor/composables/useNestedListEditor.js.map +1 -1
- package/dist/domains/listEditor/composables/useNestedListEditorController.d.ts +5 -4
- package/dist/domains/listEditor/composables/useNestedListEditorController.js.map +1 -1
- package/dist/domains/listEditor/composables/useReorderMode.js.map +1 -1
- package/dist/domains/listEditor/types/listEditorTypes.d.ts +2 -2
- package/dist/domains/listEditor/utils/listEditorLoader.d.ts +5 -5
- package/dist/domains/listEditor/utils/listEditorLoader.js.map +1 -1
- package/dist/domains/listEditor/utils/resolveCompactText.js.map +1 -1
- package/dist/domains/log/api/logApi.d.ts +2 -3
- package/dist/domains/log/api/logApi.js.map +1 -1
- package/dist/domains/log/components/ALogDatatable.js.map +1 -1
- package/dist/domains/log/components/ALogDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/log/components/ALogDetailView.js.map +1 -1
- package/dist/domains/log/components/ALogDetailView.vue.d.ts +1 -1
- package/dist/domains/log/components/ALogDetailView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/log/components/ALogFilter.js.map +1 -1
- package/dist/domains/log/components/ALogFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/log/components/ALogListView.js.map +1 -1
- package/dist/domains/log/components/ALogListView.vue.d.ts +1 -1
- package/dist/domains/log/components/ALogListView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/log/composables/logActions.d.ts +4 -5
- package/dist/domains/log/composables/logActions.js.map +1 -1
- package/dist/domains/log/composables/logType.d.ts +6 -7
- package/dist/domains/log/composables/logType.js.map +1 -1
- package/dist/domains/log/filter/logFilter.d.ts +8 -11
- package/dist/domains/log/filter/logFilter.js.map +1 -1
- package/dist/domains/permission/components/APermissionEditor.js.map +1 -1
- package/dist/domains/permission/components/APermissionEditor.vue.d.ts +4 -4
- package/dist/domains/permission/components/APermissionEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/composables/permissionActions.d.ts +3 -6
- package/dist/domains/permission/composables/permissionActions.js.map +1 -1
- package/dist/domains/permission/config/api/permissionConfigApi.d.ts +2 -2
- package/dist/domains/permission/config/api/permissionConfigApi.js.map +1 -1
- package/dist/domains/permission/config/composables/permissionConfigActions.d.ts +3 -7
- package/dist/domains/permission/config/composables/permissionConfigActions.js.map +1 -1
- package/dist/domains/permission/config/store/permissionConfigStore.d.ts +2 -4
- package/dist/domains/permission/config/store/permissionConfigStore.js.map +1 -1
- package/dist/domains/permission/group/api/permissionGroupApi.d.ts +8 -10
- package/dist/domains/permission/group/api/permissionGroupApi.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupDatatable.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupDatatable.vue.d.ts +12 -10
- package/dist/domains/permission/group/components/APermissionGroupDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupDetail.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupDetail.vue.d.ts +21 -22
- package/dist/domains/permission/group/components/APermissionGroupDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupManage.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupManage.vue.d.ts +21 -22
- package/dist/domains/permission/group/components/APermissionGroupManage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/group/composables/cachedPermissionGroups.js.map +1 -1
- package/dist/domains/permission/group/composables/permissionGroupActions.d.ts +6 -8
- package/dist/domains/permission/group/composables/permissionGroupActions.js.map +1 -1
- package/dist/domains/permission/group/composables/permissionGroupValidations.d.ts +2 -3
- package/dist/domains/permission/group/composables/permissionGroupValidations.js.map +1 -1
- package/dist/domains/permission/group/filter/permissionGroupFilter.d.ts +2 -3
- package/dist/domains/permission/group/filter/permissionGroupFilter.js.map +1 -1
- package/dist/domains/permission/group/store/permissionGroupStore.d.ts +3 -6
- package/dist/domains/permission/group/store/permissionGroupStore.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue.d.ts +5 -3
- package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.d.ts +11 -13
- package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.js.map +1 -1
- package/dist/domains/subjectSelect/components/AFilterWrapperSubjectSelect.vue.d.ts +13 -11
- package/dist/domains/subjectSelect/components/ASubjectSelect.js.map +1 -1
- package/dist/domains/subjectSelect/components/ASubjectSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/subjectSelect/composables/useSubjectSelect.js +53 -51
- package/dist/domains/subjectSelect/composables/useSubjectSelect.js.map +1 -1
- package/dist/domains/system/appShell/components/AActionbar.vue.d.ts +7 -5
- package/dist/domains/system/appShell/components/ALayoutSwitch.js.map +1 -1
- package/dist/domains/system/appShell/components/ALayoutSwitch.vue.d.ts +7 -5
- package/dist/domains/system/appShell/components/ALayoutSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/appShell/composables/teleportSlot.d.ts +0 -1
- package/dist/domains/system/appShell/composables/teleportSlot.js.map +1 -1
- package/dist/domains/system/components/AAlerts.js.map +1 -1
- package/dist/domains/system/components/AAlerts.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/composables/alerts.js.map +1 -1
- package/dist/domains/system/composables/breadcrumbs.d.ts +3 -3
- package/dist/domains/system/composables/breadcrumbs.js.map +1 -1
- package/dist/domains/system/composables/languageSettings.js.map +1 -1
- package/dist/domains/system/composables/loginStatus.js.map +1 -1
- package/dist/domains/system/composables/navigationError.d.ts +6 -8
- package/dist/domains/system/composables/navigationError.js.map +1 -1
- package/dist/domains/system/composables/pageNavigation.d.ts +9 -10
- package/dist/domains/system/composables/pageNavigation.js.map +1 -1
- package/dist/domains/system/composables/recordActions.d.ts +14 -22
- package/dist/domains/system/composables/recordActions.js.map +1 -1
- package/dist/domains/system/composables/recordPage.d.ts +23 -38
- package/dist/domains/system/composables/recordPage.js.map +1 -1
- package/dist/domains/system/composables/routeHistory.d.ts +4 -5
- package/dist/domains/system/composables/routeHistory.js.map +1 -1
- package/dist/domains/system/composables/sentry.js.map +1 -1
- package/dist/domains/system/composables/useDebugFeatures.d.ts +3 -6
- package/dist/domains/system/composables/useDebugFeatures.js.map +1 -1
- package/dist/domains/system/store/datatablePageStore.d.ts +8 -1
- package/dist/domains/system/store/datatablePageStore.js +10 -3
- package/dist/domains/system/store/datatablePageStore.js.map +1 -1
- package/dist/domains/system/systemBar/components/ASystemBar.js.map +1 -1
- package/dist/domains/system/systemBar/components/ASystemBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/systemBar/utils/appReload.d.ts +5 -5
- package/dist/domains/system/systemBar/utils/appReload.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue.d.ts +2 -3
- package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionDeleteButton.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionDeleteButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/components/ABtnSplit.vue.d.ts +9 -7
- package/dist/domains/ui/components/AAvatarColorPicker.js.map +1 -1
- package/dist/domains/ui/components/AAvatarColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ACard.js.map +1 -1
- package/dist/domains/ui/components/ACard.vue.d.ts +7 -3
- package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ACardLoader.js.map +1 -1
- package/dist/domains/ui/components/ACardLoader.vue.d.ts +1 -0
- package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js +13 -7
- package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/AChipNoLink.vue.d.ts +5 -3
- package/dist/domains/ui/components/ACopyText.vue.d.ts +9 -7
- package/dist/domains/ui/components/ACreateDialog.js.map +1 -1
- package/dist/domains/ui/components/ACreateDialog.vue.d.ts +11 -9
- package/dist/domains/ui/components/ACreateDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ADialogToolbar.vue.d.ts +5 -3
- package/dist/domains/ui/components/ARow.vue.d.ts +5 -3
- package/dist/domains/ui/components/ATimeTrackingFields.js.map +1 -1
- package/dist/domains/ui/components/ATimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/AUserAndTimeTrackingFields.js.map +1 -1
- package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue.d.ts +3 -5
- package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/datetime/components/ADatetimePicker.js +1 -1
- package/dist/domains/ui/datetime/components/ADatetimePicker.js.map +1 -1
- package/dist/domains/ui/datetime/components/ADatetimePicker.vue.d.ts +5 -3
- package/dist/domains/ui/datetime/components/ADatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/file/components/AFileDropzone.js.map +1 -1
- package/dist/domains/ui/file/components/AFileDropzone.vue.d.ts +1 -1
- package/dist/domains/ui/file/components/AFileDropzone.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/file/components/AFileInput.js.map +1 -1
- package/dist/domains/ui/file/components/AFileInput.vue.d.ts +9 -7
- package/dist/domains/ui/file/components/AFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/file/components/AFileInputDialog.js.map +1 -1
- package/dist/domains/ui/file/components/AFileInputDialog.vue.d.ts +9 -7
- package/dist/domains/ui/file/components/AFileInputDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/file/composables/dropzone.js.map +1 -1
- package/dist/domains/ui/file/composables/formatAndSizeCheck.js.map +1 -1
- package/dist/domains/ui/view/components/AGenericView.vue.d.ts +7 -5
- package/dist/domains/ui/view/components/ALoginView.js +1 -1
- package/dist/domains/ui/view/components/ALoginView.js.map +1 -1
- package/dist/domains/ui/view/components/ALoginView.vue.d.ts +5 -3
- package/dist/domains/ui/view/components/ALoginView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/view/components/ALogoutView.js.map +1 -1
- package/dist/domains/ui/view/components/ALogoutView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/view/components/ANotFoundView.js.map +1 -1
- package/dist/domains/ui/view/components/ANotFoundView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.d.ts +6 -7
- package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.js.map +1 -1
- package/dist/lib.d.ts +2 -2
- package/dist/plugins/commonVuetifyConfig.d.ts +3 -3
- package/dist/plugins/commonVuetifyConfig.js.map +1 -1
- package/dist/plugins/i18n.d.ts +4 -5
- package/dist/plugins/i18n.js.map +1 -1
- package/dist/plugins/pluginOptions.d.ts +4 -2
- package/dist/plugins/pluginOptions.js.map +1 -1
- package/dist/plugins/webfontloader.js.map +1 -1
- package/dist/shared/error/AnzuApiCancelledError.d.ts +5 -8
- package/dist/shared/error/AnzuApiCancelledError.js.map +1 -1
- package/dist/shared/error/AnzuError.d.ts +3 -5
- package/dist/shared/error/AnzuError.js.map +1 -1
- package/dist/shared/error/AuthUnavailableError.d.ts +3 -3
- package/dist/shared/error/AuthUnavailableError.js.map +1 -1
- package/dist/shared/error/isInCauseChain.d.ts +2 -2
- package/dist/shared/error/isInCauseChain.js.map +1 -1
- package/dist/shared/types/UserAndTimeTracking.d.ts +5 -5
- package/dist/shared/types/Validation.d.ts +4 -5
- package/dist/shared/types/common.d.ts +1 -3
- package/dist/shared/types/globalComponents.d.ts +5 -6
- package/dist/shared/utils/common.js.map +1 -1
- package/dist/shared/utils/datetime.d.ts +0 -1
- package/dist/shared/utils/datetime.js.map +1 -1
- package/dist/shared/utils/datetimePickerValue.d.ts +4 -7
- package/dist/shared/utils/datetimePickerValue.js.map +1 -1
- package/dist/shared/utils/development.d.ts +3 -3
- package/dist/shared/utils/development.js.map +1 -1
- package/dist/shared/utils/envConfig.d.ts +4 -4
- package/dist/shared/utils/envConfig.js.map +1 -1
- package/dist/shared/utils/json.d.ts +1 -1
- package/dist/shared/utils/json.js.map +1 -1
- package/dist/shared/utils/userAndTimeTracking.d.ts +5 -7
- package/dist/shared/utils/userAndTimeTracking.js.map +1 -1
- package/dist/shared/validators/vuelidate/common/useValidateHexColor.d.ts +3 -5
- package/dist/shared/validators/vuelidate/common/useValidateHexColor.js.map +1 -1
- package/dist/testing/appShell.d.ts +11 -11
- package/dist/testing/appShell.js.map +1 -1
- package/dist/testing/closeButtons.d.ts +9 -11
- package/dist/testing/closeButtons.js.map +1 -1
- package/dist/testing/declaredDependencies.d.ts +7 -7
- package/dist/testing/declaredDependencies.js.map +1 -1
- package/dist/testing/generatedRoutes.d.ts +6 -11
- package/dist/testing/generatedRoutes.js.map +1 -1
- package/dist/testing/routeHistory.d.ts +5 -12
- package/dist/testing/routeHistory.js.map +1 -1
- package/dist/testing/sortableLists.d.ts +16 -21
- package/dist/testing/sortableLists.js.map +1 -1
- package/dist/testing/typedRouter.d.ts +0 -1
- package/dist/testing/typedRouter.js.map +1 -1
- package/package.json +27 -27
- package/src/eslint/adminConfig.mjs +19 -27
- package/src/eslint/globalComponentNames.mjs +3 -4
- package/src/eslint/oxlint.mjs +7 -20
- package/src/eslint/plugin.d.mts +2 -4
- package/src/eslint/plugin.mjs +18 -34
- package/src/eslint/validRouteName.mjs +6 -7
- package/src/vite/devWatch.mjs +30 -43
- package/src/vite/index.d.mts +5 -5
- package/src/vite/sentry.mjs +7 -12
- package/src/vite/sourcemaps.mjs +4 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageNavigation.js","names":["states","appRouter","trackNavigation","router","state","removeBeforeEach","removeAfterEach","isNavigationFailure","failure","NavigationFailureType","to","from","removeOnError","isNavigationPending","isAppNavigationPending","pageIdOf","usePageNavigation","useRouter","pageId","onPage","navigate","replace"],"sources":["../../../../src/domains/system/composables/pageNavigation.ts"],"sourcesContent":["import { isNavigationFailure, NavigationFailureType, type RouteLocationRaw, type Router, useRouter } from 'vue-router'\n\ninterface NavigationState {\n pending: boolean\n pageId: number\n}\n\nconst states = new WeakMap<Router, NavigationState>()\nlet appRouter: Router | undefined\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"pageNavigation.js","names":["states","appRouter","trackNavigation","router","state","removeBeforeEach","removeAfterEach","isNavigationFailure","failure","NavigationFailureType","to","from","removeOnError","isNavigationPending","isAppNavigationPending","pageIdOf","usePageNavigation","useRouter","pageId","onPage","navigate","replace"],"sources":["../../../../src/domains/system/composables/pageNavigation.ts"],"sourcesContent":["import { isNavigationFailure, NavigationFailureType, type RouteLocationRaw, type Router, useRouter } from 'vue-router'\n\ninterface NavigationState {\n pending: boolean\n pageId: number\n}\n\nconst states = new WeakMap<Router, NavigationState>()\nlet appRouter: Router | undefined\n\n/**\n * Tracks the user's navigation on `router`: whether one is pending, and which page is shown.\n * Register it as the router's first guard. A page that acts after an async step\n * (load, save, socket event) checks `onPage()` first via `usePageNavigation`.\n * While the user navigates or after leaving, it does nothing. A redirect would\n * cancel the user's navigation, and a message would stay on the next page.\n * Returns the unregistration, for tests that create a router each.\n */\nexport function trackNavigation(router: Router): () => void {\n appRouter = router\n if (states.has(router)) return () => undefined\n const state: NavigationState = { pending: false, pageId: 0 }\n states.set(router, state)\n const removeBeforeEach = router.beforeEach(() => {\n state.pending = true\n })\n const removeAfterEach = router.afterEach((to, from, failure) => {\n // A newer navigation replaced this one and is still pending. It clears the flag itself.\n if (isNavigationFailure(failure, NavigationFailureType.cancelled)) return\n state.pending = false\n // The admins key their RouterView by the path: another path is another page.\n if (!failure && to.path !== from.path) state.pageId += 1\n })\n const removeOnError = router.onError(() => {\n state.pending = false\n })\n return () => {\n removeBeforeEach()\n removeAfterEach()\n removeOnError()\n states.delete(router)\n if (appRouter === router) appRouter = undefined\n }\n}\n\nexport const isNavigationPending = (router: Router): boolean => states.get(router)?.pending === true\n\n/** Whether the app's router has a navigation of the user's on its way. */\nexport const isAppNavigationPending = (): boolean => appRouter !== undefined && isNavigationPending(appRouter)\n\nconst pageIdOf = (router: Router) => states.get(router)?.pageId ?? 0\n\nexport interface UsePageNavigationReturn {\n /** The user is still on this page and not navigating away from it. */\n onPage: () => boolean\n /** Navigates only `onPage()`. Resolves whether it got there. */\n push: (to: RouteLocationRaw) => Promise<boolean>\n replace: (to: RouteLocationRaw) => Promise<boolean>\n}\n\n/**\n * For a page, or a composable in its setup, that navigates after\n * an async step, such as a redirect after save, create or delete.\n * The page is the one shown at setup. A later visit to the same path (A, B, A again) is another page.\n * A composable that receives its router passes it on.\n */\nexport function usePageNavigation(router: Router | undefined = useRouter()): UsePageNavigationReturn {\n // Without a router (a composable mounted alone in a test) there is nothing to track or navigate.\n if (!router) return { onPage: () => true, push: async () => false, replace: async () => false }\n // Registers late if the admin did not register it. It then misses only the guards that run before it.\n trackNavigation(router)\n const pageId = pageIdOf(router)\n\n const onPage = () => !isNavigationPending(router) && pageIdOf(router) === pageId\n\n // Not async, so a location the router cannot resolve still throws inside the caller's try/catch.\n const navigate = (to: RouteLocationRaw, replace: boolean): Promise<boolean> => {\n if (!onPage()) return Promise.resolve(false)\n return (replace ? router.replace(to) : router.push(to)).then((failure) => !failure)\n }\n\n return {\n onPage,\n push: (to) => navigate(to, false),\n replace: (to) => navigate(to, true),\n }\n}\n"],"mappings":";;AAOA,IAAMA,oBAAS,IAAI,QAAiC,GAChDC;AAUJ,SAAgBC,EAAgB,GAA4B;CAE1D,IADA,IAAYC,GACRH,EAAO,IAAIG,CAAM,GAAG,aAAa,KAAA;CACrC,IAAMC,IAAyB;EAAE,SAAS;EAAO,QAAQ;CAAE;CAC3D,EAAO,IAAID,GAAQC,CAAK;CACxB,IAAMC,IAAmBF,EAAO,iBAAiB;EAC/C,EAAM,UAAU;CAClB,CAAC,GACKG,IAAkBH,EAAO,WAAW,GAAI,GAAM,MAAY;EAE9D,AAAII,EAAoBC,GAASC,EAAsB,SAAS,MAChE,EAAM,UAAU,IAEZ,CAACD,KAAWE,EAAG,SAASC,EAAK,SAAM,EAAM,UAAU;CACzD,CAAC,GACKC,IAAgBT,EAAO,cAAc;EACzC,EAAM,UAAU;CAClB,CAAC;CACD,aAAa;EAKX,AAJAE,EAAiB,GACjBC,EAAgB,GAChBM,EAAc,GACdZ,EAAO,OAAOG,CAAM,GAChBF,MAAcE,MAAQ,IAAY,KAAA;CACxC;AACF;AAEA,IAAaU,KAAuB,MAA4Bb,EAAO,IAAIG,CAAM,CAAC,EAAE,YAAY,IAGnFW,UAAwCb,MAAc,KAAA,KAAaY,EAAoBZ,CAAS,GAEvGc,KAAY,MAAmBf,EAAO,IAAIG,CAAM,CAAC,EAAE,UAAU;AAgBnE,SAAgBa,EAAkB,IAA6BC,EAAU,GAA4B;CAEnG,IAAI,CAACd,GAAQ,OAAO;EAAE,cAAc;EAAM,MAAM,YAAY;EAAO,SAAS,YAAY;CAAM;CAE9F,EAAgBA,CAAM;CACtB,IAAMe,IAASH,EAASZ,CAAM,GAExBgB,UAAe,CAACN,EAAoBV,CAAM,KAAKY,EAASZ,CAAM,MAAMe,GAGpEE,KAAY,GAAsB,MACjCD,EAAO,KACJE,IAAUlB,EAAO,QAAQO,CAAE,IAAIP,EAAO,KAAKO,CAAE,EAAA,CAAG,MAAM,MAAY,CAACF,CAAO,IAD5D,QAAQ,QAAQ,EAAK;CAI7C,OAAO;EACL;EACA,OAAO,MAAOY,EAASV,GAAI,EAAK;EAChC,UAAU,MAAOU,EAASV,GAAI,EAAI;CACpC;AACF"}
|
|
@@ -1,39 +1,31 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* extra loaded/ready flag or a flag kept in a store stays hand-written.
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
3
|
+
* Get-one loader for a detail or edit page, in the shape `useRecordPage`
|
|
4
|
+
* reads. Raises `loading` and runs `load` with the page's signal.
|
|
5
|
+
* Returns `true` once loaded, else the result of `handleRecordLoadError`: `false`
|
|
6
|
+
* leaves the page, `undefined` means aborted or session expired (page stays).
|
|
7
|
+
* `loading` is lowered unless the load was aborted, because the flag then belongs to the next page.
|
|
8
|
+
* A bare `return` in `load` means loaded, and anything thrown counts as a load failure.
|
|
9
|
+
* Use it only for the record's single request; anything more stays hand-written.
|
|
10
|
+
* @example
|
|
14
11
|
* const fetchData = defineRecordLoader(detailLoading, async (id: IntegerId, signal) => {
|
|
15
12
|
* faq.value = await fetchFaq({ urlParams: { id }, signal })
|
|
16
13
|
* })
|
|
17
|
-
* ```
|
|
18
14
|
*/
|
|
19
15
|
export declare const defineRecordLoader: <Id>(loading: Ref<boolean>, load: (id: Id, signal: AbortSignal | undefined) => Promise<void>) => (id: Id, options?: {
|
|
20
16
|
signal?: AbortSignal;
|
|
21
17
|
}) => Promise<boolean | undefined>;
|
|
22
18
|
/**
|
|
23
|
-
*
|
|
24
|
-
* invalid, runs `save`, shows
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* request stays hand-written.
|
|
30
|
-
*
|
|
31
|
-
* ```ts
|
|
19
|
+
* Save of a create or edit form. Raises `loading`, touches `v$` and calls `showValidationError`
|
|
20
|
+
* if invalid, runs `save`, shows errors with `showErrorsDefault`, lowers `loading`.
|
|
21
|
+
* The success alert and what follows it stay in `save`.
|
|
22
|
+
* `loading` and `v$` are captured at definition, so both must exist then. Extra validators,
|
|
23
|
+
* flags, error handling, `finally` work, return values or requests stay hand-written.
|
|
24
|
+
* @example
|
|
32
25
|
* const onUpdate = defineRecordSave(saveButtonLoading, v$, async () => {
|
|
33
26
|
* faq.value = await updateFaq({ urlParams: { id: faq.value.id }, body: faq.value })
|
|
34
27
|
* showRecordWas('updated')
|
|
35
28
|
* })
|
|
36
|
-
* ```
|
|
37
29
|
*/
|
|
38
30
|
export declare const defineRecordSave: <Args extends unknown[]>(loading: Ref<boolean>, v$: Ref<{
|
|
39
31
|
$touch: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordActions.js","names":["defineRecordLoader","load","id","options","error","defineRecordSave","useAlerts","args","v$","save"],"sources":["../../../../src/domains/system/composables/recordActions.ts"],"sourcesContent":["import type { Ref } from 'vue'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport { handleRecordLoadError } from '@/domains/system/composables/recordPage'\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"recordActions.js","names":["defineRecordLoader","load","id","options","error","defineRecordSave","useAlerts","args","v$","save"],"sources":["../../../../src/domains/system/composables/recordActions.ts"],"sourcesContent":["import type { Ref } from 'vue'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport { handleRecordLoadError } from '@/domains/system/composables/recordPage'\n\n/**\n * Get-one loader for a detail or edit page, in the shape `useRecordPage`\n * reads. Raises `loading` and runs `load` with the page's signal.\n * Returns `true` once loaded, else the result of `handleRecordLoadError`: `false`\n * leaves the page, `undefined` means aborted or session expired (page stays).\n * `loading` is lowered unless the load was aborted, because the flag then belongs to the next page.\n * A bare `return` in `load` means loaded, and anything thrown counts as a load failure.\n * Use it only for the record's single request; anything more stays hand-written.\n * @example\n * const fetchData = defineRecordLoader(detailLoading, async (id: IntegerId, signal) => {\n * faq.value = await fetchFaq({ urlParams: { id }, signal })\n * })\n */\nexport const defineRecordLoader =\n <Id>(loading: Ref<boolean>, load: (id: Id, signal: AbortSignal | undefined) => Promise<void>) =>\n async (id: Id, options: { signal?: AbortSignal } = {}): Promise<boolean | undefined> => {\n loading.value = true\n try {\n await load(id, options.signal)\n return true\n } catch (error) {\n return handleRecordLoadError(error) ? false : undefined\n } finally {\n if (!options.signal?.aborted) loading.value = false\n }\n }\n\n/**\n * Save of a create or edit form. Raises `loading`, touches `v$` and calls `showValidationError`\n * if invalid, runs `save`, shows errors with `showErrorsDefault`, lowers `loading`.\n * The success alert and what follows it stay in `save`.\n * `loading` and `v$` are captured at definition, so both must exist then. Extra validators,\n * flags, error handling, `finally` work, return values or requests stay hand-written.\n * @example\n * const onUpdate = defineRecordSave(saveButtonLoading, v$, async () => {\n * faq.value = await updateFaq({ urlParams: { id: faq.value.id }, body: faq.value })\n * showRecordWas('updated')\n * })\n */\nexport const defineRecordSave = <Args extends unknown[]>(\n loading: Ref<boolean>,\n v$: Ref<{ $touch: () => void; $invalid: boolean }>,\n save: (...args: Args) => Promise<void>\n) => {\n const { showValidationError, showErrorsDefault } = useAlerts()\n return async (...args: Args): Promise<void> => {\n loading.value = true\n try {\n v$.value.$touch()\n if (v$.value.$invalid) {\n showValidationError()\n return\n }\n await save(...args)\n } catch (error) {\n showErrorsDefault(error)\n } finally {\n loading.value = false\n }\n }\n}\n"],"mappings":";;;AAiBA,IAAaA,KACN,GAAuB,MAC5B,OAAO,GAAQ,IAAoC,CAAC,MAAoC;CACtF,EAAQ,QAAQ;CAChB,IAAI;EAEF,OADA,MAAMC,EAAKC,GAAIC,EAAQ,MAAM,GACtB;CACT,SAASC,GAAO;EACd,OAAO,GAAsBA,CAAK,KAAY,KAAA;CAChD,UAAU;EACR,AAAKD,EAAQ,QAAQ,YAAS,EAAQ,QAAQ;CAChD;AACF,GAcWE,KACX,GACA,GACA,MACG;CACH,IAAM,EAAE,wBAAqB,yBAAsBC,EAAU;CAC7D,OAAO,OAAO,GAAGC,MAA8B;EAC7C,EAAQ,QAAQ;EAChB,IAAI;GAEF,IADAC,EAAG,MAAM,OAAO,GACZA,EAAG,MAAM,UAAU;IACrB,EAAoB;IACpB;GACF;GACA,MAAMC,EAAK,GAAGF,CAAI;EACpB,SAASH,GAAO;GACd,EAAkBA,CAAK;EACzB,UAAU;GACR,EAAQ,QAAQ;EAClB;CACF;AACF"}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
2
|
import { RouteRecordName } from 'vue-router';
|
|
3
3
|
/**
|
|
4
|
-
* Shows why a record
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* shows the message `showErrorsDefault` has for it and leaves too: the page would only show an
|
|
11
|
-
* empty record with live buttons. While the user is navigating to another page (`trackNavigation`)
|
|
12
|
-
* it shows nothing, the message would stay there; the page's `leave` then stays put as well.
|
|
4
|
+
* Shows why a record failed to load and returns whether its page should leave.
|
|
5
|
+
* Only for the record's own get-one: a 404 or 403 there means the record is unavailable, unlike for secondary requests.
|
|
6
|
+
* An aborted request or an expired session shows nothing and does not leave. Other errors show the
|
|
7
|
+
* `showErrorsDefault` message and leave, since the page would show an empty record with live buttons.
|
|
8
|
+
* While the user navigates elsewhere (`trackNavigation`) it shows nothing
|
|
9
|
+
* and does not leave, because the message would stay on the next page.
|
|
13
10
|
*/
|
|
14
11
|
export declare const handleRecordLoadError: (error: unknown, duration?: number) => boolean;
|
|
15
12
|
export interface UseRecordPageOptions {
|
|
@@ -17,21 +14,21 @@ export interface UseRecordPageOptions {
|
|
|
17
14
|
fallbackRouteName?: RouteRecordName;
|
|
18
15
|
fallbackRouteParams?: Record<string, any>;
|
|
19
16
|
/**
|
|
20
|
-
*
|
|
21
|
-
* with the record's params is skipped as that record's address
|
|
17
|
+
* Same as the page's Close button: the record's sibling views and the create form.
|
|
18
|
+
* A route with the record's params is skipped only as that record's address, see `leave`.
|
|
22
19
|
*/
|
|
23
20
|
skipRouteNames?: RouteRecordName[];
|
|
24
21
|
/**
|
|
25
|
-
* The page's loading flag. `leave`
|
|
26
|
-
* page lowers it
|
|
27
|
-
* next one
|
|
22
|
+
* The page's loading flag. `leave` keeps it up so the empty record's buttons never show.
|
|
23
|
+
* The page lowers it on unmount. The flag is often shared by all views of
|
|
24
|
+
* the entity, and the next one (e.g. a create form) must not inherit it.
|
|
28
25
|
*/
|
|
29
26
|
loading?: Ref<boolean>;
|
|
30
27
|
/**
|
|
31
|
-
* The record's load, run on mount with the page's signal
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
28
|
+
* The record's load, run on mount with the page's signal. `false` leaves the page, `true` and `undefined` keep it.
|
|
29
|
+
* A load also called later is fine: `load: () => getData()`.
|
|
30
|
+
* Omit it and write `onMounted` by hand when the page acts on
|
|
31
|
+
* the result, loads in setup or makes more requests on mount.
|
|
35
32
|
*/
|
|
36
33
|
load?: (signal: AbortSignal) => Promise<boolean | undefined>;
|
|
37
34
|
}
|
|
@@ -44,25 +41,13 @@ export interface UseRecordPageReturn {
|
|
|
44
41
|
onPage: () => boolean;
|
|
45
42
|
}
|
|
46
43
|
/**
|
|
47
|
-
* For a detail or edit page: aborts the record's load when the page goes, and leaves the page when
|
|
48
|
-
* the load
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* load: (signal) => fetchData(id, { signal }),
|
|
56
|
-
* })
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* `false` from the loader means "leave"; `undefined` is a load that was superseded or stopped on
|
|
60
|
-
* purpose, after which the page stays. A page that does more with the load writes its own `onMounted`
|
|
61
|
-
* with the returned `signal` and `leave`, see `load`.
|
|
62
|
-
*
|
|
63
|
-
* While the user is navigating to another page (an async guard, a lazy chunk; `trackNavigation`),
|
|
64
|
-
* the page does not leave: the user's navigation decides, and should it fail, the page stays with
|
|
65
|
-
* its loading flag up. Not handled: a guard that refuses the step back can leave the address bar out
|
|
66
|
-
* of step with the router.
|
|
44
|
+
* For a detail or edit page: aborts the record's load when the page goes, and leaves the page when the load fails.
|
|
45
|
+
* `false` from the loader means leave. `undefined` is a superseded or aborted load, and the page stays.
|
|
46
|
+
* While the user navigates elsewhere (`trackNavigation`), the page does not
|
|
47
|
+
* leave. If that navigation fails, the page stays with its loading flag up.
|
|
48
|
+
* Not handled: a guard that refuses the step back can leave the address bar out of sync with the router.
|
|
49
|
+
* @example
|
|
50
|
+
* useRecordPage({ fallbackRouteName: '/x', skipRouteNames: [...],
|
|
51
|
+
* loading: detailLoading, load: (signal) => fetchData(id, { signal }) })
|
|
67
52
|
*/
|
|
68
53
|
export declare function useRecordPage(options?: UseRecordPageOptions): UseRecordPageReturn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordPage.js","names":["handleRecordLoadError","isAnzuApiCancelledError","error","isInCauseChain","cause","SessionExpiredError","isAppNavigationPending","useAlerts","status","apiErrorStatus","isAnzuApiForbiddenError","showErrorT","duration","showErrorsDefault","showUnknownError","pathOf","fullPath","withoutHash","PATH_PARAM","paramsOf","record","router","route","name","match","waitForLanding","done","stopAfterEach","stopError","resolve","landed","failure","settled","navigation","useRecordPage","useRouter","useRouteHistory","useDatatablePageStore","usePageNavigation","path","controller","unmounted","options","stillHere","skipped","current","paths","names","declared","optional","key","params","findTarget","i","history","entry","isLeftAfterFailureRecently","go","target","to","back","landing","preservePageForLanding","leave","onPage","load","onMounted"],"sources":["../../../../src/domains/system/composables/recordPage.ts"],"sourcesContent":["import { onBeforeUnmount, onMounted, type Ref } from 'vue'\nimport { type NavigationFailure, type RouteLocationRaw, type RouteRecordName, type Router, useRouter } from 'vue-router'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport {\n forgetLeftAfterFailure,\n isLeftAfterFailureRecently,\n markLeftAfterFailure,\n useRouteHistory,\n} from '@/domains/system/composables/routeHistory'\nimport { useDatatablePageStore } from '@/domains/system/store/datatablePageStore'\nimport { isAppNavigationPending, usePageNavigation } from '@/domains/system/composables/pageNavigation'\nimport { apiErrorStatus } from '@/domains/api/utils/apiErrors'\nimport { isAnzuApiCancelledError } from '@/shared/error/AnzuApiCancelledError'\nimport { isAnzuApiForbiddenError } from '@/shared/error/AnzuApiForbiddenError'\nimport { SessionExpiredError } from '@/shared/error/SessionExpiredError'\nimport { isInCauseChain } from '@/shared/error/isInCauseChain'\nimport { HTTP_STATUS_FORBIDDEN, HTTP_STATUS_NOT_FOUND } from '@/shared/statusCodes'\n\n/**\n * Shows why a record could not be loaded and says whether its page should leave.\n *\n * For the record's own get-one, not for what a page loads around it: a 404 or 403 there means the\n * record is not there for this user, a 404 of a secondary request does not. A request that was\n * stopped (the page is gone) and a session found expired (the logout is already loading) show\n * nothing and do not leave. Everything else -- a 5xx, the network, a timeout, the sign-in server --\n * shows the message `showErrorsDefault` has for it and leaves too: the page would only show an\n * empty record with live buttons. While the user is navigating to another page (`trackNavigation`)\n * it shows nothing, the message would stay there; the page's `leave` then stays put as well.\n */\nexport const handleRecordLoadError = (error: unknown, duration = -1): boolean => {\n if (isAnzuApiCancelledError(error)) return false\n if (isInCauseChain(error, (cause) => cause instanceof SessionExpiredError)) return false\n if (isAppNavigationPending()) return true\n\n const { showErrorT, showErrorsDefault, showUnknownError } = useAlerts()\n const status = apiErrorStatus(error)\n // A rejected 403 is `AnzuApiForbiddenError`, which carries no status; one let through by\n // `validateStatus` is a response code error that does.\n if (isAnzuApiForbiddenError(error) || status === HTTP_STATUS_FORBIDDEN) {\n showErrorT('common.alert.recordForbidden', duration)\n return true\n }\n if (status === HTTP_STATUS_NOT_FOUND) {\n showErrorT('common.alert.recordNotFound', duration)\n return true\n }\n if (!showErrorsDefault(error, duration)) showUnknownError(duration)\n return true\n}\n\nexport interface UseRecordPageOptions {\n /** Where to go when nothing in the history is a destination: the entity's list. */\n fallbackRouteName?: RouteRecordName\n fallbackRouteParams?: Record<string, any>\n /**\n * What the page gives its Close button: the record's sibling views and the create form. A route\n * with the record's params is skipped as that record's address only, see `leave`.\n */\n skipRouteNames?: RouteRecordName[]\n /**\n * The page's loading flag. `leave` holds it up, so the empty record's buttons never show, and the\n * page lowers it as it unmounts: the flag is often shared by every view of the entity, and the\n * next one -- a create form that loads nothing -- must not inherit it.\n */\n loading?: Ref<boolean>\n /**\n * The record's load, run on mount with the page's signal; `false` from it leaves the page (`leave`), `true` and\n * `undefined` keep it. A load the page also calls later (a refresh after a save) is fine:\n * `load: () => getData()`. Leave it out, and write the `onMounted` by hand, when the page acts on the result\n * otherwise, loads in setup or makes more requests on mount.\n */\n load?: (signal: AbortSignal) => Promise<boolean | undefined>\n}\n\nexport interface UseRecordPageReturn {\n /** For the record's get-one: stopped when the page unmounts. */\n signal: AbortSignal\n /** Back to where the user came from, else to the fallback. Resolves whether it got there. */\n leave: () => Promise<boolean>\n /** The user is still on this page and not navigating away: for a redirect after the load. */\n onPage: () => boolean\n}\n\nconst pathOf = (fullPath: string) => fullPath.split(/[?#]/, 1)[0] ?? fullPath\nconst withoutHash = (fullPath: string) => fullPath.split('#', 1)[0] ?? fullPath\n\n// A param's name, its custom regex (whose `)` may be escaped) and its modifier: `?` and `*` make it optional.\nconst PATH_PARAM = /:(\\w+)(?:\\((?:\\\\.|[^\\\\)])*\\))?([?*+])?/g\n\nconst paramsOf = (router: Router, name: RouteRecordName) => {\n const record = router.getRoutes().find((route) => route.name === name)\n if (!record) return undefined\n return [...record.path.matchAll(PATH_PARAM)].map((match) => ({\n key: match[1]!,\n optional: match[2] === '?' || match[2] === '*',\n }))\n}\n\n// `router.back()` answers nothing; its landing, or its error, is the answer.\nconst waitForLanding = (router: Router) =>\n new Promise<boolean>((resolve) => {\n const done = (landed: boolean) => {\n stopAfterEach()\n stopError()\n resolve(landed)\n }\n const stopAfterEach = router.afterEach((_to, _from, failure) => done(!failure))\n const stopError = router.onError(() => done(false))\n })\n\nconst settled = (navigation: Promise<NavigationFailure | void | undefined>) =>\n navigation.then(\n (failure) => !failure,\n () => false\n )\n\n/**\n * For a detail or edit page: aborts the record's load when the page goes, and leaves the page when\n * the load fails.\n *\n * ```ts\n * useRecordPage({\n * fallbackRouteName: '/x',\n * skipRouteNames: [...],\n * loading: detailLoading,\n * load: (signal) => fetchData(id, { signal }),\n * })\n * ```\n *\n * `false` from the loader means \"leave\"; `undefined` is a load that was superseded or stopped on\n * purpose, after which the page stays. A page that does more with the load writes its own `onMounted`\n * with the returned `signal` and `leave`, see `load`.\n *\n * While the user is navigating to another page (an async guard, a lazy chunk; `trackNavigation`),\n * the page does not leave: the user's navigation decides, and should it fail, the page stays with\n * its loading flag up. Not handled: a guard that refuses the step back can leave the address bar out\n * of step with the router.\n */\nexport function useRecordPage(options: UseRecordPageOptions = {}): UseRecordPageReturn {\n const router = useRouter()\n const { history } = useRouteHistory()\n const { preservePageForLanding } = useDatatablePageStore()\n const { onPage } = usePageNavigation()\n\n // The path, not the name: /x/1 and /x/2 share a name, and a late failure of the one must not move\n // the user off the other.\n const path = router.currentRoute.value.path\n // On it again: a failure there before no longer counts.\n forgetLeftAfterFailure(path)\n const controller = new AbortController()\n let unmounted = false\n onBeforeUnmount(() => {\n unmounted = true\n controller.abort()\n // Raised by `leave`, or left up by the load just aborted, whose `finally` no longer owns it. The\n // next page mounts after this one is gone and raises it again for its own load.\n if (options.loading) options.loading.value = false\n })\n\n const stillHere = () => !unmounted && router.currentRoute.value.path === path\n\n // Unlike the Close button, which skips every entry with the record's route name so that closing\n // one row never opens another, this goes back to the view the user actually came from -- another\n // record of the same entity included. Only the addresses of THIS record are skipped, compared\n // without query and hash (a tab in the query is the same view), plus the create form the record\n // may have been saved from: back there, Save would create a second record.\n const skipped = () => {\n const current = router.currentRoute.value\n const paths = new Set<string>([pathOf(current.fullPath)])\n const names = new Set<RouteRecordName>()\n for (const name of options.skipRouteNames ?? []) {\n const declared = paramsOf(router, name)\n if (!declared) continue\n // A route without params is one address; one the record cannot fill is skipped by name.\n if (declared.length === 0 || declared.some(({ key, optional }) => !optional && !(key in current.params))) {\n names.add(name)\n continue\n }\n const params = Object.fromEntries(\n declared.filter(({ key }) => key in current.params).map(({ key }) => [key, current.params[key]])\n )\n try {\n paths.add(pathOf(router.resolve({ name, params }).fullPath))\n } catch {\n names.add(name)\n }\n }\n return { paths, names }\n }\n\n const findTarget = (): string | undefined => {\n const { paths, names } = skipped()\n for (let i = history.value.length - 1; i >= 0; i--) {\n const entry = history.value[i]!\n // An address a page just left after a failure is no destination either: two failing records\n // next to each other in the history -- A, then B, while the backend is down -- would send the\n // user back and forth for as long as the outage lasts, B leaving to A, which finds B as its\n // newest entry. Skipped, the chain ends at the list.\n if (paths.has(pathOf(entry.fullPath)) || isLeftAfterFailureRecently(pathOf(entry.fullPath))) continue\n if (entry.name !== undefined && entry.name !== null && names.has(entry.name as RouteRecordName)) continue\n return entry.fullPath\n }\n return undefined\n }\n\n // Leaves no trace of the failed address: a step back when the target is the entry right before\n // it, a replace otherwise -- a push would let the browser's Back return to the page that just\n // failed, which would fail and leave again.\n const go = async (to: RouteLocationRaw): Promise<boolean> => {\n let target: string\n try {\n target = router.resolve(to).fullPath\n } catch {\n return false\n }\n // Without the hash: a list's filter writes it under the router, so the record's `state.back`\n // names the list without it, while the route history has it. The filter also keeps the list\n // entry's `current` in step, so the step back lands on the filter, and adds no entry.\n const back = router.options.history.state.back\n if (typeof back === 'string' && withoutHash(back) === withoutHash(target)) {\n const landing = waitForLanding(router)\n preservePageForLanding(router)\n router.back()\n return landing\n }\n const navigation = router.replace(to)\n preservePageForLanding(router, { to, navigation })\n return settled(navigation)\n }\n\n const leave = async (): Promise<boolean> => {\n if (!stillHere()) return false\n // Held up for good on a leave that fails: the record is not loaded, and its buttons -- Save\n // creating a new record, Delete with the address's id -- must not come back. The Close button,\n // which no page ties to loading, is the way out then.\n if (options.loading) options.loading.value = true\n // The user is on the way to another page: that navigation decides, ours would cancel it.\n if (!onPage()) return false\n markLeftAfterFailure(path)\n const target = findTarget()\n if (target !== undefined && (await go(target))) return true\n if (!stillHere() || !onPage() || options.fallbackRouteName === undefined) return false\n return go({ name: options.fallbackRouteName, params: options.fallbackRouteParams })\n }\n\n const { load } = options\n if (load) {\n onMounted(async () => {\n if ((await load(controller.signal)) === false) await leave()\n })\n }\n\n return { signal: controller.signal, leave, onPage }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"recordPage.js","names":["handleRecordLoadError","isAnzuApiCancelledError","error","isInCauseChain","cause","SessionExpiredError","isAppNavigationPending","useAlerts","status","apiErrorStatus","isAnzuApiForbiddenError","showErrorT","duration","showErrorsDefault","showUnknownError","pathOf","fullPath","withoutHash","PATH_PARAM","paramsOf","record","router","route","name","match","waitForLanding","done","stopAfterEach","stopError","resolve","landed","failure","settled","navigation","useRecordPage","useRouter","useRouteHistory","useDatatablePageStore","usePageNavigation","path","controller","unmounted","options","stillHere","skipped","current","paths","names","declared","optional","key","params","findTarget","i","history","entry","isLeftAfterFailureRecently","go","target","to","back","landing","preservePageForLanding","leave","onPage","load","onMounted"],"sources":["../../../../src/domains/system/composables/recordPage.ts"],"sourcesContent":["import { onBeforeUnmount, onMounted, type Ref } from 'vue'\nimport { type NavigationFailure, type RouteLocationRaw, type RouteRecordName, type Router, useRouter } from 'vue-router'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport {\n forgetLeftAfterFailure,\n isLeftAfterFailureRecently,\n markLeftAfterFailure,\n useRouteHistory,\n} from '@/domains/system/composables/routeHistory'\nimport { useDatatablePageStore } from '@/domains/system/store/datatablePageStore'\nimport { isAppNavigationPending, usePageNavigation } from '@/domains/system/composables/pageNavigation'\nimport { apiErrorStatus } from '@/domains/api/utils/apiErrors'\nimport { isAnzuApiCancelledError } from '@/shared/error/AnzuApiCancelledError'\nimport { isAnzuApiForbiddenError } from '@/shared/error/AnzuApiForbiddenError'\nimport { SessionExpiredError } from '@/shared/error/SessionExpiredError'\nimport { isInCauseChain } from '@/shared/error/isInCauseChain'\nimport { HTTP_STATUS_FORBIDDEN, HTTP_STATUS_NOT_FOUND } from '@/shared/statusCodes'\n\n/**\n * Shows why a record failed to load and returns whether its page should leave.\n * Only for the record's own get-one: a 404 or 403 there means the record is unavailable, unlike for secondary requests.\n * An aborted request or an expired session shows nothing and does not leave. Other errors show the\n * `showErrorsDefault` message and leave, since the page would show an empty record with live buttons.\n * While the user navigates elsewhere (`trackNavigation`) it shows nothing\n * and does not leave, because the message would stay on the next page.\n */\nexport const handleRecordLoadError = (error: unknown, duration = -1): boolean => {\n if (isAnzuApiCancelledError(error)) return false\n if (isInCauseChain(error, (cause) => cause instanceof SessionExpiredError)) return false\n if (isAppNavigationPending()) return true\n\n const { showErrorT, showErrorsDefault, showUnknownError } = useAlerts()\n const status = apiErrorStatus(error)\n // A rejected 403 is `AnzuApiForbiddenError`, which carries no status; one let through by\n // `validateStatus` is a response code error that does.\n if (isAnzuApiForbiddenError(error) || status === HTTP_STATUS_FORBIDDEN) {\n showErrorT('common.alert.recordForbidden', duration)\n return true\n }\n if (status === HTTP_STATUS_NOT_FOUND) {\n showErrorT('common.alert.recordNotFound', duration)\n return true\n }\n if (!showErrorsDefault(error, duration)) showUnknownError(duration)\n return true\n}\n\nexport interface UseRecordPageOptions {\n /** Where to go when nothing in the history is a destination: the entity's list. */\n fallbackRouteName?: RouteRecordName\n fallbackRouteParams?: Record<string, any>\n /**\n * Same as the page's Close button: the record's sibling views and the create form.\n * A route with the record's params is skipped only as that record's address, see `leave`.\n */\n skipRouteNames?: RouteRecordName[]\n /**\n * The page's loading flag. `leave` keeps it up so the empty record's buttons never show.\n * The page lowers it on unmount. The flag is often shared by all views of\n * the entity, and the next one (e.g. a create form) must not inherit it.\n */\n loading?: Ref<boolean>\n /**\n * The record's load, run on mount with the page's signal. `false` leaves the page, `true` and `undefined` keep it.\n * A load also called later is fine: `load: () => getData()`.\n * Omit it and write `onMounted` by hand when the page acts on\n * the result, loads in setup or makes more requests on mount.\n */\n load?: (signal: AbortSignal) => Promise<boolean | undefined>\n}\n\nexport interface UseRecordPageReturn {\n /** For the record's get-one: stopped when the page unmounts. */\n signal: AbortSignal\n /** Back to where the user came from, else to the fallback. Resolves whether it got there. */\n leave: () => Promise<boolean>\n /** The user is still on this page and not navigating away: for a redirect after the load. */\n onPage: () => boolean\n}\n\nconst pathOf = (fullPath: string) => fullPath.split(/[?#]/, 1)[0] ?? fullPath\nconst withoutHash = (fullPath: string) => fullPath.split('#', 1)[0] ?? fullPath\n\n// A param's name, its custom regex (whose `)` may be escaped) and its modifier: `?` and `*` make it optional.\nconst PATH_PARAM = /:(\\w+)(?:\\((?:\\\\.|[^\\\\)])*\\))?([?*+])?/g\n\nconst paramsOf = (router: Router, name: RouteRecordName) => {\n const record = router.getRoutes().find((route) => route.name === name)\n if (!record) return undefined\n return [...record.path.matchAll(PATH_PARAM)].map((match) => ({\n key: match[1]!,\n optional: match[2] === '?' || match[2] === '*',\n }))\n}\n\n// `router.back()` returns nothing, so its landing or its error is the result.\nconst waitForLanding = (router: Router) =>\n new Promise<boolean>((resolve) => {\n const done = (landed: boolean) => {\n stopAfterEach()\n stopError()\n resolve(landed)\n }\n const stopAfterEach = router.afterEach((_to, _from, failure) => done(!failure))\n const stopError = router.onError(() => done(false))\n })\n\nconst settled = (navigation: Promise<NavigationFailure | void | undefined>) =>\n navigation.then(\n (failure) => !failure,\n () => false\n )\n\n/**\n * For a detail or edit page: aborts the record's load when the page goes, and leaves the page when the load fails.\n * `false` from the loader means leave. `undefined` is a superseded or aborted load, and the page stays.\n * While the user navigates elsewhere (`trackNavigation`), the page does not\n * leave. If that navigation fails, the page stays with its loading flag up.\n * Not handled: a guard that refuses the step back can leave the address bar out of sync with the router.\n * @example\n * useRecordPage({ fallbackRouteName: '/x', skipRouteNames: [...],\n * loading: detailLoading, load: (signal) => fetchData(id, { signal }) })\n */\nexport function useRecordPage(options: UseRecordPageOptions = {}): UseRecordPageReturn {\n const router = useRouter()\n const { history } = useRouteHistory()\n const { preservePageForLanding } = useDatatablePageStore()\n const { onPage } = usePageNavigation()\n\n // The path, not the name: /x/1 and /x/2 share a name, and a late failure of one must not move the user off the other.\n const path = router.currentRoute.value.path\n // The page is visited again, so an earlier failure no longer counts.\n forgetLeftAfterFailure(path)\n const controller = new AbortController()\n let unmounted = false\n onBeforeUnmount(() => {\n unmounted = true\n controller.abort()\n // Raised by `leave`, or left up by the aborted load whose `finally` no longer owns it.\n // The next page mounts after this one is gone and raises it again for its own load.\n if (options.loading) options.loading.value = false\n })\n\n const stillHere = () => !unmounted && router.currentRoute.value.path === path\n\n // Unlike the Close button, which skips every entry with the record's route name, this\n // returns to the view the user came from, including another record of the same entity.\n // Only this record's addresses are skipped, compared without query and hash (a tab in the query is the same view).\n // The create form is skipped too: going back there, Save would create a second record.\n const skipped = () => {\n const current = router.currentRoute.value\n const paths = new Set<string>([pathOf(current.fullPath)])\n const names = new Set<RouteRecordName>()\n for (const name of options.skipRouteNames ?? []) {\n const declared = paramsOf(router, name)\n if (!declared) continue\n // A route without params is one address; one the record cannot fill is skipped by name.\n if (declared.length === 0 || declared.some(({ key, optional }) => !optional && !(key in current.params))) {\n names.add(name)\n continue\n }\n const params = Object.fromEntries(\n declared.filter(({ key }) => key in current.params).map(({ key }) => [key, current.params[key]])\n )\n try {\n paths.add(pathOf(router.resolve({ name, params }).fullPath))\n } catch {\n names.add(name)\n }\n }\n return { paths, names }\n }\n\n const findTarget = (): string | undefined => {\n const { paths, names } = skipped()\n for (let i = history.value.length - 1; i >= 0; i--) {\n const entry = history.value[i]!\n // Addresses left recently after a failure are skipped too.\n // Otherwise two failing records in the history (A, then B, backend down) send the\n // user back and forth for the whole outage. Skipped, the chain ends at the list.\n if (paths.has(pathOf(entry.fullPath)) || isLeftAfterFailureRecently(pathOf(entry.fullPath))) continue\n if (entry.name !== undefined && entry.name !== null && names.has(entry.name as RouteRecordName)) continue\n return entry.fullPath\n }\n return undefined\n }\n\n // Leaves no trace of the failed address: a step back when the target is the previous entry, a replace otherwise.\n // A push would let browser Back return to the failed page, which would fail and leave again.\n const go = async (to: RouteLocationRaw): Promise<boolean> => {\n let target: string\n try {\n target = router.resolve(to).fullPath\n } catch {\n return false\n }\n // Compared without the hash. A list filter writes the hash outside the\n // router, so `state.back` lacks it while the route history has it.\n // The filter keeps the list entry's `current` in sync, so the step back lands on the filter and adds no entry.\n const back = router.options.history.state.back\n if (typeof back === 'string' && withoutHash(back) === withoutHash(target)) {\n const landing = waitForLanding(router)\n preservePageForLanding(router)\n router.back()\n return landing\n }\n const navigation = router.replace(to)\n preservePageForLanding(router, { to, navigation })\n return settled(navigation)\n }\n\n const leave = async (): Promise<boolean> => {\n if (!stillHere()) return false\n // Stays up for good if the leave fails. The record is not loaded, and its Save and Delete buttons must not return.\n // The Close button, which no page ties to loading, is the way out then.\n if (options.loading) options.loading.value = true\n // The user is navigating to another page. That navigation decides, and ours would cancel it.\n if (!onPage()) return false\n markLeftAfterFailure(path)\n const target = findTarget()\n if (target !== undefined && (await go(target))) return true\n if (!stillHere() || !onPage() || options.fallbackRouteName === undefined) return false\n return go({ name: options.fallbackRouteName, params: options.fallbackRouteParams })\n }\n\n const { load } = options\n if (load) {\n onMounted(async () => {\n if ((await load(controller.signal)) === false) await leave()\n })\n }\n\n return { signal: controller.signal, leave, onPage }\n}\n"],"mappings":"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"}
|
|
@@ -18,12 +18,11 @@ export interface NavigateBackTarget {
|
|
|
18
18
|
}
|
|
19
19
|
export interface NavigateBackOptions {
|
|
20
20
|
/**
|
|
21
|
-
* Route names that are not a destination
|
|
22
|
-
*
|
|
23
|
-
* on top of these, so there is no need to name it here.
|
|
21
|
+
* Route names that are not a destination, typically the record's sibling views and its create form.
|
|
22
|
+
* The current route is always skipped, so do not list it here.
|
|
24
23
|
*/
|
|
25
24
|
skipRouteNames?: RouteRecordName[];
|
|
26
|
-
/** Where to go when the walk finds nothing
|
|
25
|
+
/** Where to go when the walk finds nothing, e.g. a tab opened directly on the record. */
|
|
27
26
|
fallbackRouteName?: RouteRecordName;
|
|
28
27
|
fallbackRouteParams?: Record<string, any>;
|
|
29
28
|
}
|
|
@@ -33,6 +32,6 @@ export declare function useRouteHistory(): {
|
|
|
33
32
|
clearHistory: () => void;
|
|
34
33
|
setBlacklistedRoutes: (routeNames: RouteRecordName[]) => void;
|
|
35
34
|
addBlacklistedRoute: (routeName: RouteRecordName) => void;
|
|
36
|
-
/** Returns
|
|
35
|
+
/** Returns the target and its navigation, or `undefined` for a browser history step back. */
|
|
37
36
|
navigateBack: (router: Router, options?: NavigateBackOptions) => NavigateBackTarget | undefined;
|
|
38
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeHistory.js","names":["history","ref","historyGeneration","leftAfterFailure","LEFT_AFTER_FAILURE_MS","markLeftAfterFailure","now","left","at","path","forgetLeftAfterFailure","isLeftAfterFailureRecently","blacklistedRouteNames","MAX_HISTORY","useRouteHistory","addRoute","route","pathAndQuery","lastRoute","setBlacklistedRoutes","routeNames","addBlacklistedRoute","routeName","findRouteBack","i","isDestination","readonly","options","current","router","skip","skipRouteNames","isCurrent","entry","generation","navigation","failure","fallbackRouteName","fallback","fallbackRouteParams"],"sources":["../../../../src/domains/system/composables/routeHistory.ts"],"sourcesContent":["import type {\n NavigationFailure,\n RouteLocationNormalized,\n RouteLocationRaw,\n RouteRecordName,\n RouteRecordNameGeneric,\n Router,\n} from 'vue-router'\nimport { readonly, type Ref, ref } from 'vue'\n\n/** A visited route, as far as going back to it needs. */\nexport interface RouteHistoryEntry {\n name: RouteRecordNameGeneric\n fullPath: string\n}\n\n// Module state, so the history is one list per document. A test that fills it has to clear it\n// again (`clearHistory`), or the next test in the file reads what the previous one left behind.\nconst history = ref<RouteHistoryEntry[]>([])\n// Bumped by `clearHistory`, so that a Close landing after it leaves the new list alone.\nlet historyGeneration = 0\n// Paths a record page left because its record failed, with when; read by `useRecordPage`, which\n// skips them as a destination for a while. Here so that `clearHistory` clears it with the history.\nconst leftAfterFailure = new Map<string, number>()\nconst LEFT_AFTER_FAILURE_MS = 60_000\n\n/** For `useRecordPage` only. */\nexport const markLeftAfterFailure = (path: string) => {\n const now = Date.now()\n // Expired ones go here too: a path is otherwise only dropped when it is looked up again.\n for (const [left, at] of leftAfterFailure) if (now - at >= LEFT_AFTER_FAILURE_MS) leftAfterFailure.delete(left)\n leftAfterFailure.set(path, now)\n}\n\n/** For `useRecordPage` only: the page is there again, so a failure before no longer counts. */\nexport const forgetLeftAfterFailure = (path: string) => {\n leftAfterFailure.delete(path)\n}\n\n/** For `useRecordPage` only. */\nexport const isLeftAfterFailureRecently = (path: string) => {\n const at = leftAfterFailure.get(path)\n if (at === undefined) return false\n if (Date.now() - at < LEFT_AFTER_FAILURE_MS) return true\n leftAfterFailure.delete(path)\n return false\n}\nconst blacklistedRouteNames = ref<RouteRecordName[]>([])\n/**\n * How many routes back the history reaches. Note that `addRoute` drops only CONSECUTIVE duplicates,\n * so a user bouncing A -> B -> A -> B fills four of these slots and can push the listing they want\n * to return to out of the window. `fallbackRouteName` is what catches that.\n */\nconst MAX_HISTORY = 10\n\n/** Where `navigateBack` goes and its navigation, as `router.push` answers it. */\nexport interface NavigateBackTarget {\n to: RouteLocationRaw\n navigation: Promise<NavigationFailure | void | undefined>\n}\n\nexport interface NavigateBackOptions {\n /**\n * Route names that are not a destination -- typically the sibling views of the record being\n * closed and the create form it may have been reached from. The CURRENT route is always skipped\n * on top of these, so there is no need to name it here.\n */\n skipRouteNames?: RouteRecordName[]\n /** Where to go when the walk finds nothing -- a tab opened straight on the record. */\n fallbackRouteName?: RouteRecordName\n fallbackRouteParams?: Record<string, any>\n}\n\nexport function useRouteHistory(): {\n history: Readonly<Ref<readonly RouteHistoryEntry[]>>\n addRoute: (route: RouteLocationNormalized) => void\n clearHistory: () => void\n // The admin's typed router narrows `RouteRecordName` to its route names: a misspelled one does not compile.\n setBlacklistedRoutes: (routeNames: RouteRecordName[]) => void\n addBlacklistedRoute: (routeName: RouteRecordName) => void\n /** Returns where it goes and its navigation, `undefined` for a step back in the browser's history. */\n navigateBack: (router: Router, options?: NavigateBackOptions) => NavigateBackTarget | undefined\n} {\n const addRoute = (route: RouteLocationNormalized) => {\n if (blacklistedRouteNames.value.includes(route.name as RouteRecordName)) {\n return\n }\n\n // A list filter rewrites its hash with `history.replaceState`, which the router never sees. On a\n // push the address bar still shows the route being left, so its hash is the one to come back to.\n const [pathAndQuery] = route.fullPath.split('#')\n if (pathAndQuery === window.location.pathname + window.location.search && route.hash !== window.location.hash) {\n route = { ...route, hash: window.location.hash, fullPath: pathAndQuery + window.location.hash }\n }\n\n const lastRoute = history.value[history.value.length - 1]\n if (lastRoute && lastRoute.fullPath === route.fullPath) {\n return\n }\n\n history.value.push({ name: route.name, fullPath: route.fullPath })\n if (history.value.length > MAX_HISTORY) {\n history.value.shift()\n }\n }\n\n /** REPLACES the list. Two callers would overwrite each other -- to add one, use `addBlacklistedRoute`. */\n const setBlacklistedRoutes = (routeNames: RouteRecordName[]) => {\n blacklistedRouteNames.value = routeNames\n }\n\n const addBlacklistedRoute = (routeName: RouteRecordName) => {\n if (!blacklistedRouteNames.value.includes(routeName)) {\n blacklistedRouteNames.value.push(routeName)\n }\n }\n\n // Internal on purpose. A caller reaching for it directly would get the walk WITHOUT the\n // current-route exclusion `navigateBack` adds -- which is the whole trap `navigateBack` exists\n // to close.\n const findRouteBack = (isDestination: (route: RouteHistoryEntry) => boolean): RouteHistoryEntry | undefined => {\n for (let i = history.value.length - 1; i >= 0; i--) {\n if (isDestination(history.value[i]!)) {\n return history.value[i]\n }\n }\n return undefined\n }\n\n const clearHistory = () => {\n history.value = []\n historyGeneration++\n leftAfterFailure.clear()\n }\n\n const navigateBack = (router: Router, options: NavigateBackOptions = {}): NavigateBackTarget | undefined => {\n const { skipRouteNames, fallbackRouteName, fallbackRouteParams } = options\n const current = router.currentRoute.value\n const skip: readonly RouteRecordNameGeneric[] = skipRouteNames ?? []\n\n // The route we are on is never a place to go back to. `addRoute` runs in `beforeEach`, so a\n // navigation that a later guard cancels still records the route we never left -- and pushing\n // that again is a silent no-op, which reads as the button doing nothing at all. Callers\n // therefore do not name their own route in `skipRouteNames`.\n //\n // Both tests sit INSIDE the walk rather than filtering its result: a route name is optional in\n // vue-router, and a nameless current route can only be recognised by its path -- rejecting the\n // candidate afterwards would stop the walk at it instead of carrying on to the entry before.\n // Names are compared with `===` so a symbol name counts too, but only when the current route\n // has one: two different nameless routes are both `undefined` and are not the same place.\n const isCurrent = (route: RouteHistoryEntry) =>\n route.fullPath === current.fullPath || (current.name !== undefined && route.name === current.name)\n\n const route = findRouteBack((entry) => !isCurrent(entry) && !skip.includes(entry.name))\n\n if (route) {\n const generation = historyGeneration\n const navigation = router.push(route.fullPath)\n // Back on `route`, what came after it is behind the user, the route being left included, which\n // this navigation's `beforeEach` records. Kept, it is the next Close's destination: detail A, a\n // link to detail B, Close to A, and Close on A went back to B, over and over. Dropped once the\n // navigation has landed, so one that a guard stops (unsaved changes) or a second click cancels\n // leaves the history as it was. `Promise.resolve`: a test double's `push` may answer nothing.\n Promise.resolve(navigation).then(\n (failure) => {\n if (failure || generation !== historyGeneration) return\n // Gone without `clearHistory`, `route` was pushed out at the front (`MAX_HISTORY`) by the\n // route being left: all that is still here came after it.\n const at = history.value.indexOf(route)\n history.value.splice(at === -1 ? 0 : at)\n },\n () => undefined\n )\n return { to: route.fullPath, navigation }\n }\n if (fallbackRouteName) {\n const fallback = { name: fallbackRouteName, params: fallbackRouteParams }\n return { to: fallback, navigation: router.push(fallback) }\n }\n router.back()\n return undefined\n }\n\n return {\n history: readonly(history),\n addRoute,\n clearHistory,\n setBlacklistedRoutes,\n addBlacklistedRoute,\n navigateBack,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"routeHistory.js","names":["history","ref","historyGeneration","leftAfterFailure","LEFT_AFTER_FAILURE_MS","markLeftAfterFailure","now","left","at","path","forgetLeftAfterFailure","isLeftAfterFailureRecently","blacklistedRouteNames","MAX_HISTORY","useRouteHistory","addRoute","route","pathAndQuery","lastRoute","setBlacklistedRoutes","routeNames","addBlacklistedRoute","routeName","findRouteBack","i","isDestination","readonly","options","current","router","skip","skipRouteNames","isCurrent","entry","generation","navigation","failure","fallbackRouteName","fallback","fallbackRouteParams"],"sources":["../../../../src/domains/system/composables/routeHistory.ts"],"sourcesContent":["import type {\n NavigationFailure,\n RouteLocationNormalized,\n RouteLocationRaw,\n RouteRecordName,\n RouteRecordNameGeneric,\n Router,\n} from 'vue-router'\nimport { readonly, type Ref, ref } from 'vue'\n\n/** A visited route, as far as going back to it needs. */\nexport interface RouteHistoryEntry {\n name: RouteRecordNameGeneric\n fullPath: string\n}\n\n// Module state, so there is one history per document. A test that fills\n// it must call `clearHistory`, or the next test sees the leftovers.\nconst history = ref<RouteHistoryEntry[]>([])\n// Bumped by `clearHistory`, so a Close landing afterwards leaves the new list alone.\nlet historyGeneration = 0\n// Paths a record page left after its record failed, with the\n// time. `useRecordPage` skips them as destinations for a while.\n// Kept here so `clearHistory` clears it too.\nconst leftAfterFailure = new Map<string, number>()\nconst LEFT_AFTER_FAILURE_MS = 60_000\n\n/** For `useRecordPage` only. */\nexport const markLeftAfterFailure = (path: string) => {\n const now = Date.now()\n // Prunes expired entries here too. Otherwise a path is dropped only when it is looked up again.\n for (const [left, at] of leftAfterFailure) if (now - at >= LEFT_AFTER_FAILURE_MS) leftAfterFailure.delete(left)\n leftAfterFailure.set(path, now)\n}\n\n/** For `useRecordPage` only: the page is there again, so a failure before no longer counts. */\nexport const forgetLeftAfterFailure = (path: string) => {\n leftAfterFailure.delete(path)\n}\n\n/** For `useRecordPage` only. */\nexport const isLeftAfterFailureRecently = (path: string) => {\n const at = leftAfterFailure.get(path)\n if (at === undefined) return false\n if (Date.now() - at < LEFT_AFTER_FAILURE_MS) return true\n leftAfterFailure.delete(path)\n return false\n}\nconst blacklistedRouteNames = ref<RouteRecordName[]>([])\n/**\n * How many routes back the history reaches. `addRoute` drops only consecutive\n * duplicates, so A, B, A, B uses four slots and can push the wanted list out.\n * `fallbackRouteName` covers that case.\n */\nconst MAX_HISTORY = 10\n\n/** Where `navigateBack` goes and its navigation, as `router.push` answers it. */\nexport interface NavigateBackTarget {\n to: RouteLocationRaw\n navigation: Promise<NavigationFailure | void | undefined>\n}\n\nexport interface NavigateBackOptions {\n /**\n * Route names that are not a destination, typically the record's sibling views and its create form.\n * The current route is always skipped, so do not list it here.\n */\n skipRouteNames?: RouteRecordName[]\n /** Where to go when the walk finds nothing, e.g. a tab opened directly on the record. */\n fallbackRouteName?: RouteRecordName\n fallbackRouteParams?: Record<string, any>\n}\n\nexport function useRouteHistory(): {\n history: Readonly<Ref<readonly RouteHistoryEntry[]>>\n addRoute: (route: RouteLocationNormalized) => void\n clearHistory: () => void\n // The admin's typed router narrows `RouteRecordName` to its route names: a misspelled one does not compile.\n setBlacklistedRoutes: (routeNames: RouteRecordName[]) => void\n addBlacklistedRoute: (routeName: RouteRecordName) => void\n /** Returns the target and its navigation, or `undefined` for a browser history step back. */\n navigateBack: (router: Router, options?: NavigateBackOptions) => NavigateBackTarget | undefined\n} {\n const addRoute = (route: RouteLocationNormalized) => {\n if (blacklistedRouteNames.value.includes(route.name as RouteRecordName)) {\n return\n }\n\n // A list filter rewrites its hash with `history.replaceState`, which the router never sees.\n // On a push the address bar still shows the route being left, so its hash is the one to return to.\n const [pathAndQuery] = route.fullPath.split('#')\n if (pathAndQuery === window.location.pathname + window.location.search && route.hash !== window.location.hash) {\n route = { ...route, hash: window.location.hash, fullPath: pathAndQuery + window.location.hash }\n }\n\n const lastRoute = history.value[history.value.length - 1]\n if (lastRoute && lastRoute.fullPath === route.fullPath) {\n return\n }\n\n history.value.push({ name: route.name, fullPath: route.fullPath })\n if (history.value.length > MAX_HISTORY) {\n history.value.shift()\n }\n }\n\n /** Replaces the whole list, so two callers overwrite each other. Use `addBlacklistedRoute` to add one. */\n const setBlacklistedRoutes = (routeNames: RouteRecordName[]) => {\n blacklistedRouteNames.value = routeNames\n }\n\n const addBlacklistedRoute = (routeName: RouteRecordName) => {\n if (!blacklistedRouteNames.value.includes(routeName)) {\n blacklistedRouteNames.value.push(routeName)\n }\n }\n\n // Internal on purpose. Called directly, it lacks the current-route exclusion that `navigateBack` adds.\n const findRouteBack = (isDestination: (route: RouteHistoryEntry) => boolean): RouteHistoryEntry | undefined => {\n for (let i = history.value.length - 1; i >= 0; i--) {\n if (isDestination(history.value[i]!)) {\n return history.value[i]\n }\n }\n return undefined\n }\n\n const clearHistory = () => {\n history.value = []\n historyGeneration++\n leftAfterFailure.clear()\n }\n\n const navigateBack = (router: Router, options: NavigateBackOptions = {}): NavigateBackTarget | undefined => {\n const { skipRouteNames, fallbackRouteName, fallbackRouteParams } = options\n const current = router.currentRoute.value\n const skip: readonly RouteRecordNameGeneric[] = skipRouteNames ?? []\n\n // The current route is never a destination. `addRoute` runs in `beforeEach`, so a navigation\n // cancelled by a later guard still records it, and pushing it again is a silent no-op.\n // The check runs inside the walk, not on its result. A nameless current route is recognised only\n // by its path, and rejecting the result afterwards would stop the walk instead of continuing.\n // Names use `===` so symbol names work, but only when the current route has\n // a name: two nameless routes are both `undefined` and not the same place.\n const isCurrent = (route: RouteHistoryEntry) =>\n route.fullPath === current.fullPath || (current.name !== undefined && route.name === current.name)\n\n const route = findRouteBack((entry) => !isCurrent(entry) && !skip.includes(entry.name))\n\n if (route) {\n const generation = historyGeneration\n const navigation = router.push(route.fullPath)\n // Back on `route`, the entries after it are behind the user. Kept, they become\n // the next Close's destination, and Close ping-pongs between two details.\n // They are dropped only after landing, so a navigation stopped by a\n // guard or cancelled by a second click leaves the history unchanged.\n // `Promise.resolve` because a test double's `push` may return nothing.\n Promise.resolve(navigation).then(\n (failure) => {\n if (failure || generation !== historyGeneration) return\n // Missing without `clearHistory` means `route` was pushed out\n // at the front by `MAX_HISTORY`. Everything left came after it.\n const at = history.value.indexOf(route)\n history.value.splice(at === -1 ? 0 : at)\n },\n () => undefined\n )\n return { to: route.fullPath, navigation }\n }\n if (fallbackRouteName) {\n const fallback = { name: fallbackRouteName, params: fallbackRouteParams }\n return { to: fallback, navigation: router.push(fallback) }\n }\n router.back()\n return undefined\n }\n\n return {\n history: readonly(history),\n addRoute,\n clearHistory,\n setBlacklistedRoutes,\n addBlacklistedRoute,\n navigateBack,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentry.js","names":["sentryPromise","getSentry","module","useSentry","consoleLabel","component","report","sentry","taggedContext","context","error","level","message","key","value","user"],"sources":["../../../../src/domains/system/composables/sentry.ts"],"sourcesContent":["import type * as SentryType from '@sentry/vue'\n\ninterface SentryContext {\n extra?: Record<string, any>\n tags?: Record<string, string>\n level?: 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug'\n [key: string]: any\n}\n\nlet sentryPromise: Promise<typeof SentryType | null> | null = null\n\nconst getSentry = (): Promise<typeof SentryType | null> => {\n if (!sentryPromise) {\n sentryPromise = import('@sentry/vue').then((module) => module).catch(() => null)\n }\n return sentryPromise\n}\n\nexport function useSentry(component = 'common-admin') {\n const consoleLabel = `[${component}]`\n\n /**\n * Sentry is imported lazily, so
|
|
1
|
+
{"version":3,"file":"sentry.js","names":["sentryPromise","getSentry","module","useSentry","consoleLabel","component","report","sentry","taggedContext","context","error","level","message","key","value","user"],"sources":["../../../../src/domains/system/composables/sentry.ts"],"sourcesContent":["import type * as SentryType from '@sentry/vue'\n\ninterface SentryContext {\n extra?: Record<string, any>\n tags?: Record<string, string>\n level?: 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug'\n [key: string]: any\n}\n\nlet sentryPromise: Promise<typeof SentryType | null> | null = null\n\nconst getSentry = (): Promise<typeof SentryType | null> => {\n if (!sentryPromise) {\n sentryPromise = import('@sentry/vue').then((module) => module).catch(() => null)\n }\n return sentryPromise\n}\n\nexport function useSentry(component = 'common-admin') {\n const consoleLabel = `[${component}]`\n\n /**\n * Sentry is imported lazily, so this is async and must never\n * throw. A failed report must not break the code that reports.\n */\n const report = (send: (sentry: typeof SentryType) => void): void => {\n getSentry().then((sentry) => {\n if (!sentry) {\n return\n }\n try {\n send(sentry)\n } catch (e) {\n console.debug('Sentry logging failed', e)\n }\n })\n }\n\n const taggedContext = (context?: SentryContext): SentryContext => ({\n ...context,\n tags: {\n ...context?.tags,\n component,\n },\n })\n\n const logError = (error: Error, context?: SentryContext): void => {\n console.error(consoleLabel, error)\n\n report((sentry) => sentry.captureException(error, taggedContext(context)))\n }\n\n const logMessage = (\n message: string,\n level: 'fatal' | 'error' | 'warning' | 'info' | 'debug' = 'info',\n context?: SentryContext\n ): void => {\n switch (level) {\n case 'fatal':\n case 'error':\n console.error(consoleLabel, message)\n break\n case 'warning':\n console.warn(consoleLabel, message)\n break\n case 'info':\n console.info(consoleLabel, message)\n break\n case 'debug':\n console.debug(consoleLabel, message)\n break\n default:\n console.log(consoleLabel, message)\n }\n\n report((sentry) => sentry.captureMessage(message, { level, ...taggedContext(context) }))\n }\n\n const setTag = (key: string, value: string): void => {\n report((sentry) => sentry.setTag(key, value))\n }\n\n const setUser = (user: { id: string; email?: string; username?: string }): void => {\n report((sentry) => sentry.setUser(user))\n }\n\n return {\n logError,\n logMessage,\n setTag,\n setUser,\n }\n}\n"],"mappings":";AASA,IAAIA,IAA0D,MAExDC,WACJ,AACED,MAAgB,OAAO,cAAc,CAAC,MAAM,MAAWE,CAAM,CAAC,CAAC,YAAY,IAAI,GAE1EF;AAGT,SAAgBG,EAAU,IAAY,gBAAgB;CACpD,IAAMC,IAAe,IAAIC,EAAU,IAM7BC,KAAU,MAAoD;EAClE,EAAU,CAAC,CAAC,MAAM,MAAW;GAC3B,IAAKC,GAGL,IAAI;IACF,EAAKA,CAAM;GACb,SAAS,GAAG;IACV,QAAQ,MAAM,yBAAyB,CAAC;GAC1C;EACF,CAAC;CACH,GAEMC,KAAiB,OAA4C;EACjE,GAAGC;EACH,MAAM;GACJ,GAAGA,GAAS;GACZ;EACF;CACF;CA0CA,OAAO;EACL,WAzCgB,GAAc,MAAkC;GAGhE,AAFA,QAAQ,MAAML,GAAcM,CAAK,GAEjCJ,GAAQ,MAAWC,EAAO,iBAAiBG,GAAOF,EAAcC,CAAO,CAAC,CAAC;EAC3E;EAsCE,aAnCA,GACA,IAA0D,QAC1D,MACS;GACT,QAAQE,GAAR;IACE,KAAK;IACL,KAAK;KACH,QAAQ,MAAMP,GAAcQ,CAAO;KACnC;IACF,KAAK;KACH,QAAQ,KAAKR,GAAcQ,CAAO;KAClC;IACF,KAAK;KACH,QAAQ,KAAKR,GAAcQ,CAAO;KAClC;IACF,KAAK;KACH,QAAQ,MAAMR,GAAcQ,CAAO;KACnC;IACF,SACE,QAAQ,IAAIR,GAAcQ,CAAO;GACrC;GAEA,GAAQ,MAAWL,EAAO,eAAeK,GAAS;IAAE;IAAO,GAAGJ,EAAcC,CAAO;GAAE,CAAC,CAAC;EACzF;EAaE,SAXc,GAAa,MAAwB;GACnD,GAAQ,MAAWF,EAAO,OAAOM,GAAKC,CAAK,CAAC;EAC9C;EAUE,UARe,MAAkE;GACjF,GAAQ,MAAWP,EAAO,QAAQQ,CAAI,CAAC;EACzC;CAOA;AACF"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Developer
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Plain localStorage, so it needs no current user -- which is what makes it usable in an admin
|
|
7
|
-
* where the user may not have an account in any particular system yet.
|
|
2
|
+
* Developer diagnostics switch, separate from `useUnreleasedFeatures` on purpose. Enabling
|
|
3
|
+
* work in progress must not arm the error-reporting test buttons, and vice versa.
|
|
4
|
+
* Uses plain localStorage, so it needs no current user and works where the user has no account in a system yet.
|
|
8
5
|
*/
|
|
9
6
|
export declare function useDebugFeatures(): {
|
|
10
7
|
showDebugFeatures: import('@vueuse/shared').RemovableRef<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDebugFeatures.js","names":["NAME","useDebugFeatures","useStorage"],"sources":["../../../../src/domains/system/composables/useDebugFeatures.ts"],"sourcesContent":["import { useStorage } from '@vueuse/core'\n\nconst NAME = 'debugFeatures'\n\n/**\n * Developer
|
|
1
|
+
{"version":3,"file":"useDebugFeatures.js","names":["NAME","useDebugFeatures","useStorage"],"sources":["../../../../src/domains/system/composables/useDebugFeatures.ts"],"sourcesContent":["import { useStorage } from '@vueuse/core'\n\nconst NAME = 'debugFeatures'\n\n/**\n * Developer diagnostics switch, separate from `useUnreleasedFeatures` on purpose. Enabling\n * work in progress must not arm the error-reporting test buttons, and vice versa.\n * Uses plain localStorage, so it needs no current user and works where the user has no account in a system yet.\n */\nexport function useDebugFeatures() {\n const showDebugFeatures = useStorage(NAME, false, localStorage, { writeDefaults: false })\n\n return {\n showDebugFeatures,\n }\n}\n"],"mappings":";;AAEA,IAAMA,IAAO;AAOb,SAAgBC,IAAmB;CAGjC,OAAO,EACL,mBAHwBC,EAAWF,GAAM,IAAO,cAAc,EAAE,eAAe,GAAM,CAGrF,EACF;AACF"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { Router } from 'vue-router';
|
|
2
2
|
import { NavigateBackTarget } from '../composables/routeHistory';
|
|
3
|
+
export interface StoredDatatablePage {
|
|
4
|
+
page: number;
|
|
5
|
+
rowsPerPage?: number;
|
|
6
|
+
view?: string;
|
|
7
|
+
}
|
|
3
8
|
export declare const datatablePageKey: (system?: unknown, subject?: unknown) => string;
|
|
4
9
|
export declare function useDatatablePageStore(): {
|
|
5
|
-
setStoredPage: (key: string, page: number) => void;
|
|
10
|
+
setStoredPage: (key: string, page: number, rowsPerPage?: number, view?: string | null) => void;
|
|
6
11
|
setPreservePage: () => void;
|
|
7
12
|
preservePageForLanding: (router: Router, closing?: NavigateBackTarget) => void;
|
|
8
13
|
consumeStoredPage: (key: string) => number | null;
|
|
14
|
+
getStoredRowsPerPage: (key: string) => number | null;
|
|
15
|
+
getStoredView: (key: string) => string | null;
|
|
9
16
|
};
|
|
@@ -5,8 +5,13 @@ import { NavigationFailureType as n, isNavigationFailure as r } from "vue-router
|
|
|
5
5
|
var i = t({}), a = t(!1), o = "__unscoped", s, c = (e, t) => typeof e == "string" && typeof t == "string" ? `${e}_${t}` : o;
|
|
6
6
|
function l() {
|
|
7
7
|
return {
|
|
8
|
-
setStoredPage: (
|
|
9
|
-
|
|
8
|
+
setStoredPage: (t, n, r, a) => {
|
|
9
|
+
let o = {
|
|
10
|
+
...i.value[t],
|
|
11
|
+
page: n,
|
|
12
|
+
rowsPerPage: r
|
|
13
|
+
};
|
|
14
|
+
a === null ? delete o.view : e(a) || (o.view = a), i.value[t] = o;
|
|
10
15
|
},
|
|
11
16
|
setPreservePage: () => {
|
|
12
17
|
a.value = !0;
|
|
@@ -33,7 +38,9 @@ function l() {
|
|
|
33
38
|
}), p = e(i) ? t.onError(d) : void 0;
|
|
34
39
|
s = u;
|
|
35
40
|
},
|
|
36
|
-
consumeStoredPage: (e) => a.value ? (a.value = !1, i.value[e] ?? null) : null
|
|
41
|
+
consumeStoredPage: (e) => a.value ? (a.value = !1, i.value[e]?.page ?? null) : null,
|
|
42
|
+
getStoredRowsPerPage: (e) => i.value[e]?.rowsPerPage ?? null,
|
|
43
|
+
getStoredView: (e) => i.value[e]?.view ?? null
|
|
37
44
|
};
|
|
38
45
|
}
|
|
39
46
|
export { c as datatablePageKey, l as useDatatablePageStore };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datatablePageStore.js","names":["storedPages","ref","preservePage","UNSCOPED_KEY","stopPendingLanding","datatablePageKey","system","subject","useDatatablePageStore","key","
|
|
1
|
+
{"version":3,"file":"datatablePageStore.js","names":["storedPages","ref","preservePage","UNSCOPED_KEY","stopPendingLanding","datatablePageKey","system","subject","useDatatablePageStore","stored","key","view","isUndefined","landed","stopped","target","closing","router","stop","stopAfterEach","stopError","drop","failure","isNavigationFailure","NavigationFailureType","landing"],"sources":["../../../../src/domains/system/store/datatablePageStore.ts"],"sourcesContent":["import { ref } from 'vue'\nimport { isNavigationFailure, NavigationFailureType, type Router } from 'vue-router'\nimport type { NavigateBackTarget } from '@/domains/system/composables/routeHistory'\nimport { isUndefined } from '@/shared/utils/common'\n\n// The page is stored per table. A single global slot leaked across lists, so list A reopened on the page set in list B.\n// The preserve flag stays global on purpose: it means the next list landed on restores its page.\n// The rows per page are kept with the page: page 3 at another page size shows other rows.\n// So is the view, the serialized filter and sort the page was shown in (see `useFilterHelpers`).\nexport interface StoredDatatablePage {\n page: number\n rowsPerPage?: number\n view?: string\n}\nconst storedPages = ref<Record<string, StoredDatatablePage>>({})\nconst preservePage = ref<boolean>(false)\n\nconst UNSCOPED_KEY = '__unscoped'\n\n// Shared by all Close buttons. A newer Close takes over an older one's\n// landing, so the older one cannot clear the flag the newer one set.\nlet stopPendingLanding: (() => void) | undefined\n\nexport const datatablePageKey = (system?: unknown, subject?: unknown): string =>\n typeof system === 'string' && typeof subject === 'string' ? `${system}_${subject}` : UNSCOPED_KEY\n\nexport function useDatatablePageStore() {\n // `view` undefined keeps the stored one: the pager stores a page change, which stays in the view\n // the filter helpers stored on load, submit or reset. `null` forgets it.\n const setStoredPage = (key: string, page: number, rowsPerPage?: number, view?: string | null) => {\n const stored: StoredDatatablePage = { ...storedPages.value[key], page, rowsPerPage }\n if (view === null) delete stored.view\n else if (!isUndefined(view)) stored.view = view\n storedPages.value[key] = stored\n }\n\n const setPreservePage = () => {\n preservePage.value = true\n }\n\n /**\n * Sets the flag only for the page the Close's navigation lands on.\n * A list there reads it on mount, after the landing's `afterEach`.\n * The flag is dropped by the next navigation, by the Close's navigation failing\n * or being cancelled, and by a landing elsewhere. A second click takes it over.\n * Without `closing` (browser step back, which returns nothing) the first\n * landing takes it, and a non-cancel failure or navigation error drops it.\n * The push rejection is handled here, so errors vue-router does not report (e.g. an app\n * `afterEach` throwing) are not unhandled. During a step back the store also listens to `onError`,\n * so vue-router does not log that error to the console in apps without their own listener.\n */\n const preservePageForLanding = (router: Router, closing?: NavigateBackTarget) => {\n stopPendingLanding?.()\n preservePage.value = true\n let landed = false\n let stopped = false\n const target = isUndefined(closing) ? undefined : router.resolve(closing.to).fullPath\n const stop = () => {\n stopped = true\n stopAfterEach()\n stopError?.()\n }\n const drop = () => {\n stop()\n if (stopPendingLanding === stop) stopPendingLanding = undefined\n preservePage.value = false\n }\n closing?.navigation.then(\n (failure) => {\n if (!stopped && failure) drop()\n },\n () => {\n if (!stopped) drop()\n }\n )\n const stopAfterEach = router.afterEach((landing, _from, failure) => {\n if (landed) return drop()\n if (failure) {\n // Another navigation's failure is not the Close's to answer for; the Close's own comes from its push.\n if (isUndefined(closing) && !isNavigationFailure(failure, NavigationFailureType.cancelled)) drop()\n return\n }\n if (!isUndefined(target) && (landing.redirectedFrom ?? landing).fullPath !== target) return drop()\n landed = true\n // Kept past the landing, the listener would keep vue-router from logging the next navigation's error.\n stopError?.()\n })\n const stopError = isUndefined(closing) ? router.onError(drop) : undefined\n stopPendingLanding = stop\n }\n\n const consumeStoredPage = (key: string): number | null => {\n if (!preservePage.value) return null\n preservePage.value = false\n return storedPages.value[key]?.page ?? null\n }\n\n // Read with a page `consumeStoredPage` returned, so the list shows the same rows.\n const getStoredRowsPerPage = (key: string): number | null => storedPages.value[key]?.rowsPerPage ?? null\n\n const getStoredView = (key: string): string | null => storedPages.value[key]?.view ?? null\n\n return {\n setStoredPage,\n setPreservePage,\n preservePageForLanding,\n consumeStoredPage,\n getStoredRowsPerPage,\n getStoredView,\n }\n}\n"],"mappings":";;;;AAcA,IAAMA,IAAcC,EAAyC,CAAC,CAAC,GACzDC,IAAeD,EAAa,EAAK,GAEjCE,IAAe,cAIjBC,GAESC,KAAoB,GAAkB,MACjD,OAAOC,KAAW,YAAY,OAAOC,KAAY,WAAW,GAAGD,EAAO,GAAGC,MAAYJ;AAEvF,SAAgBK,IAAwB;CA4EtC,OAAO;EACL,gBA1EqB,GAAa,GAAc,GAAsB,MAAyB;GAC/F,IAAMC,IAA8B;IAAE,GAAGT,EAAY,MAAMU;IAAM;IAAM;GAAY;GAGnF,AAFIC,MAAS,OAAM,OAAOF,EAAO,OACvBG,EAAYD,CAAI,MAAG,EAAO,OAAOA,IAC3C,EAAY,MAAMD,KAAOD;EAC3B;EAsEE,uBApE4B;GAC5B,EAAa,QAAQ;EACvB;EAmEE,yBAtD8B,GAAgB,MAAiC;GAE/E,AADAL,IAAqB,GACrB,EAAa,QAAQ;GACrB,IAAIS,IAAS,IACTC,IAAU,IACRC,IAASH,EAAYI,CAAO,IAAI,KAAA,IAAYC,EAAO,QAAQD,EAAQ,EAAE,CAAC,CAAC,UACvEE,UAAa;IAGjB,AAFA,IAAU,IACVC,EAAc,GACdC,IAAY;GACd,GACMC,UAAa;IAGjB,AAFAH,EAAK,GACDd,MAAuBc,MAAM,IAAqB,KAAA,IACtD,EAAa,QAAQ;GACvB;GACA,GAAS,WAAW,MACjB,MAAY;IACX,AAAI,CAACJ,KAAWQ,KAASD,EAAK;GAChC,SACM;IACJ,AAAKP,KAASO,EAAK;GACrB,CACF;GACA,IAAMF,IAAgBF,EAAO,WAAW,GAAS,GAAO,MAAY;IAClE,IAAIJ,GAAQ,OAAOQ,EAAK;IACxB,IAAIC,GAEF,AAAIV,EAAYI,CAAO,KAAK,CAACO,EAAoBD,GAASE,EAAsB,SAAS,KAAGH,EAAK;SAGnG;SAAI,CAACT,EAAYG,CAAM,MAAMU,EAAQ,kBAAkBA,EAAA,CAAS,aAAaV,GAAQ,OAAOM,EAAK;KAGjG,AAFA,IAAS,IAETD,IAAY;IAHqF;GAInG,CAAC,GACKA,IAAYR,EAAYI,CAAO,IAAIC,EAAO,QAAQI,CAAI,IAAI,KAAA;GAChE,IAAqBH;EACvB;EAiBE,oBAfyB,MACpBhB,EAAa,SAClB,EAAa,QAAQ,IACdF,EAAY,MAAMU,EAAI,EAAE,QAAQ,QAFP;EAehC,uBAT4B,MAA+BV,EAAY,MAAMU,EAAI,EAAE,eAAe;EAUlG,gBARqB,MAA+BV,EAAY,MAAMU,EAAI,EAAE,QAAQ;CAStF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ASystemBar.js","names":["_sfc_main","ASystemBar_vue_vue_type_script_setup_true_lang_default","ASystemBar_default"],"sources":["../../../../../src/domains/system/systemBar/components/ASystemBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport ASystemBarNewVersion from '@/domains/system/systemBar/components/ASystemBarNewVersion.vue'\nimport { isUndefined } from '@/shared/utils/common'\nimport { AnzuNewVersionFetchError, isAnzuNewVersionFetchError } from '@/shared/error/AnzuNewVersionFetchError'\nimport { useUserActivity } from '@/domains/system/composables/useUserActivity'\nimport { useSystemBar } from '@/domains/system/systemBar/composables/systemBar'\n\nconst props = withDefaults(\n defineProps<{\n currentVersion: string\n checkInterval?: number\n jsonRelativePath?: string\n minInactiveTime?: number\n }>(),\n {\n checkInterval: 60000,\n jsonRelativePath: 'config.json',\n minInactiveTime: 5000,\n }\n)\n\nconst showSystemBar = ref<boolean>(false)\nconst abortController = ref<AbortController | null>(null)\nconst lastInactiveTime = ref<number>(0)\n\nconst CONSECUTIVE_FAILURE_ALERT_THRESHOLD = 5\nlet consecutiveFailures = 0\nlet alertedForCurrentOutage = false\n\nconst { newVersion } = useSystemBar()\n\nconst checkNewVersion = async (): Promise<void> => {\n if (abortController.value) {\n abortController.value.abort()\n }\n\n abortController.value = new AbortController()\n\n const isAbortError = (error: unknown): error is Error => {\n return error instanceof Error && error.name === 'AbortError'\n }\n\n try {\n const res = await fetch(`/${props.jsonRelativePath}?random=${Date.now()}`, {\n signal: abortController.value.signal,\n })\n if (res.ok) {\n const contentType = res.headers.get('content-type')\n if (!contentType || !contentType.includes('application/json')) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect content type.')\n }\n const json = await res.json()\n if (Object.keys(json).length < 1) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect response body.')\n }\n showSystemBar.value = !isUndefined(json.appVersion) && json.appVersion !== props.currentVersion\n newVersion.value = showSystemBar.value\n consecutiveFailures = 0\n alertedForCurrentOutage = false\n\n return\n }\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect response code.')\n } catch (error) {\n if (isAbortError(error)) {\n return\n }\n if (isAnzuNewVersionFetchError(error)) {\n throw error\n }\n if (error instanceof SyntaxError) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Syntax error.', error)\n }\n if (error instanceof Error) {\n throw new AnzuNewVersionFetchError('Unable to load env config. ' + error.message, error)\n }\n throw new AnzuNewVersionFetchError('Unable to load env config. Unknown error.', error as any)\n }\n}\n\nconst systemBarComponent = computed(() => {\n return ASystemBarNewVersion\n})\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst { pause, resume } = useIntervalFn(() => {\n checkNewVersion().catch((error) => {\n if (isAnzuNewVersionFetchError(error)) {\n consecutiveFailures++\n if (consecutiveFailures >= CONSECUTIVE_FAILURE_ALERT_THRESHOLD && !alertedForCurrentOutage) {\n alertedForCurrentOutage = true\n // One signal per outage — ops can alert on this; resets on the next successful poll.\n console.error(`[ASystemBar] Version check failed ${consecutiveFailures} consecutive times:`, error)\n }\n return\n }\n console.warn(error)\n })\n}, props.checkInterval)\n\nconst { isWindowActive } = useUserActivity()\n\n// Only one retry is
|
|
1
|
+
{"version":3,"file":"ASystemBar.js","names":["_sfc_main","ASystemBar_vue_vue_type_script_setup_true_lang_default","ASystemBar_default"],"sources":["../../../../../src/domains/system/systemBar/components/ASystemBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport ASystemBarNewVersion from '@/domains/system/systemBar/components/ASystemBarNewVersion.vue'\nimport { isUndefined } from '@/shared/utils/common'\nimport { AnzuNewVersionFetchError, isAnzuNewVersionFetchError } from '@/shared/error/AnzuNewVersionFetchError'\nimport { useUserActivity } from '@/domains/system/composables/useUserActivity'\nimport { useSystemBar } from '@/domains/system/systemBar/composables/systemBar'\n\nconst props = withDefaults(\n defineProps<{\n currentVersion: string\n checkInterval?: number\n jsonRelativePath?: string\n minInactiveTime?: number\n }>(),\n {\n checkInterval: 60000,\n jsonRelativePath: 'config.json',\n minInactiveTime: 5000,\n }\n)\n\nconst showSystemBar = ref<boolean>(false)\nconst abortController = ref<AbortController | null>(null)\nconst lastInactiveTime = ref<number>(0)\n\nconst CONSECUTIVE_FAILURE_ALERT_THRESHOLD = 5\nlet consecutiveFailures = 0\nlet alertedForCurrentOutage = false\n\nconst { newVersion } = useSystemBar()\n\nconst checkNewVersion = async (): Promise<void> => {\n if (abortController.value) {\n abortController.value.abort()\n }\n\n abortController.value = new AbortController()\n\n const isAbortError = (error: unknown): error is Error => {\n return error instanceof Error && error.name === 'AbortError'\n }\n\n try {\n const res = await fetch(`/${props.jsonRelativePath}?random=${Date.now()}`, {\n signal: abortController.value.signal,\n })\n if (res.ok) {\n const contentType = res.headers.get('content-type')\n if (!contentType || !contentType.includes('application/json')) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect content type.')\n }\n const json = await res.json()\n if (Object.keys(json).length < 1) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect response body.')\n }\n showSystemBar.value = !isUndefined(json.appVersion) && json.appVersion !== props.currentVersion\n newVersion.value = showSystemBar.value\n consecutiveFailures = 0\n alertedForCurrentOutage = false\n\n return\n }\n throw new AnzuNewVersionFetchError('Unable to load env config. Incorrect response code.')\n } catch (error) {\n if (isAbortError(error)) {\n return\n }\n if (isAnzuNewVersionFetchError(error)) {\n throw error\n }\n if (error instanceof SyntaxError) {\n throw new AnzuNewVersionFetchError('Unable to load env config. Syntax error.', error)\n }\n if (error instanceof Error) {\n throw new AnzuNewVersionFetchError('Unable to load env config. ' + error.message, error)\n }\n throw new AnzuNewVersionFetchError('Unable to load env config. Unknown error.', error as any)\n }\n}\n\nconst systemBarComponent = computed(() => {\n return ASystemBarNewVersion\n})\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst { pause, resume } = useIntervalFn(() => {\n checkNewVersion().catch((error) => {\n if (isAnzuNewVersionFetchError(error)) {\n consecutiveFailures++\n if (consecutiveFailures >= CONSECUTIVE_FAILURE_ALERT_THRESHOLD && !alertedForCurrentOutage) {\n alertedForCurrentOutage = true\n // One signal per outage — ops can alert on this; resets on the next successful poll.\n console.error(`[ASystemBar] Version check failed ${consecutiveFailures} consecutive times:`, error)\n }\n return\n }\n console.warn(error)\n })\n}, props.checkInterval)\n\nconst { isWindowActive } = useUserActivity()\n\n// Only one retry is pending at a time. Untracked, a retry left\n// scheduled after unmount starts a fetch that cannot be aborted.\n// A new check also replaces a pending retry, since returning to\n// the window starts one while a previous retry may be pending.\nlet retryTimer: ReturnType<typeof setTimeout> | undefined = undefined\n\nconst checkNewVersionWithRetry = (attempt = 1, maxAttempts = 3) => {\n const delay = Math.min(1000 * attempt, 3000) // 1000ms, 2000ms, 3000ms\n\n clearTimeout(retryTimer)\n retryTimer = setTimeout(async () => {\n try {\n await checkNewVersion()\n } catch (error) {\n if (\n error instanceof AnzuNewVersionFetchError &&\n (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) &&\n attempt < maxAttempts\n ) {\n checkNewVersionWithRetry(attempt + 1, maxAttempts)\n } else {\n console.error('Version check failed:', error)\n }\n }\n }, delay)\n}\n\nwatch(\n isWindowActive,\n (newValue: boolean) => {\n const now: number = Date.now()\n\n if (newValue) {\n const inactiveDuration: number = now - lastInactiveTime.value\n resume()\n if (inactiveDuration > props.minInactiveTime) {\n checkNewVersionWithRetry()\n }\n } else {\n lastInactiveTime.value = now\n pause()\n }\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n clearTimeout(retryTimer)\n if (abortController.value) {\n abortController.value.abort()\n }\n})\n</script>\n\n<template>\n <VAppBar\n v-if=\"showSystemBar\"\n height=\"48\"\n color=\"orange-accent-3\"\n elevation=\"0\"\n :order=\"-1\"\n >\n <div class=\"text-center w-100 text-body-small pb-1\">\n <component :is=\"systemBarComponent\" />\n </div>\n </VAppBar>\n</template>\n"],"mappings":""}
|