@anzusystems/common-admin 2.0.0-rc.4 → 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/README.md +1 -1
- 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 +26 -26
- 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":"userCrossSystemWrites.js","names":["classifyWriteStatus","status","BulkOutcome","request","useApiRequest","descriptor","url","useUserCrossSystemWrites","resolveEnabledWrite","read","get","current","enabled","descriptorMayWrite","body","cloneDeep","write","saved","error","probeStatusFromError","USER_METADATA_FIELDS","resolveMetadataWrite","fields","readMetadataField","field","target","concurrentFields","isNull","seen","writeMetadataField","method","resolveCreateEndpoint","created","execute"],"sources":["../../../../src/domains/anzuUser/composables/userCrossSystemWrites.ts"],"sourcesContent":["import { useApiRequest } from '@/domains/api/composables/useApiRequest'\nimport { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_UNPROCESSABLE_ENTITY } from '@/shared/statusCodes'\nimport {\n type AnyUserSystemDescriptor,\n descriptorMayWrite,\n resolveCreateEndpoint,\n resolveEnabledWrite,\n resolveMetadataWrite,\n} from '@/domains/anzuUser/composables/userSystemDescriptor'\nimport { BulkOutcome, type BulkOutcomeType } from '@/domains/anzuUser/store/userCrossSystemStore'\nimport { probeStatusFromError } from '@/domains/anzuUser/composables/userSystemProbe'\nimport {\n readMetadataField,\n USER_METADATA_FIELDS,\n writeMetadataField,\n type UserMetadataField,\n} from '@/domains/anzuUser/utils/userMetadataDiff'\nimport type { AnzuUser, BaseUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId } from '@/shared/types/common'\nimport { cloneDeep, isNull } from '@/shared/utils/common'\n\nexport interface WriteResult {\n outcome: BulkOutcomeType\n /** What the server holds afterwards, when it answered with the record. */\n user?: AnzuUser\n /**\n * Fields whose stored value had moved away from both the target and what the search saw.\n *\n * The write still goes through -- decision 24 says the operator's value wins -- but somebody\n * edited the record in between, and the log line says so rather than letting it pass unnoticed.\n */\n concurrentFields?: UserMetadataField[]\n detail?: string\n}\n\n/**\n * What the operator is told about a failed write.\n *\n * 422 and 400 are their own line and not a generic failure: a PUT validates the whole body, and an\n * account carrying a colour or an e-mail that no longer passes validation will fail even on a plain\n * \"disable\". With legacy data that is an ordinary outcome, and \"could not be saved\" would send\n * somebody looking for a bug that is not there.\n */\nexport const classifyWriteStatus = (status: number | null): BulkOutcomeType => {\n if (status === null) return BulkOutcome.Unavailable\n if (status === 403) return BulkOutcome.Forbidden\n if (status === 401) return BulkOutcome.Unauthenticated\n if (status === 404) return BulkOutcome.NotFound\n if (status === HTTP_STATUS_UNPROCESSABLE_ENTITY || status === HTTP_STATUS_BAD_REQUEST) return BulkOutcome.Invalid\n return BulkOutcome.Unavailable\n}\n\nconst request = <R extends object, B>(\n descriptor: AnyUserSystemDescriptor,\n method: 'GET' | 'PUT' | 'PATCH' | 'POST',\n url: string\n) =>\n useApiRequest<R, B>({\n client: descriptor.client,\n method,\n system: descriptor.system,\n entity: descriptor.entity,\n urlTemplate: url,\n })\n\nexport const useUserCrossSystemWrites = () => {\n /**\n * Switching an account on or off.\n *\n * There is no PATCH for this anywhere -- the only method that calls `setEnabled` is the full\n * update -- so it is a read followed by a write on the same path, with the whole record the read\n * returned. That is not caution, it is the contract: the DTO defaults roles to `[ROLE_USER]`,\n * `enabled` to true and both permission collections to empty, and the manager writes all four\n * unconditionally. A body of \"just the enabled flag\" resets the roles, wipes the grants, detaches\n * the groups and switches a disabled account back on.\n *\n * On `/adm/users` in cms it goes further still: that PUT runs `updateRelations()` over seven\n * scalars and twelve collections, so an omitted `desks` does not mean \"unchanged\", it means\n * \"remove from every desk\".\n */\n const setEnabled = async (\n descriptor: AnyUserSystemDescriptor,\n id: IntegerId,\n enabled: boolean\n ): Promise<WriteResult> => {\n const { get, url } = resolveEnabledWrite(descriptor)\n try {\n const { execute: read } = request<AnzuUser, null>(descriptor, 'GET', get)\n const current = await read({ urlParams: { id } })\n if (current.enabled === enabled) {\n // Already there. A no-op PUT would still run `updateRelations()` in cms -- risk for nothing.\n return { outcome: BulkOutcome.Done, user: current }\n }\n // The right may have gone while the record was read: reported as the server would refuse it.\n if (!descriptorMayWrite(descriptor, 'update')) return { outcome: BulkOutcome.Forbidden }\n const body = cloneDeep(current)\n body.enabled = enabled\n const { execute: write } = request<AnzuUser, AnzuUser>(descriptor, 'PUT', url)\n const saved = await write({ urlParams: { id }, body })\n return { outcome: BulkOutcome.Done, user: saved }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)) }\n }\n }\n\n /**\n * Writing the shared metadata.\n *\n * Through `PATCH /adm/users/{id}` wherever that path exists, because the method behind it\n * physically cannot write roles, permissions, groups or `enabled` -- it has no setters for them.\n * That is a stronger guarantee than assembling a careful body, and it is why the plan sends\n * metadata this way rather than through the full update.\n *\n * The body is still the whole record the read returned. `id` in particular has to be in it: the\n * uniqueness validator only excludes the record itself when the DTO carries a non-empty id, and\n * without it the server reports the user's own e-mail as already taken -- on every account.\n */\n const writeMetadata = async (\n descriptor: AnyUserSystemDescriptor,\n id: IntegerId,\n target: BaseUser,\n fields: readonly UserMetadataField[] = USER_METADATA_FIELDS,\n /** What the search showed for this system, so a change made in between can be recognised. */\n seen: BaseUser | null = null\n ): Promise<WriteResult & { changed: boolean }> => {\n const { method, get, url } = resolveMetadataWrite(descriptor)\n try {\n const { execute: read } = request<AnzuUser, null>(descriptor, 'GET', get)\n // Read again immediately before writing, not reused from the search: those results can be\n // hours old, and a system whose value already matches must not be written to at all.\n const current = await read({ urlParams: { id } })\n\n const differs = fields.some((field) => readMetadataField(current, field) !== readMetadataField(target, field))\n if (!differs) return { outcome: BulkOutcome.Done, user: current, changed: false }\n\n // Different from what the operator chose *and* from what they were shown when they chose it:\n // somebody else wrote to this record in between. The value still goes in -- that is what was\n // asked for -- and the log names the fields.\n const concurrentFields = isNull(seen)\n ? []\n : fields.filter(\n (field) =>\n readMetadataField(current, field) !== readMetadataField(seen, field) &&\n readMetadataField(current, field) !== readMetadataField(target, field)\n )\n\n // The right may have gone while the record was read: reported as the server would refuse it.\n if (!descriptorMayWrite(descriptor, 'update')) return { outcome: BulkOutcome.Forbidden, changed: false }\n const body = cloneDeep(current)\n fields.forEach((field) => writeMetadataField(body, field, readMetadataField(target, field)))\n\n const { execute: write } = request<AnzuUser, AnzuUser>(descriptor, method, url)\n const saved = await write({ urlParams: { id }, body })\n return { outcome: BulkOutcome.Done, user: saved, changed: true, concurrentFields }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)), changed: false }\n }\n }\n\n /**\n * Creating an account in another system.\n *\n * The body comes from the library factory -- `roles: []`, `enabled: false` -- with the metadata\n * copied over. Assembling it by hand from base fields is what would have the backend fill in\n * `ROLE_USER`, leaving an account with a role nobody granted.\n */\n const createInSystem = async (descriptor: AnyUserSystemDescriptor, body: AnzuUser): Promise<WriteResult> => {\n try {\n const { execute } = request<AnzuUser, AnzuUser>(descriptor, 'POST', resolveCreateEndpoint(descriptor))\n const created = await execute({ body })\n return { outcome: BulkOutcome.Done, user: created }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)) }\n }\n }\n\n /** The source account, read fresh from the server rather than taken from a store or a form. */\n const readSourceUser = async (descriptor: AnyUserSystemDescriptor, id: IntegerId): Promise<AnzuUser | null> => {\n const { get } = resolveEnabledWrite(descriptor)\n try {\n const { execute } = request<AnzuUser, null>(descriptor, 'GET', get)\n return await execute({ urlParams: { id } })\n } catch {\n return null\n }\n }\n\n return {\n setEnabled,\n writeMetadata,\n createInSystem,\n readSourceUser,\n }\n}\n"],"mappings":";;;;;;;;AA2CA,IAAaA,KAAuB,MAC9BC,MAAW,OAAaC,EAAY,cACpCD,MAAW,MAAYC,EAAY,YACnCD,MAAW,MAAYC,EAAY,kBACnCD,MAAW,MAAYC,EAAY,WACnCD,MAAA,OAA+CA,MAAA,MAA2CC,EAAY,UACnGA,EAAY,aAGfC,KACJ,GACA,GACA,MAEAC,EAAoB;CAClB,QAAQC,EAAW;CACnB;CACA,QAAQA,EAAW;CACnB,QAAQA,EAAW;CACnB,aAAaC;AACf,CAAC,GAEUC,WA0HJ;CACL,mBA3GA,GACA,GACA,MACyB;EACzB,IAAM,EAAE,QAAK,WAAQC,EAAoBH,CAAU;EACnD,IAAI;GACF,IAAM,EAAE,SAASI,MAASN,EAAwBE,GAAY,OAAOK,CAAG,GAClEC,IAAU,MAAMF,EAAK,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;GAChD,IAAIE,EAAQ,YAAYC,GAEtB,OAAO;IAAE,SAASV,EAAY;IAAM,MAAMS;GAAQ;GAGpD,IAAI,CAACE,EAAmBR,GAAY,QAAQ,GAAG,OAAO,EAAE,SAASH,EAAY,UAAU;GACvF,IAAMY,IAAOC,EAAUJ,CAAO;GAC9B,EAAK,UAAUC;GACf,IAAM,EAAE,SAASI,MAAUb,EAA4BE,GAAY,OAAOC,CAAG,GACvEW,IAAQ,MAAMD,EAAM;IAAE,WAAW,EAAE,MAAG;IAAG;GAAK,CAAC;GACrD,OAAO;IAAE,SAASd,EAAY;IAAM,MAAMe;GAAM;EAClD,SAASC,GAAO;GACd,OAAO,EAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC,EAAE;EACrE;CACF;CAsFE,sBAvEA,GACA,GACA,GACA,IAAuCE,GAEvC,IAAwB,SACwB;EAChD,IAAM,EAAE,WAAQ,QAAK,WAAQC,EAAqBhB,CAAU;EAC5D,IAAI;GACF,IAAM,EAAE,SAASI,MAASN,EAAwBE,GAAY,OAAOK,CAAG,GAGlEC,IAAU,MAAMF,EAAK,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;GAGhD,IAAI,CADYa,EAAO,MAAM,MAAUC,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBE,GAAQD,CAAK,CACvG,GAAS,OAAO;IAAE,SAAStB,EAAY;IAAM,MAAMS;IAAS,SAAS;GAAM;GAKhF,IAAMe,IAAmBC,EAAOC,CAAI,IAChC,CAAC,IACDN,EAAO,QACJ,MACCC,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBK,GAAMJ,CAAK,KACnED,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBE,GAAQD,CAAK,CACzE;GAGJ,IAAI,CAACX,EAAmBR,GAAY,QAAQ,GAAG,OAAO;IAAE,SAASH,EAAY;IAAW,SAAS;GAAM;GACvG,IAAMY,IAAOC,EAAUJ,CAAO;GAC9B,EAAO,SAAS,MAAUkB,EAAmBf,GAAMU,GAAOD,EAAkBE,GAAQD,CAAK,CAAC,CAAC;GAE3F,IAAM,EAAE,SAASR,MAAUb,EAA4BE,GAAYyB,GAAQxB,CAAG,GACxEW,IAAQ,MAAMD,EAAM;IAAE,WAAW,EAAE,MAAG;IAAG;GAAK,CAAC;GACrD,OAAO;IAAE,SAASd,EAAY;IAAM,MAAMe;IAAO,SAAS;IAAM;GAAiB;EACnF,SAASC,GAAO;GACd,OAAO;IAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC;IAAG,SAAS;GAAM;EACrF;CACF;CAiCE,uBAxB4B,GAAqC,MAAyC;EAC1G,IAAI;GACF,IAAM,EAAE,eAAYf,EAA4BE,GAAY,QAAQ0B,EAAsB1B,CAAU,CAAC,GAC/F2B,IAAU,MAAMC,EAAQ,EAAE,QAAK,CAAC;GACtC,OAAO;IAAE,SAAS/B,EAAY;IAAM,MAAM8B;GAAQ;EACpD,SAASd,GAAO;GACd,OAAO,EAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC,EAAE;EACrE;CACF;CAiBE,uBAd4B,GAAqC,MAA4C;EAC7G,IAAM,EAAE,WAAQV,EAAoBH,CAAU;EAC9C,IAAI;GACF,IAAM,EAAE,eAAYF,EAAwBE,GAAY,OAAOK,CAAG;GAClE,OAAO,MAAMuB,EAAQ,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;EAC5C,QAAQ;GACN,OAAO;EACT;CACF;AAOA"}
|
|
1
|
+
{"version":3,"file":"userCrossSystemWrites.js","names":["classifyWriteStatus","status","BulkOutcome","request","useApiRequest","descriptor","url","useUserCrossSystemWrites","resolveEnabledWrite","read","get","current","enabled","descriptorMayWrite","body","cloneDeep","write","saved","error","probeStatusFromError","USER_METADATA_FIELDS","resolveMetadataWrite","fields","readMetadataField","field","target","concurrentFields","isNull","seen","writeMetadataField","method","resolveCreateEndpoint","created","execute"],"sources":["../../../../src/domains/anzuUser/composables/userCrossSystemWrites.ts"],"sourcesContent":["import { useApiRequest } from '@/domains/api/composables/useApiRequest'\nimport { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_UNPROCESSABLE_ENTITY } from '@/shared/statusCodes'\nimport {\n type AnyUserSystemDescriptor,\n descriptorMayWrite,\n resolveCreateEndpoint,\n resolveEnabledWrite,\n resolveMetadataWrite,\n} from '@/domains/anzuUser/composables/userSystemDescriptor'\nimport { BulkOutcome, type BulkOutcomeType } from '@/domains/anzuUser/store/userCrossSystemStore'\nimport { probeStatusFromError } from '@/domains/anzuUser/composables/userSystemProbe'\nimport {\n readMetadataField,\n USER_METADATA_FIELDS,\n writeMetadataField,\n type UserMetadataField,\n} from '@/domains/anzuUser/utils/userMetadataDiff'\nimport type { AnzuUser, BaseUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId } from '@/shared/types/common'\nimport { cloneDeep, isNull } from '@/shared/utils/common'\n\nexport interface WriteResult {\n outcome: BulkOutcomeType\n /** The server's record after the write, when it returned one. */\n user?: AnzuUser\n /**\n * Fields whose stored value differed from both the target and what the search saw.\n * The write still goes through (decision 24: the operator's value wins). The log reports the concurrent edit.\n */\n concurrentFields?: UserMetadataField[]\n detail?: string\n}\n\n/**\n * 422 and 400 get their own outcome. A PUT validates the whole body.\n * Legacy data that no longer validates fails even a plain disable. That is not a bug.\n */\nexport const classifyWriteStatus = (status: number | null): BulkOutcomeType => {\n if (status === null) return BulkOutcome.Unavailable\n if (status === 403) return BulkOutcome.Forbidden\n if (status === 401) return BulkOutcome.Unauthenticated\n if (status === 404) return BulkOutcome.NotFound\n if (status === HTTP_STATUS_UNPROCESSABLE_ENTITY || status === HTTP_STATUS_BAD_REQUEST) return BulkOutcome.Invalid\n return BulkOutcome.Unavailable\n}\n\nconst request = <R extends object, B>(\n descriptor: AnyUserSystemDescriptor,\n method: 'GET' | 'PUT' | 'PATCH' | 'POST',\n url: string\n) =>\n useApiRequest<R, B>({\n client: descriptor.client,\n method,\n system: descriptor.system,\n entity: descriptor.entity,\n urlTemplate: url,\n })\n\nexport const useUserCrossSystemWrites = () => {\n /**\n * No PATCH exists for `enabled`. Only the full update calls `setEnabled`,\n * so this is a GET then PUT on the same path with the whole record.\n * The DTO defaults roles to `[ROLE_USER]`, `enabled` to true and permissions to empty. A\n * partial body resets roles, wipes grants, detaches groups and re-enables the account.\n * In cms `/adm/users` PUT runs `updateRelations()`, so an omitted `desks` removes the user from every desk.\n */\n const setEnabled = async (\n descriptor: AnyUserSystemDescriptor,\n id: IntegerId,\n enabled: boolean\n ): Promise<WriteResult> => {\n const { get, url } = resolveEnabledWrite(descriptor)\n try {\n const { execute: read } = request<AnzuUser, null>(descriptor, 'GET', get)\n const current = await read({ urlParams: { id } })\n if (current.enabled === enabled) {\n // Already in the target state. A no-op PUT would still run `updateRelations()` in cms.\n return { outcome: BulkOutcome.Done, user: current }\n }\n // The right may have been revoked during the read. Report it as the server would refuse it.\n if (!descriptorMayWrite(descriptor, 'update')) return { outcome: BulkOutcome.Forbidden }\n const body = cloneDeep(current)\n body.enabled = enabled\n const { execute: write } = request<AnzuUser, AnzuUser>(descriptor, 'PUT', url)\n const saved = await write({ urlParams: { id }, body })\n return { outcome: BulkOutcome.Done, user: saved }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)) }\n }\n }\n\n /**\n * Uses `PATCH /adm/users/{id}` where it exists. Its method\n * has no setters for roles, permissions, groups or `enabled`.\n * The body is still the whole record from the read. It must include `id`:\n * without it the uniqueness validator reports the user's own e-mail as taken.\n */\n const writeMetadata = async (\n descriptor: AnyUserSystemDescriptor,\n id: IntegerId,\n target: BaseUser,\n fields: readonly UserMetadataField[] = USER_METADATA_FIELDS,\n /** What the search showed for this system, to detect a change made in between. */\n seen: BaseUser | null = null\n ): Promise<WriteResult & { changed: boolean }> => {\n const { method, get, url } = resolveMetadataWrite(descriptor)\n try {\n const { execute: read } = request<AnzuUser, null>(descriptor, 'GET', get)\n // Read again right before writing. Search results can be hours\n // old, and a system that already matches must not be written.\n const current = await read({ urlParams: { id } })\n\n const differs = fields.some((field) => readMetadataField(current, field) !== readMetadataField(target, field))\n if (!differs) return { outcome: BulkOutcome.Done, user: current, changed: false }\n\n // Differs from both the target and what the operator saw: someone else wrote in between.\n // The value is still written, and the log names the fields.\n const concurrentFields = isNull(seen)\n ? []\n : fields.filter(\n (field) =>\n readMetadataField(current, field) !== readMetadataField(seen, field) &&\n readMetadataField(current, field) !== readMetadataField(target, field)\n )\n\n // The right may have been revoked during the read. Report it as the server would refuse it.\n if (!descriptorMayWrite(descriptor, 'update')) return { outcome: BulkOutcome.Forbidden, changed: false }\n const body = cloneDeep(current)\n fields.forEach((field) => writeMetadataField(body, field, readMetadataField(target, field)))\n\n const { execute: write } = request<AnzuUser, AnzuUser>(descriptor, method, url)\n const saved = await write({ urlParams: { id }, body })\n return { outcome: BulkOutcome.Done, user: saved, changed: true, concurrentFields }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)), changed: false }\n }\n }\n\n /**\n * The body comes from the library factory (`roles: []`, `enabled: false`) with metadata copied over.\n * A hand-built body would let the backend default to `ROLE_USER`, a role nobody granted.\n */\n const createInSystem = async (descriptor: AnyUserSystemDescriptor, body: AnzuUser): Promise<WriteResult> => {\n try {\n const { execute } = request<AnzuUser, AnzuUser>(descriptor, 'POST', resolveCreateEndpoint(descriptor))\n const created = await execute({ body })\n return { outcome: BulkOutcome.Done, user: created }\n } catch (error) {\n return { outcome: classifyWriteStatus(probeStatusFromError(error)) }\n }\n }\n\n /** Reads the source account fresh from the server, not from a store or form. */\n const readSourceUser = async (descriptor: AnyUserSystemDescriptor, id: IntegerId): Promise<AnzuUser | null> => {\n const { get } = resolveEnabledWrite(descriptor)\n try {\n const { execute } = request<AnzuUser, null>(descriptor, 'GET', get)\n return await execute({ urlParams: { id } })\n } catch {\n return null\n }\n }\n\n return {\n setEnabled,\n writeMetadata,\n createInSystem,\n readSourceUser,\n }\n}\n"],"mappings":";;;;;;;;AAqCA,IAAaA,KAAuB,MAC9BC,MAAW,OAAaC,EAAY,cACpCD,MAAW,MAAYC,EAAY,YACnCD,MAAW,MAAYC,EAAY,kBACnCD,MAAW,MAAYC,EAAY,WACnCD,MAAA,OAA+CA,MAAA,MAA2CC,EAAY,UACnGA,EAAY,aAGfC,KACJ,GACA,GACA,MAEAC,EAAoB;CAClB,QAAQC,EAAW;CACnB;CACA,QAAQA,EAAW;CACnB,QAAQA,EAAW;CACnB,aAAaC;AACf,CAAC,GAEUC,WAyGJ;CACL,mBAjGA,GACA,GACA,MACyB;EACzB,IAAM,EAAE,QAAK,WAAQC,EAAoBH,CAAU;EACnD,IAAI;GACF,IAAM,EAAE,SAASI,MAASN,EAAwBE,GAAY,OAAOK,CAAG,GAClEC,IAAU,MAAMF,EAAK,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;GAChD,IAAIE,EAAQ,YAAYC,GAEtB,OAAO;IAAE,SAASV,EAAY;IAAM,MAAMS;GAAQ;GAGpD,IAAI,CAACE,EAAmBR,GAAY,QAAQ,GAAG,OAAO,EAAE,SAASH,EAAY,UAAU;GACvF,IAAMY,IAAOC,EAAUJ,CAAO;GAC9B,EAAK,UAAUC;GACf,IAAM,EAAE,SAASI,MAAUb,EAA4BE,GAAY,OAAOC,CAAG,GACvEW,IAAQ,MAAMD,EAAM;IAAE,WAAW,EAAE,MAAG;IAAG;GAAK,CAAC;GACrD,OAAO;IAAE,SAASd,EAAY;IAAM,MAAMe;GAAM;EAClD,SAASC,GAAO;GACd,OAAO,EAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC,EAAE;EACrE;CACF;CA4EE,sBAnEA,GACA,GACA,GACA,IAAuCE,GAEvC,IAAwB,SACwB;EAChD,IAAM,EAAE,WAAQ,QAAK,WAAQC,EAAqBhB,CAAU;EAC5D,IAAI;GACF,IAAM,EAAE,SAASI,MAASN,EAAwBE,GAAY,OAAOK,CAAG,GAGlEC,IAAU,MAAMF,EAAK,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;GAGhD,IAAI,CADYa,EAAO,MAAM,MAAUC,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBE,GAAQD,CAAK,CACvG,GAAS,OAAO;IAAE,SAAStB,EAAY;IAAM,MAAMS;IAAS,SAAS;GAAM;GAIhF,IAAMe,IAAmBC,EAAOC,CAAI,IAChC,CAAC,IACDN,EAAO,QACJ,MACCC,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBK,GAAMJ,CAAK,KACnED,EAAkBZ,GAASa,CAAK,MAAMD,EAAkBE,GAAQD,CAAK,CACzE;GAGJ,IAAI,CAACX,EAAmBR,GAAY,QAAQ,GAAG,OAAO;IAAE,SAASH,EAAY;IAAW,SAAS;GAAM;GACvG,IAAMY,IAAOC,EAAUJ,CAAO;GAC9B,EAAO,SAAS,MAAUkB,EAAmBf,GAAMU,GAAOD,EAAkBE,GAAQD,CAAK,CAAC,CAAC;GAE3F,IAAM,EAAE,SAASR,MAAUb,EAA4BE,GAAYyB,GAAQxB,CAAG,GACxEW,IAAQ,MAAMD,EAAM;IAAE,WAAW,EAAE,MAAG;IAAG;GAAK,CAAC;GACrD,OAAO;IAAE,SAASd,EAAY;IAAM,MAAMe;IAAO,SAAS;IAAM;GAAiB;EACnF,SAASC,GAAO;GACd,OAAO;IAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC;IAAG,SAAS;GAAM;EACrF;CACF;CA8BE,uBAxB4B,GAAqC,MAAyC;EAC1G,IAAI;GACF,IAAM,EAAE,eAAYf,EAA4BE,GAAY,QAAQ0B,EAAsB1B,CAAU,CAAC,GAC/F2B,IAAU,MAAMC,EAAQ,EAAE,QAAK,CAAC;GACtC,OAAO;IAAE,SAAS/B,EAAY;IAAM,MAAM8B;GAAQ;EACpD,SAASd,GAAO;GACd,OAAO,EAAE,SAASlB,EAAoBmB,EAAqBD,CAAK,CAAC,EAAE;EACrE;CACF;CAiBE,uBAd4B,GAAqC,MAA4C;EAC7G,IAAM,EAAE,WAAQV,EAAoBH,CAAU;EAC9C,IAAI;GACF,IAAM,EAAE,eAAYF,EAAwBE,GAAY,OAAOK,CAAG;GAClE,OAAO,MAAMuB,EAAQ,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;EAC5C,QAAQ;GACN,OAAO;EACT;CACF;AAOA"}
|
|
@@ -2,13 +2,11 @@ import { RouteLocationRaw } from 'vue-router';
|
|
|
2
2
|
import { AxiosClientFn } from '../../api/utils/client';
|
|
3
3
|
import { AnzuUser } from '../../../shared/types/AnzuUser';
|
|
4
4
|
/**
|
|
5
|
-
* A
|
|
6
|
-
*
|
|
7
|
-
* `settings.banned`. Both arrive with the record -- they are `#[Serialize]` on the entity -- so
|
|
8
|
-
* rendering one costs no extra call.
|
|
5
|
+
* A system state shown next to `enabled`. Today: blog's `status` and forum's `settings.banned`.
|
|
6
|
+
* Both are serialized on the entity, so rendering costs no extra call.
|
|
9
7
|
*/
|
|
10
8
|
export interface UserSystemExtraState {
|
|
11
|
-
/** "blogger", "commenter"
|
|
9
|
+
/** "blogger", "commenter". The app translates it; the library only prints it. */
|
|
12
10
|
label: string;
|
|
13
11
|
/** "active", "banned". */
|
|
14
12
|
value: string;
|
|
@@ -25,40 +23,28 @@ export interface BaseUserEndpointPair extends AnzuUserEndpointPair {
|
|
|
25
23
|
patch: string;
|
|
26
24
|
}
|
|
27
25
|
/**
|
|
28
|
-
* Paired GET
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* preceding GET on the *same path* returned. The two paths return different DTOs -- `/adm/users`
|
|
32
|
-
* in cms answers `CmsUserDto` and its PUT runs `updateRelations()` over seven scalars and twelve
|
|
33
|
-
* collections -- so a GET from one path and a PUT to the other silently drops whatever the other
|
|
34
|
-
* DTO carries.
|
|
26
|
+
* Paired GET and write paths. A write body is always the whole object the GET on the same path returned.
|
|
27
|
+
* The two paths return different DTOs. A GET from one and a PUT to the other
|
|
28
|
+
* silently drops fields, e.g. cms `CmsUserDto` with `updateRelations()`.
|
|
35
29
|
*/
|
|
36
30
|
export interface UserSystemEndpoints {
|
|
37
31
|
anzuUser: AnzuUserEndpointPair | null;
|
|
38
32
|
base: BaseUserEndpointPair | null;
|
|
39
33
|
permissionGroup: string;
|
|
40
|
-
/**
|
|
41
|
-
* Per system, not one constant. contentHub's is `/adm/users/current`, and the admins had this
|
|
42
|
-
* hard-coded as a single path shared by every backend.
|
|
43
|
-
*/
|
|
34
|
+
/** Per system. contentHub uses `/adm/users/current`. */
|
|
44
35
|
currentUser: string;
|
|
45
36
|
list: string;
|
|
46
37
|
/**
|
|
47
|
-
* Which pair the probe reads through.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* have no access". The rule is "the probe goes the way the write goes".
|
|
38
|
+
* Which pair the probe reads through. The probe follows the write path.
|
|
39
|
+
* In dam `GET /adm/v1/anzu-user/{id}` is ungated while `GET /adm/users/{id}`
|
|
40
|
+
* needs `DAM_USER_READ`, so only the second can show "no access".
|
|
51
41
|
*/
|
|
52
42
|
probe: 'anzuUser' | 'base';
|
|
53
43
|
}
|
|
54
44
|
/**
|
|
55
|
-
* Where "manage in X" leads. A callback
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* The return type is a discriminated union so the two cannot be confused in code either -- an
|
|
59
|
-
* internal target is pushed through the router, an external one is an `<a href>` opened in a new
|
|
60
|
-
* tab, and `href: null` is a configured-but-missing url, which renders disabled with a reason
|
|
61
|
-
* rather than as a dead button.
|
|
45
|
+
* Where "manage in X" leads. A callback because the descriptor does not know which row is drawn.
|
|
46
|
+
* Internal targets go through the router. External ones open in a new tab.
|
|
47
|
+
* `href: null` means a missing url and renders disabled with a reason.
|
|
62
48
|
*/
|
|
63
49
|
export type UserSystemManageTarget = {
|
|
64
50
|
kind: 'internal';
|
|
@@ -73,21 +59,19 @@ export interface UserSystemDescriptor<TSystem extends string = string, TUser ext
|
|
|
73
59
|
/** Reaches every `useApiRequest` built for this system; see `permissionGroupApi`. */
|
|
74
60
|
entity: string;
|
|
75
61
|
/**
|
|
76
|
-
* Whether the system is
|
|
77
|
-
*
|
|
78
|
-
* not the same thing. The value is app-specific (`envConfig[system].enabled`) and the library has
|
|
79
|
-
* no way to read it.
|
|
62
|
+
* Whether the system is enabled in this admin's config (`envConfig[system].enabled`).
|
|
63
|
+
* Mandatory because the disabled state must be shown. Omitting the system from the array is not the same.
|
|
80
64
|
*/
|
|
81
65
|
isEnabled: () => boolean;
|
|
82
66
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
67
|
+
* Validation profile. `false`: only e-mail is required. `true`: also
|
|
68
|
+
* first name, last name, full name, avatar text and avatar colour.
|
|
69
|
+
* Same for create and edit.
|
|
86
70
|
*/
|
|
87
71
|
requiredMetadata: boolean;
|
|
88
72
|
/**
|
|
89
|
-
* Whether the id is typed in. False only in cms, where the backend looks it up in SSO
|
|
90
|
-
*
|
|
73
|
+
* Whether the id is typed in. False only in cms, where the backend looks it up in SSO by e-mail.
|
|
74
|
+
* Read-only on edit regardless.
|
|
91
75
|
*/
|
|
92
76
|
idInput: boolean;
|
|
93
77
|
extraState?: (user: TUser) => UserSystemExtraState | null;
|
|
@@ -98,42 +82,34 @@ export interface UserSystemDescriptor<TSystem extends string = string, TUser ext
|
|
|
98
82
|
/** In the confirmation dialog when an account is created here. */
|
|
99
83
|
createNote?: string;
|
|
100
84
|
endpoints: UserSystemEndpoints;
|
|
101
|
-
/**
|
|
85
|
+
/** The system's name as the app translates it. */
|
|
102
86
|
label?: string;
|
|
103
|
-
/** Added in task 2. */
|
|
104
87
|
manage?: (user: TUser) => UserSystemManageTarget;
|
|
105
88
|
/**
|
|
106
|
-
* Whether the current user may write this system's accounts. `false`
|
|
107
|
-
* disable, manage and the
|
|
108
|
-
*
|
|
109
|
-
*
|
|
89
|
+
* Whether the current user may write this system's accounts. `false`
|
|
90
|
+
* removes create, enable/disable, manage and the bulk action part.
|
|
91
|
+
* `undefined` or no function leaves it to the probe and the
|
|
92
|
+
* backend. Only the admin knows the other systems' current users.
|
|
110
93
|
*/
|
|
111
94
|
canWrite?: (action: UserSystemWriteAction) => boolean | undefined;
|
|
112
95
|
}
|
|
113
96
|
export type UserSystemWriteAction = 'create' | 'update';
|
|
114
97
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* Descriptors differ in `TUser` -- blog's `extraState` reaches for `status`, forum's for
|
|
118
|
-
* `settings.banned` -- so an array of them cannot keep each one's type. Without a single place to
|
|
119
|
-
* erase it, `strict: true` would demand a cast in every admin, at every call site. This does it
|
|
120
|
-
* once, where the array is built.
|
|
98
|
+
* Type erasure point for the heterogeneous descriptor array.
|
|
99
|
+
* Descriptors differ in `TUser`. Erasing here avoids a cast at every call site under `strict: true`.
|
|
121
100
|
*/
|
|
122
101
|
export type AnyUserSystemDescriptor = UserSystemDescriptor<string, AnzuUser>;
|
|
123
102
|
export declare const defineUserSystemDescriptor: <TSystem extends string, TUser extends AnzuUser>(descriptor: UserSystemDescriptor<TSystem, TUser>) => AnyUserSystemDescriptor;
|
|
124
103
|
/** False only when the descriptor says no. Not knowing is not a no. */
|
|
125
104
|
export declare const descriptorMayWrite: (descriptor: AnyUserSystemDescriptor, action: UserSystemWriteAction) => boolean;
|
|
126
105
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* has no `/adm/users`. Every admin's descriptor test asserts this resolves for each of its
|
|
130
|
-
* systems.
|
|
106
|
+
* Both `endpoints` branches are nullable, so `probe: 'base'` may name a system without `/adm/users`.
|
|
107
|
+
* Each admin's descriptor test asserts this resolves for every system.
|
|
131
108
|
*/
|
|
132
109
|
export declare const resolveProbeEndpoint: (descriptor: AnyUserSystemDescriptor) => AnzuUserEndpointPair;
|
|
133
110
|
/**
|
|
134
|
-
* Metadata
|
|
135
|
-
*
|
|
136
|
-
* groups or `enabled`. That is a stronger guarantee than being careful about what goes in the body.
|
|
111
|
+
* Metadata goes through `PATCH /adm/users/{id}` where it exists.
|
|
112
|
+
* Its method has no setters for roles, permissions, groups or `enabled`.
|
|
137
113
|
*/
|
|
138
114
|
export declare const resolveMetadataWrite: (descriptor: AnyUserSystemDescriptor) => {
|
|
139
115
|
method: "PATCH";
|
|
@@ -145,8 +121,8 @@ export declare const resolveMetadataWrite: (descriptor: AnyUserSystemDescriptor)
|
|
|
145
121
|
url: string;
|
|
146
122
|
};
|
|
147
123
|
/**
|
|
148
|
-
* `enabled` has no
|
|
149
|
-
* So it
|
|
124
|
+
* `enabled` has no PATCH. Only the full update calls `setEnabled`.
|
|
125
|
+
* So it is GET then PUT on the same path with the whole DTO from the GET.
|
|
150
126
|
*/
|
|
151
127
|
export declare const resolveEnabledWrite: (descriptor: AnyUserSystemDescriptor) => {
|
|
152
128
|
get: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userSystemDescriptor.js","names":["defineUserSystemDescriptor","descriptor","descriptorMayWrite","action","resolveProbeEndpoint","pair","resolveMetadataWrite","base","anzuUser","resolveEnabledWrite","resolveCreateEndpoint"],"sources":["../../../../src/domains/anzuUser/composables/userSystemDescriptor.ts"],"sourcesContent":["import type { RouteLocationRaw } from 'vue-router'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\n\n/**\n * A state a system has on top of `enabled`, shown next to it. Today only two systems have one:\n * blog's `status` (guest / waiting_approval / active / ban / gdpr_deleted) and forum's\n * `settings.banned`. Both arrive with the record -- they are `#[Serialize]` on the entity -- so\n * rendering one costs no extra call.\n */\nexport interface UserSystemExtraState {\n /** \"blogger\", \"commenter\" -- the app translates it; the library only prints it. */\n label: string\n /** \"active\", \"banned\". */\n value: string\n tone: 'ok' | 'warn' | 'error'\n}\n\n/** `/adm/v1/anzu-user`. Absent in contentHub, which has only `/adm/users`. */\nexport interface AnzuUserEndpointPair {\n get: string\n put: string\n post: string\n}\n\n/** `/adm/users`. Only cms, dam and contentHub have it; it is the only path with a `PATCH`. */\nexport interface BaseUserEndpointPair extends AnzuUserEndpointPair {\n patch: string\n}\n\n/**\n * Paired GET + write paths, never loose urls.\n *\n * This is what makes the write invariant expressible: a write body is always the whole object the\n * preceding GET on the *same path* returned. The two paths return different DTOs -- `/adm/users`\n * in cms answers `CmsUserDto` and its PUT runs `updateRelations()` over seven scalars and twelve\n * collections -- so a GET from one path and a PUT to the other silently drops whatever the other\n * DTO carries.\n */\nexport interface UserSystemEndpoints {\n anzuUser: AnzuUserEndpointPair | null\n base: BaseUserEndpointPair | null\n permissionGroup: string\n /**\n * Per system, not one constant. contentHub's is `/adm/users/current`, and the admins had this\n * hard-coded as a single path shared by every backend.\n */\n currentUser: string\n list: string\n /**\n * Which pair the probe reads through. A field rather than something derived, because in dam the\n * choice is visible to the operator: `GET /adm/v1/anzu-user/{id}` has no gating at all while\n * `GET /adm/users/{id}` sits behind `DAM_USER_READ`, so only the second can ever render \"you\n * have no access\". The rule is \"the probe goes the way the write goes\".\n */\n probe: 'anzuUser' | 'base'\n}\n\n/**\n * Where \"manage in X\" leads. A callback over the user rather than a static value: a global\n * descriptor does not know which row is being drawn.\n *\n * The return type is a discriminated union so the two cannot be confused in code either -- an\n * internal target is pushed through the router, an external one is an `<a href>` opened in a new\n * tab, and `href: null` is a configured-but-missing url, which renders disabled with a reason\n * rather than as a dead button.\n */\nexport type UserSystemManageTarget =\n | { kind: 'internal'; to: RouteLocationRaw }\n | { kind: 'external'; href: string | null }\n\nexport interface UserSystemDescriptor<TSystem extends string = string, TUser extends AnzuUser = AnzuUser> {\n system: TSystem\n client: AxiosClientFn\n /** Reaches every `useApiRequest` built for this system; see `permissionGroupApi`. */\n entity: string\n /**\n * Whether the system is switched on in this admin's configuration. Mandatory, not optional: the\n * \"disabled in configuration\" state has to be *shown*, so leaving the system out of the array is\n * not the same thing. The value is app-specific (`envConfig[system].enabled`) and the library has\n * no way to read it.\n */\n isEnabled: () => boolean\n /**\n * Which validation profile this system's form uses. `false` means only the e-mail is required;\n * `true` adds first name, last name, full name, avatar text and avatar colour. It is a property\n * of the system, and it is the same for creating and for editing.\n */\n requiredMetadata: boolean\n /**\n * Whether the id is typed in. False only in cms, where the backend looks it up in SSO from the\n * e-mail. On an edit the field is read-only regardless.\n */\n idInput: boolean\n extraState?: (user: TUser) => UserSystemExtraState | null\n /** Above the `enabled` switch and in the row of a bulk action. */\n enabledNote?: string\n /** In the metadata repair dialog and in the owning form. */\n metadataNote?: string\n /** In the confirmation dialog when an account is created here. */\n createNote?: string\n endpoints: UserSystemEndpoints\n /** Added in task 2: the system's name as the app translates it. */\n label?: string\n /** Added in task 2. */\n manage?: (user: TUser) => UserSystemManageTarget\n /**\n * Whether the current user may write this system's accounts. `false` takes away create, enable or\n * disable, manage and the system's part of a bulk action; `undefined`, or no function, leaves it to the\n * probe and the backend's answer, as before. Only the admin can say: the library has no current user of\n * another system, and only the admin knows which ones it has loaded.\n */\n canWrite?: (action: UserSystemWriteAction) => boolean | undefined\n}\n\nexport type UserSystemWriteAction = 'create' | 'update'\n\n/**\n * The erasure boundary for a heterogeneous array.\n *\n * Descriptors differ in `TUser` -- blog's `extraState` reaches for `status`, forum's for\n * `settings.banned` -- so an array of them cannot keep each one's type. Without a single place to\n * erase it, `strict: true` would demand a cast in every admin, at every call site. This does it\n * once, where the array is built.\n */\nexport type AnyUserSystemDescriptor = UserSystemDescriptor<string, AnzuUser>\n\nexport const defineUserSystemDescriptor = <TSystem extends string, TUser extends AnzuUser>(\n descriptor: UserSystemDescriptor<TSystem, TUser>\n): AnyUserSystemDescriptor => descriptor as unknown as AnyUserSystemDescriptor\n\n/** False only when the descriptor says no. Not knowing is not a no. */\nexport const descriptorMayWrite = (descriptor: AnyUserSystemDescriptor, action: UserSystemWriteAction): boolean =>\n descriptor.canWrite?.(action) !== false\n\n/**\n * The pair the probe reads through, with the one invariant the type cannot state: both branches of\n * `endpoints` are nullable, so nothing stops a descriptor naming `probe: 'base'` on a system that\n * has no `/adm/users`. Every admin's descriptor test asserts this resolves for each of its\n * systems.\n */\nexport const resolveProbeEndpoint = (descriptor: AnyUserSystemDescriptor): AnzuUserEndpointPair => {\n const pair = descriptor.endpoints[descriptor.endpoints.probe]\n if (pair === null) {\n throw new Error(\n `[userSystemDescriptor] '${descriptor.system}' names probe '${descriptor.endpoints.probe}', which it does not have.`\n )\n }\n return pair\n}\n\n/**\n * Metadata is written through `PATCH /adm/users/{id}` wherever that path exists: the method behind\n * it can only write e-mail, locale, avatar and person -- it has no setter for roles, permissions,\n * groups or `enabled`. That is a stronger guarantee than being careful about what goes in the body.\n */\nexport const resolveMetadataWrite = (\n descriptor: AnyUserSystemDescriptor\n): { method: 'PATCH'; get: string; url: string } | { method: 'PUT'; get: string; url: string } => {\n const base = descriptor.endpoints.base\n if (base !== null) return { method: 'PATCH', get: base.get, url: base.patch }\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has neither write path.`)\n }\n return { method: 'PUT', get: anzuUser.get, url: anzuUser.put }\n}\n\n/**\n * `enabled` has no `PATCH` anywhere: the only method that calls `setEnabled` is the full update.\n * So it goes GET + PUT, on the same path, with the whole DTO the GET returned.\n */\nexport const resolveEnabledWrite = (descriptor: AnyUserSystemDescriptor): { get: string; url: string } => {\n const base = descriptor.endpoints.base\n if (base !== null) return { get: base.get, url: base.put }\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has neither write path.`)\n }\n return { get: anzuUser.get, url: anzuUser.put }\n}\n\n/** Creating an account goes the same way a write does. */\nexport const resolveCreateEndpoint = (descriptor: AnyUserSystemDescriptor): string => {\n const base = descriptor.endpoints.base\n if (base !== null) return base.post\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has no create path.`)\n }\n return anzuUser.post\n}\n"],"mappings":";AA+HA,IAAaA,KACX,MAC4BC,GAGjBC,KAAsB,GAAqC,MACtED,EAAW,WAAWE,CAAM,MAAM,IAQvBC,KAAwB,MAA8D;CACjG,IAAMC,IAAOJ,EAAW,UAAUA,EAAW,UAAU;CACvD,IAAII,MAAS,MACX,MAAU,MACR,2BAA2BJ,EAAW,OAAO,iBAAiBA,EAAW,UAAU,MAAM,2BAC3F;CAEF,OAAOI;AACT,GAOaC,KACX,MACgG;CAChG,IAAMC,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAO;EAAE,QAAQ;EAAS,KAAKA,EAAK;EAAK,KAAKA,EAAK;CAAM;CAC5E,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,0BAA0B;CAEzF,OAAO;EAAE,QAAQ;EAAO,KAAKO,EAAS;EAAK,KAAKA,EAAS;CAAI;AAC/D,GAMaC,KAAuB,MAAsE;CACxG,IAAMF,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAO;EAAE,KAAKA,EAAK;EAAK,KAAKA,EAAK;CAAI;CACzD,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,0BAA0B;CAEzF,OAAO;EAAE,KAAKO,EAAS;EAAK,KAAKA,EAAS;CAAI;AAChD,GAGaE,KAAyB,MAAgD;CACpF,IAAMH,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAOA,EAAK;CAC/B,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,sBAAsB;CAErF,OAAOO,EAAS;AAClB"}
|
|
1
|
+
{"version":3,"file":"userSystemDescriptor.js","names":["defineUserSystemDescriptor","descriptor","descriptorMayWrite","action","resolveProbeEndpoint","pair","resolveMetadataWrite","base","anzuUser","resolveEnabledWrite","resolveCreateEndpoint"],"sources":["../../../../src/domains/anzuUser/composables/userSystemDescriptor.ts"],"sourcesContent":["import type { RouteLocationRaw } from 'vue-router'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\n\n/**\n * A system state shown next to `enabled`. Today: blog's `status` and forum's `settings.banned`.\n * Both are serialized on the entity, so rendering costs no extra call.\n */\nexport interface UserSystemExtraState {\n /** \"blogger\", \"commenter\". The app translates it; the library only prints it. */\n label: string\n /** \"active\", \"banned\". */\n value: string\n tone: 'ok' | 'warn' | 'error'\n}\n\n/** `/adm/v1/anzu-user`. Absent in contentHub, which has only `/adm/users`. */\nexport interface AnzuUserEndpointPair {\n get: string\n put: string\n post: string\n}\n\n/** `/adm/users`. Only cms, dam and contentHub have it; it is the only path with a `PATCH`. */\nexport interface BaseUserEndpointPair extends AnzuUserEndpointPair {\n patch: string\n}\n\n/**\n * Paired GET and write paths. A write body is always the whole object the GET on the same path returned.\n * The two paths return different DTOs. A GET from one and a PUT to the other\n * silently drops fields, e.g. cms `CmsUserDto` with `updateRelations()`.\n */\nexport interface UserSystemEndpoints {\n anzuUser: AnzuUserEndpointPair | null\n base: BaseUserEndpointPair | null\n permissionGroup: string\n /** Per system. contentHub uses `/adm/users/current`. */\n currentUser: string\n list: string\n /**\n * Which pair the probe reads through. The probe follows the write path.\n * In dam `GET /adm/v1/anzu-user/{id}` is ungated while `GET /adm/users/{id}`\n * needs `DAM_USER_READ`, so only the second can show \"no access\".\n */\n probe: 'anzuUser' | 'base'\n}\n\n/**\n * Where \"manage in X\" leads. A callback because the descriptor does not know which row is drawn.\n * Internal targets go through the router. External ones open in a new tab.\n * `href: null` means a missing url and renders disabled with a reason.\n */\nexport type UserSystemManageTarget =\n | { kind: 'internal'; to: RouteLocationRaw }\n | { kind: 'external'; href: string | null }\n\nexport interface UserSystemDescriptor<TSystem extends string = string, TUser extends AnzuUser = AnzuUser> {\n system: TSystem\n client: AxiosClientFn\n /** Reaches every `useApiRequest` built for this system; see `permissionGroupApi`. */\n entity: string\n /**\n * Whether the system is enabled in this admin's config (`envConfig[system].enabled`).\n * Mandatory because the disabled state must be shown. Omitting the system from the array is not the same.\n */\n isEnabled: () => boolean\n /**\n * Validation profile. `false`: only e-mail is required. `true`: also\n * first name, last name, full name, avatar text and avatar colour.\n * Same for create and edit.\n */\n requiredMetadata: boolean\n /**\n * Whether the id is typed in. False only in cms, where the backend looks it up in SSO by e-mail.\n * Read-only on edit regardless.\n */\n idInput: boolean\n extraState?: (user: TUser) => UserSystemExtraState | null\n /** Above the `enabled` switch and in the row of a bulk action. */\n enabledNote?: string\n /** In the metadata repair dialog and in the owning form. */\n metadataNote?: string\n /** In the confirmation dialog when an account is created here. */\n createNote?: string\n endpoints: UserSystemEndpoints\n /** The system's name as the app translates it. */\n label?: string\n manage?: (user: TUser) => UserSystemManageTarget\n /**\n * Whether the current user may write this system's accounts. `false`\n * removes create, enable/disable, manage and the bulk action part.\n * `undefined` or no function leaves it to the probe and the\n * backend. Only the admin knows the other systems' current users.\n */\n canWrite?: (action: UserSystemWriteAction) => boolean | undefined\n}\n\nexport type UserSystemWriteAction = 'create' | 'update'\n\n/**\n * Type erasure point for the heterogeneous descriptor array.\n * Descriptors differ in `TUser`. Erasing here avoids a cast at every call site under `strict: true`.\n */\nexport type AnyUserSystemDescriptor = UserSystemDescriptor<string, AnzuUser>\n\nexport const defineUserSystemDescriptor = <TSystem extends string, TUser extends AnzuUser>(\n descriptor: UserSystemDescriptor<TSystem, TUser>\n): AnyUserSystemDescriptor => descriptor as unknown as AnyUserSystemDescriptor\n\n/** False only when the descriptor says no. Not knowing is not a no. */\nexport const descriptorMayWrite = (descriptor: AnyUserSystemDescriptor, action: UserSystemWriteAction): boolean =>\n descriptor.canWrite?.(action) !== false\n\n/**\n * Both `endpoints` branches are nullable, so `probe: 'base'` may name a system without `/adm/users`.\n * Each admin's descriptor test asserts this resolves for every system.\n */\nexport const resolveProbeEndpoint = (descriptor: AnyUserSystemDescriptor): AnzuUserEndpointPair => {\n const pair = descriptor.endpoints[descriptor.endpoints.probe]\n if (pair === null) {\n throw new Error(\n `[userSystemDescriptor] '${descriptor.system}' names probe '${descriptor.endpoints.probe}', which it does not have.`\n )\n }\n return pair\n}\n\n/**\n * Metadata goes through `PATCH /adm/users/{id}` where it exists.\n * Its method has no setters for roles, permissions, groups or `enabled`.\n */\nexport const resolveMetadataWrite = (\n descriptor: AnyUserSystemDescriptor\n): { method: 'PATCH'; get: string; url: string } | { method: 'PUT'; get: string; url: string } => {\n const base = descriptor.endpoints.base\n if (base !== null) return { method: 'PATCH', get: base.get, url: base.patch }\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has neither write path.`)\n }\n return { method: 'PUT', get: anzuUser.get, url: anzuUser.put }\n}\n\n/**\n * `enabled` has no PATCH. Only the full update calls `setEnabled`.\n * So it is GET then PUT on the same path with the whole DTO from the GET.\n */\nexport const resolveEnabledWrite = (descriptor: AnyUserSystemDescriptor): { get: string; url: string } => {\n const base = descriptor.endpoints.base\n if (base !== null) return { get: base.get, url: base.put }\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has neither write path.`)\n }\n return { get: anzuUser.get, url: anzuUser.put }\n}\n\n/** Creating an account goes the same way a write does. */\nexport const resolveCreateEndpoint = (descriptor: AnyUserSystemDescriptor): string => {\n const base = descriptor.endpoints.base\n if (base !== null) return base.post\n const anzuUser = descriptor.endpoints.anzuUser\n if (anzuUser === null) {\n throw new Error(`[userSystemDescriptor] '${descriptor.system}' has no create path.`)\n }\n return anzuUser.post\n}\n"],"mappings":";AA0GA,IAAaA,KACX,MAC4BC,GAGjBC,KAAsB,GAAqC,MACtED,EAAW,WAAWE,CAAM,MAAM,IAMvBC,KAAwB,MAA8D;CACjG,IAAMC,IAAOJ,EAAW,UAAUA,EAAW,UAAU;CACvD,IAAII,MAAS,MACX,MAAU,MACR,2BAA2BJ,EAAW,OAAO,iBAAiBA,EAAW,UAAU,MAAM,2BAC3F;CAEF,OAAOI;AACT,GAMaC,KACX,MACgG;CAChG,IAAMC,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAO;EAAE,QAAQ;EAAS,KAAKA,EAAK;EAAK,KAAKA,EAAK;CAAM;CAC5E,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,0BAA0B;CAEzF,OAAO;EAAE,QAAQ;EAAO,KAAKO,EAAS;EAAK,KAAKA,EAAS;CAAI;AAC/D,GAMaC,KAAuB,MAAsE;CACxG,IAAMF,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAO;EAAE,KAAKA,EAAK;EAAK,KAAKA,EAAK;CAAI;CACzD,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,0BAA0B;CAEzF,OAAO;EAAE,KAAKO,EAAS;EAAK,KAAKA,EAAS;CAAI;AAChD,GAGaE,KAAyB,MAAgD;CACpF,IAAMH,IAAON,EAAW,UAAU;CAClC,IAAIM,MAAS,MAAM,OAAOA,EAAK;CAC/B,IAAMC,IAAWP,EAAW,UAAU;CACtC,IAAIO,MAAa,MACf,MAAU,MAAM,2BAA2BP,EAAW,OAAO,sBAAsB;CAErF,OAAOO,EAAS;AAClB"}
|
|
@@ -5,29 +5,16 @@ import { UserSystemAxes } from '../utils/userSystemState';
|
|
|
5
5
|
import { AnzuUser } from '../../../shared/types/AnzuUser';
|
|
6
6
|
import { IntegerId } from '../../../shared/types/common';
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* The probe cannot do this itself: a first 401 is ambiguous -- expired session or no account --
|
|
11
|
-
* and the only way to tell them apart is to refresh and ask again, with the session this admin
|
|
12
|
-
* refreshes (its `createRefreshSession`, shared with its refresh interceptor). Without this hook a
|
|
13
|
-
* panel would show an expired token as "no account here", which is exactly the confusion decision
|
|
14
|
-
* 16 forbids.
|
|
15
|
-
*
|
|
16
|
-
* Returns true when the refresh succeeded and the call is worth repeating.
|
|
8
|
+
* Refreshes a system's session; returns true when the call is worth retrying.
|
|
9
|
+
* A first 401 may be an expired session or no account. Only a refresh and retry tells them apart (decision 16).
|
|
17
10
|
*/
|
|
18
11
|
export type UserSystemRefreshHook = (system: string) => Promise<boolean>;
|
|
19
12
|
export { USER_PROBE_ENTITY };
|
|
20
13
|
export declare const UserSystemRefreshHookKey: InjectionKey<UserSystemRefreshHook>;
|
|
21
14
|
/**
|
|
22
|
-
* The
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* alone misses exactly the answers that exist *because* the backend replied with a body: a
|
|
26
|
-
* validation failure is `AnzuApiValidationError`, a dependency conflict is
|
|
27
|
-
* `AnzuApiDependencyExistsError`, and both are 422s that have to be reported as such. Reported as
|
|
28
|
-
* "the system did not answer" they would send the operator looking for an outage instead of at the
|
|
29
|
-
* account whose stored data no longer validates -- which, with legacy rows, is the failure that
|
|
30
|
-
* happens most.
|
|
15
|
+
* The backend status, or null when nothing answered.
|
|
16
|
+
* Read from the axios cause, not the error class. `AnzuApiValidationError`
|
|
17
|
+
* and `AnzuApiDependencyExistsError` are 422s and must be reported as such.
|
|
31
18
|
*/
|
|
32
19
|
export declare const probeStatusFromError: (error: unknown) => number | null;
|
|
33
20
|
export interface UserSystemProbeResult {
|
|
@@ -43,14 +30,7 @@ export interface UserSystemProbeParams {
|
|
|
43
30
|
refreshHook?: UserSystemRefreshHook | undefined;
|
|
44
31
|
}
|
|
45
32
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* Reads through `endpoints[probe].get`, never a hard-coded path: in dam the choice is visible to
|
|
49
|
-
* the operator, because `/adm/v1/anzu-user/{id}` has no gating there while `/adm/users/{id}` sits
|
|
50
|
-
* behind `DAM_USER_READ` -- only the second can ever render "you have no access".
|
|
51
|
-
*
|
|
52
|
-
* Note for the app: a probe answering 404 is an expected result here, not a failure. The default
|
|
53
|
-
* api error logger skips it; a logger of the app's own still receives it and should filter on
|
|
54
|
-
* `status === 404 && entity === USER_PROBE_ENTITY`, or every absent account writes a line into the log.
|
|
33
|
+
* Reads through `endpoints[probe].get`, never a hard-coded path (dam gates only `/adm/users/{id}`).
|
|
34
|
+
* A 404 here is expected. A custom app error logger should skip `status === 404 && entity === USER_PROBE_ENTITY`.
|
|
55
35
|
*/
|
|
56
36
|
export declare const useUserSystemProbe: (params: UserSystemProbeParams) => UserSystemProbeResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userSystemProbe.js","names":["axios","UserSystemRefreshHookKey","probeStatusFromError","error","AnzuApiResponseCodeError","AnzuApiForbiddenError","AnzuApiAxiosError","cause","useUserSystemProbe","params","axes","ref","emptyUserSystemAxes","user","generation","abortInFlight","descriptor","UserSystemLoad","UserSystemPresence","UserSystemAccess","token","endpoint","resolveProbeEndpoint","ask","useApiRequest","USER_PROBE_ENTITY","abort","execute","found","AnzuApiCancelledError","status","refreshHook","refreshed","retryError","classifyProbeStatus"],"sources":["../../../../src/domains/anzuUser/composables/userSystemProbe.ts"],"sourcesContent":["import { ref, type InjectionKey, type Ref } from 'vue'\nimport axios from 'axios'\nimport { AnzuApiAxiosError } from '@/shared/error/AnzuApiAxiosError'\nimport { AnzuApiCancelledError } from '@/shared/error/AnzuApiCancelledError'\nimport { AnzuApiForbiddenError } from '@/shared/error/AnzuApiForbiddenError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { HTTP_STATUS_FORBIDDEN, HTTP_STATUS_UNAUTHORIZED } from '@/shared/statusCodes'\nimport { USER_PROBE_ENTITY } from '@/domains/api/utils/apiErrors'\nimport { useApiRequest } from '@/domains/api/composables/useApiRequest'\nimport { type AnyUserSystemDescriptor, resolveProbeEndpoint } from '@/domains/anzuUser/composables/userSystemDescriptor'\nimport {\n classifyProbeStatus,\n emptyUserSystemAxes,\n UserSystemAccess,\n UserSystemLoad,\n UserSystemPresence,\n type UserSystemAxes,\n} from '@/domains/anzuUser/utils/userSystemState'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId } from '@/shared/types/common'\n\n/**\n * How an app refreshes a session for one system, and retries.\n *\n * The probe cannot do this itself: a first 401 is ambiguous -- expired session or no account --\n * and the only way to tell them apart is to refresh and ask again, with the session this admin\n * refreshes (its `createRefreshSession`, shared with its refresh interceptor). Without this hook a\n * panel would show an expired token as \"no account here\", which is exactly the confusion decision\n * 16 forbids.\n *\n * Returns true when the refresh succeeded and the call is worth repeating.\n */\nexport type UserSystemRefreshHook = (system: string) => Promise<boolean>\n\nexport { USER_PROBE_ENTITY }\n\nexport const UserSystemRefreshHookKey: InjectionKey<UserSystemRefreshHook> = Symbol('UserSystemRefreshHook')\n\n/**\n * The status the backend answered with, or null when nothing ever answered.\n *\n * Read off the axios failure the mapped error kept as its cause, not off the class. Going by class\n * alone misses exactly the answers that exist *because* the backend replied with a body: a\n * validation failure is `AnzuApiValidationError`, a dependency conflict is\n * `AnzuApiDependencyExistsError`, and both are 422s that have to be reported as such. Reported as\n * \"the system did not answer\" they would send the operator looking for an outage instead of at the\n * account whose stored data no longer validates -- which, with legacy rows, is the failure that\n * happens most.\n */\nexport const probeStatusFromError = (error: unknown): number | null => {\n if (error instanceof AnzuApiResponseCodeError) return error.code\n if (error instanceof AnzuApiForbiddenError) return HTTP_STATUS_FORBIDDEN\n if (error instanceof AnzuApiAxiosError) return error.cause.response?.status ?? null\n const cause = (error as { cause?: unknown } | null)?.cause\n if (axios.isAxiosError(cause)) return cause.response?.status ?? null\n if (axios.isAxiosError(error)) return error.response?.status ?? null\n\n return null\n}\n\nexport interface UserSystemProbeResult {\n axes: Ref<UserSystemAxes>\n user: Ref<AnzuUser | null>\n probe: (id: IntegerId) => Promise<void>\n reset: () => void\n cancel: () => void\n}\n\nexport interface UserSystemProbeParams {\n descriptor: AnyUserSystemDescriptor\n /** Usually injected once per page; passing it explicitly is for tests and one-off panels. */\n refreshHook?: UserSystemRefreshHook | undefined\n}\n\n/**\n * One system's answer about one user.\n *\n * Reads through `endpoints[probe].get`, never a hard-coded path: in dam the choice is visible to\n * the operator, because `/adm/v1/anzu-user/{id}` has no gating there while `/adm/users/{id}` sits\n * behind `DAM_USER_READ` -- only the second can ever render \"you have no access\".\n *\n * Note for the app: a probe answering 404 is an expected result here, not a failure. The default\n * api error logger skips it; a logger of the app's own still receives it and should filter on\n * `status === 404 && entity === USER_PROBE_ENTITY`, or every absent account writes a line into the log.\n */\nexport const useUserSystemProbe = (params: UserSystemProbeParams): UserSystemProbeResult => {\n const { descriptor, refreshHook } = params\n\n const axes = ref<UserSystemAxes>(emptyUserSystemAxes())\n const user = ref<AnzuUser | null>(null)\n\n let generation = 0\n /**\n * The helper's abort handle for the request that is in flight.\n *\n * The generation token alone already stops a stale answer from being written; this is what stops\n * the request itself. Leaving a page mid-search would otherwise leave up to eighteen calls\n * running against backends nobody is waiting for any more.\n */\n let abortInFlight: (() => void) | null = null\n\n const reset = () => {\n axes.value = emptyUserSystemAxes()\n user.value = null\n }\n\n const cancel = () => {\n generation++\n abortInFlight?.()\n abortInFlight = null\n }\n\n const probe = async (id: IntegerId) => {\n // A system switched off in configuration is a state to show, not a call to make.\n if (!descriptor.isEnabled()) {\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Unknown,\n access: UserSystemAccess.ConfigDisabled,\n enabled: 'unknown',\n }\n user.value = null\n return\n }\n\n const token = ++generation\n axes.value = { ...axes.value, load: UserSystemLoad.Loading }\n\n const endpoint = resolveProbeEndpoint(descriptor)\n\n const ask = async () => {\n const { execute, abort } = useApiRequest<AnzuUser, null>({\n client: descriptor.client,\n method: 'GET',\n system: descriptor.system,\n entity: USER_PROBE_ENTITY,\n validationSystem: 'common',\n validationEntity: descriptor.entity,\n urlTemplate: endpoint.get,\n })\n abortInFlight = abort\n try {\n return await execute({ urlParams: { id } })\n } finally {\n abortInFlight = null\n }\n }\n\n try {\n const found = await ask()\n if (token !== generation) return\n user.value = found\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Present,\n access: UserSystemAccess.Ok,\n enabled: found.enabled,\n }\n } catch (error) {\n if (token !== generation) return\n if (error instanceof AnzuApiCancelledError) return\n\n let status = probeStatusFromError(error)\n\n // The one retry the classification depends on. Only after it has happened is a 401 a verdict\n // rather than a question.\n if (status === HTTP_STATUS_UNAUTHORIZED && refreshHook) {\n const refreshed = await refreshHook(descriptor.system).catch(() => false)\n if (token !== generation) return\n if (refreshed) {\n try {\n const found = await ask()\n if (token !== generation) return\n user.value = found\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Present,\n access: UserSystemAccess.Ok,\n enabled: found.enabled,\n }\n return\n } catch (retryError) {\n if (token !== generation) return\n status = probeStatusFromError(retryError)\n }\n }\n }\n\n user.value = null\n axes.value = {\n load: UserSystemLoad.Loaded,\n ...classifyProbeStatus(status),\n enabled: 'unknown',\n }\n }\n }\n\n return { axes, user, probe, reset, cancel }\n}\n"],"mappings":";;;;;;;;;;;;AAoCA,IAAaC,IAAgE,OAAO,uBAAuB,GAa9FC,KAAwB,MAAkC;CACrE,IAAIC,aAAiBC,GAA0B,OAAOD,EAAM;CAC5D,IAAIA,aAAiBE,GAAuB,OAAA;CAC5C,IAAIF,aAAiBG,GAAmB,OAAOH,EAAM,MAAM,UAAU,UAAU;CAC/E,IAAMI,IAASJ,GAAsC;CAIrD,OAHIH,EAAM,aAAaO,CAAK,IAAUA,EAAM,UAAU,UAAU,OAC5DP,EAAM,aAAaG,CAAK,IAAUA,EAAM,UAAU,UAAU,OAEzD;AACT,GA2BaK,KAAsB,MAAyD;CAC1F,IAAM,EAAE,eAAY,mBAAgBC,GAE9BC,IAAOC,EAAoBC,EAAoB,CAAC,GAChDC,IAAOF,EAAqB,IAAI,GAElCG,IAAa,GAQbC,IAAqC;CAkGzC,OAAO;EAAE;EAAM;EAAM,cArFA,MAAkB;GAErC,IAAI,CAACC,EAAW,UAAU,GAAG;IAO3B,AANA,EAAK,QAAQ;KACX,MAAMC,EAAe;KACrB,UAAUC,EAAmB;KAC7B,QAAQC,EAAiB;KACzB,SAAS;IACX,GACA,EAAK,QAAQ;IACb;GACF;GAEA,IAAMC,IAAQ,EAAEN;GAChB,EAAK,QAAQ;IAAE,GAAGJ,EAAK;IAAO,MAAMO,EAAe;GAAQ;GAE3D,IAAMI,IAAWC,EAAqBN,CAAU,GAE1CO,IAAM,YAAY;IACtB,IAAM,EAAE,YAAS,aAAUC,EAA8B;KACvD,QAAQR,EAAW;KACnB,QAAQ;KACR,QAAQA,EAAW;KACnB,QAAQS;KACR,kBAAkB;KAClB,kBAAkBT,EAAW;KAC7B,aAAaK,EAAS;IACxB,CAAC;IACD,IAAgBK;IAChB,IAAI;KACF,OAAO,MAAMC,EAAQ,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;IAC5C,UAAU;KACR,IAAgB;IAClB;GACF;GAEA,IAAI;IACF,IAAMC,IAAQ,MAAML,EAAI;IACxB,IAAIH,MAAUN,GAAY;IAE1B,AADA,EAAK,QAAQc,GACb,EAAK,QAAQ;KACX,MAAMX,EAAe;KACrB,UAAUC,EAAmB;KAC7B,QAAQC,EAAiB;KACzB,SAASS,EAAM;IACjB;GACF,SAASzB,GAAO;IAEd,IADIiB,MAAUN,KACVX,aAAiB0B,GAAuB;IAE5C,IAAIC,IAAS5B,EAAqBC,CAAK;IAIvC,IAAI2B,MAAA,OAAuCC,GAAa;KACtD,IAAMC,IAAY,MAAMD,EAAYf,EAAW,MAAM,CAAC,CAAC,YAAY,EAAK;KACxE,IAAII,MAAUN,GAAY;KAC1B,IAAIkB,GACF,IAAI;MACF,IAAMJ,IAAQ,MAAML,EAAI;MACxB,IAAIH,MAAUN,GAAY;MAE1B,AADA,EAAK,QAAQc,GACb,EAAK,QAAQ;OACX,MAAMX,EAAe;OACrB,UAAUC,EAAmB;OAC7B,QAAQC,EAAiB;OACzB,SAASS,EAAM;MACjB;MACA;KACF,SAASK,GAAY;MACnB,IAAIb,MAAUN,GAAY;MAC1B,IAASZ,EAAqB+B,CAAU;KAC1C;IAEJ;IAGA,AADA,EAAK,QAAQ,MACb,EAAK,QAAQ;KACX,MAAMhB,EAAe;KACrB,GAAGiB,EAAoBJ,CAAM;KAC7B,SAAS;IACX;GACF;EACF;EAE4B,aAhGR;GAElB,AADA,EAAK,QAAQlB,EAAoB,GACjC,EAAK,QAAQ;EACf;EA6FmC,cA3Fd;GAGnB,AAFA,KACAG,IAAgB,GAChB,IAAgB;EAClB;CAuF0C;AAC5C"}
|
|
1
|
+
{"version":3,"file":"userSystemProbe.js","names":["axios","UserSystemRefreshHookKey","probeStatusFromError","error","AnzuApiResponseCodeError","AnzuApiForbiddenError","AnzuApiAxiosError","cause","useUserSystemProbe","params","axes","ref","emptyUserSystemAxes","user","generation","abortInFlight","descriptor","UserSystemLoad","UserSystemPresence","UserSystemAccess","token","endpoint","resolveProbeEndpoint","ask","useApiRequest","USER_PROBE_ENTITY","abort","execute","found","AnzuApiCancelledError","status","refreshHook","refreshed","retryError","classifyProbeStatus"],"sources":["../../../../src/domains/anzuUser/composables/userSystemProbe.ts"],"sourcesContent":["import { ref, type InjectionKey, type Ref } from 'vue'\nimport axios from 'axios'\nimport { AnzuApiAxiosError } from '@/shared/error/AnzuApiAxiosError'\nimport { AnzuApiCancelledError } from '@/shared/error/AnzuApiCancelledError'\nimport { AnzuApiForbiddenError } from '@/shared/error/AnzuApiForbiddenError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { HTTP_STATUS_FORBIDDEN, HTTP_STATUS_UNAUTHORIZED } from '@/shared/statusCodes'\nimport { USER_PROBE_ENTITY } from '@/domains/api/utils/apiErrors'\nimport { useApiRequest } from '@/domains/api/composables/useApiRequest'\nimport { type AnyUserSystemDescriptor, resolveProbeEndpoint } from '@/domains/anzuUser/composables/userSystemDescriptor'\nimport {\n classifyProbeStatus,\n emptyUserSystemAxes,\n UserSystemAccess,\n UserSystemLoad,\n UserSystemPresence,\n type UserSystemAxes,\n} from '@/domains/anzuUser/utils/userSystemState'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId } from '@/shared/types/common'\n\n/**\n * Refreshes a system's session; returns true when the call is worth retrying.\n * A first 401 may be an expired session or no account. Only a refresh and retry tells them apart (decision 16).\n */\nexport type UserSystemRefreshHook = (system: string) => Promise<boolean>\n\nexport { USER_PROBE_ENTITY }\n\nexport const UserSystemRefreshHookKey: InjectionKey<UserSystemRefreshHook> = Symbol('UserSystemRefreshHook')\n\n/**\n * The backend status, or null when nothing answered.\n * Read from the axios cause, not the error class. `AnzuApiValidationError`\n * and `AnzuApiDependencyExistsError` are 422s and must be reported as such.\n */\nexport const probeStatusFromError = (error: unknown): number | null => {\n if (error instanceof AnzuApiResponseCodeError) return error.code\n if (error instanceof AnzuApiForbiddenError) return HTTP_STATUS_FORBIDDEN\n if (error instanceof AnzuApiAxiosError) return error.cause.response?.status ?? null\n const cause = (error as { cause?: unknown } | null)?.cause\n if (axios.isAxiosError(cause)) return cause.response?.status ?? null\n if (axios.isAxiosError(error)) return error.response?.status ?? null\n\n return null\n}\n\nexport interface UserSystemProbeResult {\n axes: Ref<UserSystemAxes>\n user: Ref<AnzuUser | null>\n probe: (id: IntegerId) => Promise<void>\n reset: () => void\n cancel: () => void\n}\n\nexport interface UserSystemProbeParams {\n descriptor: AnyUserSystemDescriptor\n /** Usually injected once per page; passing it explicitly is for tests and one-off panels. */\n refreshHook?: UserSystemRefreshHook | undefined\n}\n\n/**\n * Reads through `endpoints[probe].get`, never a hard-coded path (dam gates only `/adm/users/{id}`).\n * A 404 here is expected. A custom app error logger should skip `status === 404 && entity === USER_PROBE_ENTITY`.\n */\nexport const useUserSystemProbe = (params: UserSystemProbeParams): UserSystemProbeResult => {\n const { descriptor, refreshHook } = params\n\n const axes = ref<UserSystemAxes>(emptyUserSystemAxes())\n const user = ref<AnzuUser | null>(null)\n\n let generation = 0\n /**\n * Aborts the in-flight request. The generation token only drops stale answers.\n * Without this, leaving mid-search leaves up to eighteen calls running.\n */\n let abortInFlight: (() => void) | null = null\n\n const reset = () => {\n axes.value = emptyUserSystemAxes()\n user.value = null\n }\n\n const cancel = () => {\n generation++\n abortInFlight?.()\n abortInFlight = null\n }\n\n const probe = async (id: IntegerId) => {\n // A system disabled in config is shown as a state, not called.\n if (!descriptor.isEnabled()) {\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Unknown,\n access: UserSystemAccess.ConfigDisabled,\n enabled: 'unknown',\n }\n user.value = null\n return\n }\n\n const token = ++generation\n axes.value = { ...axes.value, load: UserSystemLoad.Loading }\n\n const endpoint = resolveProbeEndpoint(descriptor)\n\n const ask = async () => {\n const { execute, abort } = useApiRequest<AnzuUser, null>({\n client: descriptor.client,\n method: 'GET',\n system: descriptor.system,\n entity: USER_PROBE_ENTITY,\n validationSystem: 'common',\n validationEntity: descriptor.entity,\n urlTemplate: endpoint.get,\n })\n abortInFlight = abort\n try {\n return await execute({ urlParams: { id } })\n } finally {\n abortInFlight = null\n }\n }\n\n try {\n const found = await ask()\n if (token !== generation) return\n user.value = found\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Present,\n access: UserSystemAccess.Ok,\n enabled: found.enabled,\n }\n } catch (error) {\n if (token !== generation) return\n if (error instanceof AnzuApiCancelledError) return\n\n let status = probeStatusFromError(error)\n\n // A 401 is only a verdict after this refresh and retry.\n if (status === HTTP_STATUS_UNAUTHORIZED && refreshHook) {\n const refreshed = await refreshHook(descriptor.system).catch(() => false)\n if (token !== generation) return\n if (refreshed) {\n try {\n const found = await ask()\n if (token !== generation) return\n user.value = found\n axes.value = {\n load: UserSystemLoad.Loaded,\n presence: UserSystemPresence.Present,\n access: UserSystemAccess.Ok,\n enabled: found.enabled,\n }\n return\n } catch (retryError) {\n if (token !== generation) return\n status = probeStatusFromError(retryError)\n }\n }\n }\n\n user.value = null\n axes.value = {\n load: UserSystemLoad.Loaded,\n ...classifyProbeStatus(status),\n enabled: 'unknown',\n }\n }\n }\n\n return { axes, user, probe, reset, cancel }\n}\n"],"mappings":";;;;;;;;;;;;AA6BA,IAAaC,IAAgE,OAAO,uBAAuB,GAO9FC,KAAwB,MAAkC;CACrE,IAAIC,aAAiBC,GAA0B,OAAOD,EAAM;CAC5D,IAAIA,aAAiBE,GAAuB,OAAA;CAC5C,IAAIF,aAAiBG,GAAmB,OAAOH,EAAM,MAAM,UAAU,UAAU;CAC/E,IAAMI,IAASJ,GAAsC;CAIrD,OAHIH,EAAM,aAAaO,CAAK,IAAUA,EAAM,UAAU,UAAU,OAC5DP,EAAM,aAAaG,CAAK,IAAUA,EAAM,UAAU,UAAU,OAEzD;AACT,GAoBaK,KAAsB,MAAyD;CAC1F,IAAM,EAAE,eAAY,mBAAgBC,GAE9BC,IAAOC,EAAoBC,EAAoB,CAAC,GAChDC,IAAOF,EAAqB,IAAI,GAElCG,IAAa,GAKbC,IAAqC;CAiGzC,OAAO;EAAE;EAAM;EAAM,cApFA,MAAkB;GAErC,IAAI,CAACC,EAAW,UAAU,GAAG;IAO3B,AANA,EAAK,QAAQ;KACX,MAAMC,EAAe;KACrB,UAAUC,EAAmB;KAC7B,QAAQC,EAAiB;KACzB,SAAS;IACX,GACA,EAAK,QAAQ;IACb;GACF;GAEA,IAAMC,IAAQ,EAAEN;GAChB,EAAK,QAAQ;IAAE,GAAGJ,EAAK;IAAO,MAAMO,EAAe;GAAQ;GAE3D,IAAMI,IAAWC,EAAqBN,CAAU,GAE1CO,IAAM,YAAY;IACtB,IAAM,EAAE,YAAS,aAAUC,EAA8B;KACvD,QAAQR,EAAW;KACnB,QAAQ;KACR,QAAQA,EAAW;KACnB,QAAQS;KACR,kBAAkB;KAClB,kBAAkBT,EAAW;KAC7B,aAAaK,EAAS;IACxB,CAAC;IACD,IAAgBK;IAChB,IAAI;KACF,OAAO,MAAMC,EAAQ,EAAE,WAAW,EAAE,MAAG,EAAE,CAAC;IAC5C,UAAU;KACR,IAAgB;IAClB;GACF;GAEA,IAAI;IACF,IAAMC,IAAQ,MAAML,EAAI;IACxB,IAAIH,MAAUN,GAAY;IAE1B,AADA,EAAK,QAAQc,GACb,EAAK,QAAQ;KACX,MAAMX,EAAe;KACrB,UAAUC,EAAmB;KAC7B,QAAQC,EAAiB;KACzB,SAASS,EAAM;IACjB;GACF,SAASzB,GAAO;IAEd,IADIiB,MAAUN,KACVX,aAAiB0B,GAAuB;IAE5C,IAAIC,IAAS5B,EAAqBC,CAAK;IAGvC,IAAI2B,MAAA,OAAuCC,GAAa;KACtD,IAAMC,IAAY,MAAMD,EAAYf,EAAW,MAAM,CAAC,CAAC,YAAY,EAAK;KACxE,IAAII,MAAUN,GAAY;KAC1B,IAAIkB,GACF,IAAI;MACF,IAAMJ,IAAQ,MAAML,EAAI;MACxB,IAAIH,MAAUN,GAAY;MAE1B,AADA,EAAK,QAAQc,GACb,EAAK,QAAQ;OACX,MAAMX,EAAe;OACrB,UAAUC,EAAmB;OAC7B,QAAQC,EAAiB;OACzB,SAASS,EAAM;MACjB;MACA;KACF,SAASK,GAAY;MACnB,IAAIb,MAAUN,GAAY;MAC1B,IAASZ,EAAqB+B,CAAU;KAC1C;IAEJ;IAGA,AADA,EAAK,QAAQ,MACb,EAAK,QAAQ;KACX,MAAMhB,EAAe;KACrB,GAAGiB,EAAoBJ,CAAM;KAC7B,SAAS;IACX;GACF;EACF;EAE4B,aA/FR;GAElB,AADA,EAAK,QAAQlB,EAAoB,GACjC,EAAK,QAAQ;EACf;EA4FmC,cA1Fd;GAGnB,AAFA,KACAG,IAAgB,GAChB,IAAgB;EAClB;CAsF0C;AAC5C"}
|
|
@@ -23,28 +23,18 @@ declare const anzuUserListFields: ({
|
|
|
23
23
|
type ListFields = typeof anzuUserListFields;
|
|
24
24
|
export declare const anzuUserFilterStorageKey: (system: string) => string;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and cms has `allowedSites`, which exists nowhere else. Hard-coding either variant would send the
|
|
31
|
-
* wrong query to the other backend, and leaving them out costs those two lists filters they have
|
|
32
|
-
* today.
|
|
33
|
-
*
|
|
34
|
-
* `AFilterWrapper` draws any field that is not `render.skip` by itself, so a plain extra field
|
|
35
|
-
* needs nothing else; one that wants its own widget -- a remote autocomplete -- is passed through
|
|
36
|
-
* the matching slot.
|
|
26
|
+
* Common fields plus per-system extras.
|
|
27
|
+
* Extras are a parameter because backends differ: cms filters groups
|
|
28
|
+
* with `memberOf`, dam with `custom`, and only cms has `allowedSites`.
|
|
29
|
+
* Extra fields render automatically; a custom widget goes through the matching slot.
|
|
37
30
|
*/
|
|
38
31
|
export declare function useAnzuUserListFilter<E extends readonly MakeFilterOption[] = []>(system: string, extraFields?: E): {
|
|
39
32
|
filterConfig: FilterConfig<readonly [...ListFields, ...E]>;
|
|
40
33
|
filterData: FilterData<readonly [...ListFields, ...E]>;
|
|
41
34
|
};
|
|
42
35
|
/**
|
|
43
|
-
* Exact
|
|
44
|
-
*
|
|
45
|
-
* `startsWith` -- what the list filter uses and what admin-inhouse's search used -- cannot answer
|
|
46
|
-
* the question that search asks. "Is this person here under this address" has to be `eq`, or
|
|
47
|
-
* `jozko@sme.sk` matches `jozko.mrkvicka@sme.sk` and the fan-out reports the wrong identity.
|
|
36
|
+
* Exact e-mail match for cross-system search.
|
|
37
|
+
* `startsWith` would match `jozko@sme.sk` to `jozko.mrkvicka@sme.sk` and report the wrong identity.
|
|
48
38
|
*/
|
|
49
39
|
export declare function useAnzuUserEmailLookupFilter(): {
|
|
50
40
|
filterConfig: FilterConfig<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anzuUserFilter.js","names":["anzuUserListFields","listStores","anzuUserFilterStorageKey","system","useAnzuUserListFilter","extras","extraFields","fields","key","field","store","createFilterStore","createFilter","ANZU_USER_ENTITY","useAnzuUserEmailLookupFilter"],"sources":["../../../../src/domains/anzuUser/filter/anzuUserFilter.ts"],"sourcesContent":["import {\n createFilter,\n createFilterStore,\n type FilterConfig,\n type FilterData,\n type MakeFilterOption,\n} from '@/domains/filters/composables/filterFactory'\nimport { ANZU_USER_ENTITY } from '@/domains/anzuUser/api/anzuUserApi'\n\nconst anzuUserListFields = [\n { name: 'id' as const, default: null, type: 'integer' },\n { name: 'email' as const, variant: 'startsWith', default: null, type: 'string', render: { skip: true } },\n { name: 'enabled' as const, default: null, type: 'boolean' },\n] satisfies readonly MakeFilterOption[]\n\ntype ListFields = typeof anzuUserListFields\n\n/** One store per system; see the note in `permissionGroupFilter`. */\nconst listStores = new Map<string, FilterData<readonly MakeFilterOption[]>>()\n\nexport const anzuUserFilterStorageKey = (system: string) => `commonAnzuUser_${system}`\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"anzuUserFilter.js","names":["anzuUserListFields","listStores","anzuUserFilterStorageKey","system","useAnzuUserListFilter","extras","extraFields","fields","key","field","store","createFilterStore","createFilter","ANZU_USER_ENTITY","useAnzuUserEmailLookupFilter"],"sources":["../../../../src/domains/anzuUser/filter/anzuUserFilter.ts"],"sourcesContent":["import {\n createFilter,\n createFilterStore,\n type FilterConfig,\n type FilterData,\n type MakeFilterOption,\n} from '@/domains/filters/composables/filterFactory'\nimport { ANZU_USER_ENTITY } from '@/domains/anzuUser/api/anzuUserApi'\n\nconst anzuUserListFields = [\n { name: 'id' as const, default: null, type: 'integer' },\n { name: 'email' as const, variant: 'startsWith', default: null, type: 'string', render: { skip: true } },\n { name: 'enabled' as const, default: null, type: 'boolean' },\n] satisfies readonly MakeFilterOption[]\n\ntype ListFields = typeof anzuUserListFields\n\n/** One store per system; see the note in `permissionGroupFilter`. */\nconst listStores = new Map<string, FilterData<readonly MakeFilterOption[]>>()\n\nexport const anzuUserFilterStorageKey = (system: string) => `commonAnzuUser_${system}`\n\n/**\n * Common fields plus per-system extras.\n * Extras are a parameter because backends differ: cms filters groups\n * with `memberOf`, dam with `custom`, and only cms has `allowedSites`.\n * Extra fields render automatically; a custom widget goes through the matching slot.\n */\nexport function useAnzuUserListFilter<E extends readonly MakeFilterOption[] = []>(\n system: string,\n extraFields?: E\n): {\n filterConfig: FilterConfig<readonly [...ListFields, ...E]>\n filterData: FilterData<readonly [...ListFields, ...E]>\n} {\n const extras = (extraFields ?? []) as readonly MakeFilterOption[]\n const fields = [...anzuUserListFields, ...extras] as unknown as readonly [...ListFields, ...E]\n // Extras are part of the store key. A shared store would carry a value the other list cannot clear.\n const key = [system, ...extras.map((field) => field.name)].join('|')\n\n let store = listStores.get(key)\n if (!store) {\n store = createFilterStore(fields) as FilterData<readonly MakeFilterOption[]>\n listStores.set(key, store)\n }\n\n const { filterConfig, filterData } = createFilter(fields, store as FilterData<readonly [...ListFields, ...E]>, {\n system: 'common',\n subject: ANZU_USER_ENTITY,\n })\n\n return { filterConfig, filterData }\n}\n\n/**\n * Exact e-mail match for cross-system search.\n * `startsWith` would match `jozko@sme.sk` to `jozko.mrkvicka@sme.sk` and report the wrong identity.\n */\nexport function useAnzuUserEmailLookupFilter() {\n const fields = [\n { name: 'email' as const, variant: 'eq', default: null, type: 'string' },\n ] satisfies readonly MakeFilterOption[]\n\n const { filterConfig, filterData } = createFilter(fields, createFilterStore(fields), {\n system: 'common',\n subject: ANZU_USER_ENTITY,\n })\n\n return { filterConfig, filterData }\n}\n\n/** Test seam; the list stores are module state. */\nexport const resetAnzuUserListFilters = () => {\n listStores.clear()\n}\n"],"mappings":";;;AASA,IAAMA,IAAqB;CACzB;EAAE,MAAM;EAAe,SAAS;EAAM,MAAM;CAAU;CACtD;EAAE,MAAM;EAAkB,SAAS;EAAc,SAAS;EAAM,MAAM;EAAU,QAAQ,EAAE,MAAM,GAAK;CAAE;CACvG;EAAE,MAAM;EAAoB,SAAS;EAAM,MAAM;CAAU;AAC7D,GAKMC,oBAAa,IAAI,IAAqD,GAE/DC,KAA4B,MAAmB,kBAAkBC;AAQ9E,SAAgBC,EACd,GACA,GAIA;CACA,IAAMC,IAAUC,KAAe,CAAC,GAC1BC,IAAS,CAAC,GAAGP,GAAoB,GAAGK,CAAM,GAE1CG,IAAM,CAACL,GAAQ,GAAGE,EAAO,KAAK,MAAUI,EAAM,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,GAE/DC,IAAQT,EAAW,IAAIO,CAAG;CAC9B,AAAKE,MACH,IAAQC,EAAkBJ,CAAM,GAChCN,EAAW,IAAIO,GAAKE,CAAK;CAG3B,IAAM,EAAE,iBAAc,kBAAeE,EAAaL,GAAQG,GAAqD;EAC7G,QAAQ;EACR,SAASG;CACX,CAAC;CAED,OAAO;EAAE;EAAc;CAAW;AACpC;AAMA,SAAgBC,IAA+B;CAC7C,IAAMP,IAAS,CACb;EAAE,MAAM;EAAkB,SAAS;EAAM,SAAS;EAAM,MAAM;CAAS,CACzE,GAEM,EAAE,iBAAc,kBAAeK,EAAaL,GAAQI,EAAkBJ,CAAM,GAAG;EACnF,QAAQ;EACR,SAASM;CACX,CAAC;CAED,OAAO;EAAE;EAAc;CAAW;AACpC"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { AnzuUser } from '../../../shared/types/AnzuUser';
|
|
2
|
-
/**
|
|
3
|
-
* The one user the owning form is editing. Cross-system pages do not use this -- they hold a
|
|
4
|
-
* result per system and never a single "current" user -- so it stays a single record, the way the
|
|
5
|
-
* admins have it.
|
|
6
|
-
*/
|
|
2
|
+
/** The single user the owning form edits. Cross-system pages keep per-system results instead. */
|
|
7
3
|
export declare const useAnzuUserOneStore: import('pinia').SetupStoreDefinition<"commonAdminAnzuUserOneStore", {
|
|
8
4
|
anzuUser: import('vue').Ref<{
|
|
9
5
|
enabled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anzuUserStore.js","names":["useAnzuUserOneStore","defineStore","useAnzuUserFactory","anzuUser","ref","createAnzuUser","loadingAnzuUser","setAnzuUser","newAnzuUser","setLoadingAnzuUser","loading","reset","system","resourceName"],"sources":["../../../../src/domains/anzuUser/store/anzuUserStore.ts"],"sourcesContent":["import { acceptHMRUpdate, defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { useAnzuUserFactory } from '@/domains/anzuUser/factory/AnzuUserFactory'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\n\n
|
|
1
|
+
{"version":3,"file":"anzuUserStore.js","names":["useAnzuUserOneStore","defineStore","useAnzuUserFactory","anzuUser","ref","createAnzuUser","loadingAnzuUser","setAnzuUser","newAnzuUser","setLoadingAnzuUser","loading","reset","system","resourceName"],"sources":["../../../../src/domains/anzuUser/store/anzuUserStore.ts"],"sourcesContent":["import { acceptHMRUpdate, defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { useAnzuUserFactory } from '@/domains/anzuUser/factory/AnzuUserFactory'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\n\n/** The single user the owning form edits. Cross-system pages keep per-system results instead. */\nexport const useAnzuUserOneStore = defineStore('commonAdminAnzuUserOneStore', () => {\n const { createAnzuUser } = useAnzuUserFactory()\n\n const anzuUser = ref<AnzuUser>(createAnzuUser())\n const loadingAnzuUser = ref(false)\n\n function setAnzuUser(newAnzuUser: AnzuUser) {\n anzuUser.value = newAnzuUser\n }\n\n function setLoadingAnzuUser(loading: boolean) {\n loadingAnzuUser.value = loading\n }\n\n function reset(system = '', resourceName = 'user') {\n anzuUser.value = createAnzuUser(system, resourceName)\n loadingAnzuUser.value = false\n }\n\n return {\n anzuUser,\n loadingAnzuUser,\n setAnzuUser,\n setLoadingAnzuUser,\n reset,\n }\n})\n\nif (import.meta.hot) {\n import.meta.hot.accept(acceptHMRUpdate(useAnzuUserOneStore, import.meta.hot))\n}\n"],"mappings":";;;;AAMA,IAAaA,IAAsBC,EAAY,qCAAqC;CAClF,IAAM,EAAE,sBAAmBC,EAAmB,GAExCC,IAAWC,EAAcC,EAAe,CAAC,GACzCC,IAAkBF,EAAI,EAAK;CAEjC,SAASG,EAAY,GAAuB;EAC1C,EAAS,QAAQC;CACnB;CAEA,SAASC,EAAmB,GAAkB;EAC5C,EAAgB,QAAQC;CAC1B;CAEA,SAASC,EAAM,IAAS,IAAI,IAAe,QAAQ;EAEjD,AADA,EAAS,QAAQN,EAAeO,GAAQC,CAAY,GACpD,EAAgB,QAAQ;CAC1B;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF,CAAC"}
|
|
@@ -35,25 +35,14 @@ export interface BulkLogEntry {
|
|
|
35
35
|
system: string;
|
|
36
36
|
outcome: BulkOutcomeType;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* The log survives a run so that a retry does not erase the systems that succeeded a minute ago,
|
|
41
|
-
* and the retry button acts on whatever the log calls failed. Without these two fields a failed
|
|
42
|
-
* metadata write would be retried as a disable, and a previous person's failures would be retried
|
|
43
|
-
* against the id currently on screen -- neither `setEnabled` nor `writeMetadata` can tell it is
|
|
44
|
-
* being asked about a different action or a different account.
|
|
38
|
+
* The run this line belongs to. The log survives so a retry keeps earlier successes.
|
|
39
|
+
* Without these fields a retry could repeat the wrong action or target the person now on screen.
|
|
45
40
|
*/
|
|
46
41
|
action: BulkActionType;
|
|
47
42
|
subjectId: IntegerIdNullable;
|
|
48
43
|
detail?: string;
|
|
49
44
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Search results and the bulk run live here, not inside the dialog's component.
|
|
52
|
-
*
|
|
53
|
-
* The dialog can be closed while the calls are still going -- one dead backend running into its
|
|
54
|
-
* timeout must not lock the screen -- and state owned by the component would be thrown away with
|
|
55
|
-
* it. The results stay on the page either way.
|
|
56
|
-
*/
|
|
45
|
+
/** Kept in a store, not the dialog. The dialog can close while calls run, and the results must survive. */
|
|
57
46
|
export declare const useUserCrossSystemStore: import('pinia').SetupStoreDefinition<"commonAdminUserCrossSystemStore", {
|
|
58
47
|
searchTerm: import('vue').Ref<string, string>;
|
|
59
48
|
resolvedId: import('vue').Ref<IntegerIdNullable, IntegerIdNullable>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userCrossSystemStore.js","names":["CrossSystemPhase","BulkAction","BulkOutcome","useUserCrossSystemStore","defineStore","searchTerm","ref","resolvedId","phase","results","identityConflict","bulkRunning","bulkAction","bulkSubjectId","bulkLog","termRejected","resetResults","setResult","system","result","ensureResult","emptyUserSystemAxes","patchAxes","current","setUser","startBulk","action","subjectId","queued","systems","kept","entry","setBulkEntry","index","i","old","finishBulk","reset"],"sources":["../../../../src/domains/anzuUser/store/userCrossSystemStore.ts"],"sourcesContent":["import { acceptHMRUpdate, defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { emptyUserSystemAxes, type UserSystemAxes } from '@/domains/anzuUser/utils/userSystemState'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId, IntegerIdNullable } from '@/shared/types/common'\n\nexport interface UserSystemResult {\n axes: UserSystemAxes\n user: AnzuUser | null\n}\n\nexport const CrossSystemPhase = {\n Idle: 'idle',\n /** First round of an e-mail search: find the person and their id. */\n MatchingEmail: 'matchingEmail',\n /** Second round: ask every system by that id, to catch the ones holding a different e-mail. */\n VerifyingById: 'verifyingById',\n Done: 'done',\n} as const\nexport type CrossSystemPhaseType = (typeof CrossSystemPhase)[keyof typeof CrossSystemPhase]\n\nexport const BulkAction = {\n Enable: 'enable',\n Disable: 'disable',\n Metadata: 'metadata',\n} as const\nexport type BulkActionType = (typeof BulkAction)[keyof typeof BulkAction]\n\nexport const BulkOutcome = {\n Pending: 'pending',\n Running: 'running',\n Done: 'done',\n Forbidden: 'forbidden',\n Unauthenticated: 'unauthenticated',\n NotFound: 'notFound',\n Invalid: 'invalid',\n Unavailable: 'unavailable',\n} as const\nexport type BulkOutcomeType = (typeof BulkOutcome)[keyof typeof BulkOutcome]\n\nexport interface BulkLogEntry {\n system: string\n outcome: BulkOutcomeType\n /**\n *
|
|
1
|
+
{"version":3,"file":"userCrossSystemStore.js","names":["CrossSystemPhase","BulkAction","BulkOutcome","useUserCrossSystemStore","defineStore","searchTerm","ref","resolvedId","phase","results","identityConflict","bulkRunning","bulkAction","bulkSubjectId","bulkLog","termRejected","resetResults","setResult","system","result","ensureResult","emptyUserSystemAxes","patchAxes","current","setUser","startBulk","action","subjectId","queued","systems","kept","entry","setBulkEntry","index","i","old","finishBulk","reset"],"sources":["../../../../src/domains/anzuUser/store/userCrossSystemStore.ts"],"sourcesContent":["import { acceptHMRUpdate, defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { emptyUserSystemAxes, type UserSystemAxes } from '@/domains/anzuUser/utils/userSystemState'\nimport type { AnzuUser } from '@/shared/types/AnzuUser'\nimport type { IntegerId, IntegerIdNullable } from '@/shared/types/common'\n\nexport interface UserSystemResult {\n axes: UserSystemAxes\n user: AnzuUser | null\n}\n\nexport const CrossSystemPhase = {\n Idle: 'idle',\n /** First round of an e-mail search: find the person and their id. */\n MatchingEmail: 'matchingEmail',\n /** Second round: ask every system by that id, to catch the ones holding a different e-mail. */\n VerifyingById: 'verifyingById',\n Done: 'done',\n} as const\nexport type CrossSystemPhaseType = (typeof CrossSystemPhase)[keyof typeof CrossSystemPhase]\n\nexport const BulkAction = {\n Enable: 'enable',\n Disable: 'disable',\n Metadata: 'metadata',\n} as const\nexport type BulkActionType = (typeof BulkAction)[keyof typeof BulkAction]\n\nexport const BulkOutcome = {\n Pending: 'pending',\n Running: 'running',\n Done: 'done',\n Forbidden: 'forbidden',\n Unauthenticated: 'unauthenticated',\n NotFound: 'notFound',\n Invalid: 'invalid',\n Unavailable: 'unavailable',\n} as const\nexport type BulkOutcomeType = (typeof BulkOutcome)[keyof typeof BulkOutcome]\n\nexport interface BulkLogEntry {\n system: string\n outcome: BulkOutcomeType\n /**\n * The run this line belongs to. The log survives so a retry keeps earlier successes.\n * Without these fields a retry could repeat the wrong action or target the person now on screen.\n */\n action: BulkActionType\n subjectId: IntegerIdNullable\n detail?: string\n}\n\n/** Kept in a store, not the dialog. The dialog can close while calls run, and the results must survive. */\nexport const useUserCrossSystemStore = defineStore('commonAdminUserCrossSystemStore', () => {\n const searchTerm = ref('')\n const resolvedId = ref<IntegerIdNullable>(null)\n const phase = ref<CrossSystemPhaseType>(CrossSystemPhase.Idle)\n const results = ref(new Map<string, UserSystemResult>())\n\n /**\n * The same e-mail answered with two ids. Bulk actions stop when set.\n * AnzuUser cannot be deleted, so writes under the wrong identity would persist.\n */\n const identityConflict = ref<Map<string, IntegerId> | null>(null)\n\n const bulkRunning = ref(false)\n const bulkAction = ref<BulkActionType | null>(null)\n const bulkSubjectId = ref<IntegerIdNullable>(null)\n const bulkLog = ref<BulkLogEntry[]>([])\n\n /** The term was neither an address nor an id, so nothing was asked and there is nothing to show. */\n const termRejected = ref(false)\n\n function resetResults() {\n results.value = new Map()\n resolvedId.value = null\n identityConflict.value = null\n phase.value = CrossSystemPhase.Idle\n termRejected.value = false\n // A new search is a new person. An old log's retry would write to the new `resolvedId`.\n bulkLog.value = []\n bulkAction.value = null\n bulkSubjectId.value = null\n }\n\n function setResult(system: string, result: UserSystemResult) {\n results.value.set(system, result)\n }\n\n function ensureResult(system: string) {\n if (!results.value.has(system)) {\n results.value.set(system, { axes: emptyUserSystemAxes(), user: null })\n }\n }\n\n function patchAxes(system: string, axes: UserSystemAxes) {\n ensureResult(system)\n const current = results.value.get(system)!\n results.value.set(system, { ...current, axes })\n }\n\n function setUser(system: string, user: AnzuUser | null) {\n ensureResult(system)\n const current = results.value.get(system)!\n results.value.set(system, { ...current, user })\n }\n\n /**\n * Starts a run over `systems`, keeping earlier log entries for the same action and account.\n * A retry runs a subset; clearing the log would erase earlier successes.\n */\n function startBulk(action: BulkActionType, systems: string[], subjectId: IntegerIdNullable) {\n bulkRunning.value = true\n bulkAction.value = action\n bulkSubjectId.value = subjectId\n const queued = new Set(systems)\n const kept = bulkLog.value.filter(\n (entry) => entry.action === action && entry.subjectId === subjectId && !queued.has(entry.system)\n )\n bulkLog.value = [...kept, ...systems.map((system) => ({ system, outcome: BulkOutcome.Pending, action, subjectId }))]\n }\n\n function setBulkEntry(system: string, outcome: BulkOutcomeType, detail?: string) {\n const index = bulkLog.value.findIndex(\n (entry) => entry.system === system && entry.action === bulkAction.value && entry.subjectId === bulkSubjectId.value\n )\n if (index === -1) return\n const entry: BulkLogEntry = { ...bulkLog.value[index]!, outcome, detail }\n bulkLog.value = bulkLog.value.map((old, i) => (i === index ? entry : old))\n }\n\n function finishBulk() {\n bulkRunning.value = false\n }\n\n /**\n * Clears the page for the next visit but keeps the bulk lock.\n * `cancel()` stops probes, not writes. Releasing the lock would allow a second\n * bulk action on the same account (B13). The run releases it when done.\n */\n function reset() {\n searchTerm.value = ''\n resetResults()\n }\n\n return {\n searchTerm,\n resolvedId,\n phase,\n results,\n identityConflict,\n bulkRunning,\n bulkAction,\n bulkSubjectId,\n bulkLog,\n termRejected,\n resetResults,\n setResult,\n patchAxes,\n setUser,\n startBulk,\n setBulkEntry,\n finishBulk,\n reset,\n }\n})\n\nif (import.meta.hot) {\n import.meta.hot.accept(acceptHMRUpdate(useUserCrossSystemStore, import.meta.hot))\n}\n"],"mappings":";;;;AAWA,IAAaA,IAAmB;CAC9B,MAAM;CAEN,eAAe;CAEf,eAAe;CACf,MAAM;AACR,GAGaC,IAAa;CACxB,QAAQ;CACR,SAAS;CACT,UAAU;AACZ,GAGaC,IAAc;CACzB,SAAS;CACT,SAAS;CACT,MAAM;CACN,WAAW;CACX,iBAAiB;CACjB,UAAU;CACV,SAAS;CACT,aAAa;AACf,GAgBaC,IAA0BC,EAAY,yCAAyC;CAC1F,IAAMC,IAAaC,EAAI,EAAE,GACnBC,IAAaD,EAAuB,IAAI,GACxCE,IAAQF,EAA0BN,EAAiB,IAAI,GACvDS,IAAUH,kBAAI,IAAI,IAA8B,CAAC,GAMjDI,IAAmBJ,EAAmC,IAAI,GAE1DK,IAAcL,EAAI,EAAK,GACvBM,IAAaN,EAA2B,IAAI,GAC5CO,IAAgBP,EAAuB,IAAI,GAC3CQ,IAAUR,EAAoB,CAAC,CAAC,GAGhCS,IAAeT,EAAI,EAAK;CAE9B,SAASU,IAAe;EAStB,AARA,EAAQ,wBAAQ,IAAI,IAAI,GACxB,EAAW,QAAQ,MACnB,EAAiB,QAAQ,MACzB,EAAM,QAAQhB,EAAiB,MAC/B,EAAa,QAAQ,IAErB,EAAQ,QAAQ,CAAC,GACjB,EAAW,QAAQ,MACnB,EAAc,QAAQ;CACxB;CAEA,SAASiB,EAAU,GAAgB,GAA0B;EAC3D,EAAQ,MAAM,IAAIC,GAAQC,CAAM;CAClC;CAEA,SAASC,EAAa,GAAgB;EACpC,AAAKX,EAAQ,MAAM,IAAIS,CAAM,KAC3BT,EAAQ,MAAM,IAAIS,GAAQ;GAAE,MAAMG,EAAoB;GAAG,MAAM;EAAK,CAAC;CAEzE;CAEA,SAASC,EAAU,GAAgB,GAAsB;EACvD,EAAaJ,CAAM;EACnB,IAAMK,IAAUd,EAAQ,MAAM,IAAIS,CAAM;EACxC,EAAQ,MAAM,IAAIA,GAAQ;GAAE,GAAGK;GAAS;EAAK,CAAC;CAChD;CAEA,SAASC,EAAQ,GAAgB,GAAuB;EACtD,EAAaN,CAAM;EACnB,IAAMK,IAAUd,EAAQ,MAAM,IAAIS,CAAM;EACxC,EAAQ,MAAM,IAAIA,GAAQ;GAAE,GAAGK;GAAS;EAAK,CAAC;CAChD;CAMA,SAASE,EAAU,GAAwB,GAAmB,GAA8B;EAG1F,AAFA,EAAY,QAAQ,IACpB,EAAW,QAAQC,GACnB,EAAc,QAAQC;EACtB,IAAMC,IAAS,IAAI,IAAIC,CAAO,GACxBC,IAAOhB,EAAQ,MAAM,QACxB,MAAUiB,EAAM,WAAWL,KAAUK,EAAM,cAAcJ,KAAa,CAACC,EAAO,IAAIG,EAAM,MAAM,CACjG;EACA,EAAQ,QAAQ,CAAC,GAAGD,GAAM,GAAGD,EAAQ,KAAK,OAAY;GAAE;GAAQ,SAAS3B,EAAY;GAAS;GAAQ;EAAU,EAAE,CAAC;CACrH;CAEA,SAAS8B,EAAa,GAAgB,GAA0B,GAAiB;EAC/E,IAAMC,IAAQnB,EAAQ,MAAM,WACzB,MAAUiB,EAAM,WAAWb,KAAUa,EAAM,WAAWnB,EAAW,SAASmB,EAAM,cAAclB,EAAc,KAC/G;EACA,IAAIoB,MAAU,IAAI;EAClB,IAAMF,IAAsB;GAAE,GAAGjB,EAAQ,MAAMmB;GAAS;GAAS;EAAO;EACxE,EAAQ,QAAQnB,EAAQ,MAAM,KAAK,GAAK,MAAOoB,MAAMD,IAAQF,IAAQI,CAAI;CAC3E;CAEA,SAASC,IAAa;EACpB,EAAY,QAAQ;CACtB;CAOA,SAASC,IAAQ;EAEf,AADA,EAAW,QAAQ,IACnBrB,EAAa;CACf;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF,CAAC"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { BaseUser } from '../../../shared/types/AnzuUser';
|
|
2
2
|
/**
|
|
3
|
-
* The six fields
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `jozko@sme.sk` in weather and `j.mrkvicka@sme.sk` in blog, a search by e-mail finds weather and
|
|
7
|
-
* blog answers nothing -- which looks exactly like "no account here". The second round, by the id
|
|
8
|
-
* the first round found, is what turns that silence into the inconsistency it actually is.
|
|
3
|
+
* The six compared fields.
|
|
4
|
+
* `email` is why e-mail search runs twice: a system with a different
|
|
5
|
+
* address answers nothing. The id round reveals that as an inconsistency.
|
|
9
6
|
*/
|
|
10
7
|
export declare const USER_METADATA_FIELDS: readonly ["email", "person.firstName", "person.lastName", "person.fullName", "avatar.color", "avatar.text"];
|
|
11
8
|
export type UserMetadataField = (typeof USER_METADATA_FIELDS)[number];
|
|
@@ -17,22 +14,13 @@ export interface MetadataDifference {
|
|
|
17
14
|
values: Map<string, string>;
|
|
18
15
|
}
|
|
19
16
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Blog is compared on `person.*` like everything else, and its own root `firstName`/`lastName`
|
|
23
|
-
* columns are deliberately left out of this: those are the byline under an article, the blog's slug
|
|
24
|
-
* and the public API, not back-office metadata. That blog's `person` is empty for most bloggers and
|
|
25
|
-
* will therefore read as different is correct -- the back-office identity really is unset there,
|
|
26
|
-
* and the first repair fills it in.
|
|
17
|
+
* Blog is compared on `person.*`. Its root `firstName`/`lastName` are the public byline and are excluded.
|
|
18
|
+
* Blog's empty `person` reads as different on purpose; the first repair fills it.
|
|
27
19
|
*/
|
|
28
20
|
export declare const findMetadataDifferences: (records: Map<string, BaseUser>) => MetadataDifference[];
|
|
29
21
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* Never "whichever answered first" -- the fan-out is parallel, so that would be a different answer
|
|
34
|
-
* on every run. The order is a default rather than a hidden rule: the dialog names the source and
|
|
35
|
-
* lets it be changed.
|
|
22
|
+
* Prefill source: the first system in configured order with a record.
|
|
23
|
+
* Not the first to answer, since the fan-out is parallel. The dialog names the source and lets it be changed.
|
|
36
24
|
*/
|
|
37
25
|
export declare const pickPrefillSource: (order: string[], records: Map<string, BaseUser>) => string | null;
|
|
38
26
|
/** Systems whose stored value differs from the one about to be written. Nothing else is touched. */
|