@anzusystems/common-admin 2.0.0-rc.11 → 2.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domains/anzuUser/components/AAnzuUserDatatable.js.map +1 -1
- 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_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_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/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_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_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_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/AUserMetadataForm.js.map +1 -1
- 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/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_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/AUserTabsShell.js.map +1 -1
- package/dist/domains/anzuUser/components/AUserTabsShell.vue_vue_type_script_setup_true_lang.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/cached/components/ACachedChip.js.map +1 -1
- package/dist/domains/cached/components/ACachedChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/cached/components/ACachedUserChip.js.map +1 -1
- package/dist/domains/cached/components/ACachedUserChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/collab/components/ACollabCountdown.js.map +1 -1
- package/dist/domains/collab/components/ACollabCountdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/collab/components/ACollabLockedByUser.js.map +1 -1
- package/dist/domains/collab/components/ACollabManagement.js.map +1 -1
- package/dist/domains/collab/components/ACollabManagement.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/customDataForm/components/ACustomDataForm.js.map +1 -1
- 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/dam/assetDetail/components/AColorBox.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.js.map +1 -1
- 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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialogLoader.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailDialogSidebar.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsTeleportTarget.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsWrapper.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsWrapper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- 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/AssetFileFailReasonChip.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileFailReasonChip.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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileRotate.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetFileRotate.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_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_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/components/AssetMetadataImageAttributes.js.map +1 -1
- package/dist/domains/dam/assetDetail/components/AssetMetadataImageAttributes.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AAssetListInner.js.map +1 -1
- 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_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_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/AssetImagePreview.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetImagePreview.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectFilter.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectFilterForm.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectFilterForm.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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListTable.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListTiles.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectListTiles.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/AssetSelectTilesItem.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/AssetSelectTilesItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/assetSelect/components/FilterPodcastRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/author/components/AuthorCreateButton.js.map +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_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.map +1 -1
- 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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/components/DamAdminAssetLink.js.map +1 -1
- package/dist/domains/dam/cropper/components/ACropper.js.map +1 -1
- 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/components/DamAssetImageRoiSelectLazy.js.map +1 -1
- package/dist/domains/dam/cropper/components/DamAssetImageRoiSelectLazy.vue_vue_type_script_setup_true_lang.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/AImageWidgetMultipleSimple.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidgetSimple.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AImageWidgetSimple.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AMediaWidgetSimple.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/AMediaWidgetSimple.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.js.map +1 -1
- 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_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_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_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_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.js.map +1 -1
- package/dist/domains/dam/imageWidget/components/MediaWidgetSimpleDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.js.map +1 -1
- 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.map +1 -1
- package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueButtonStop.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueButtonStop.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/UploadQueueDialogSingleSidebarMetadata.js.map +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_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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/dam/uploadQueue/components/UploadQueueItemErrorOverlay.js.map +1 -1
- package/dist/domains/dam/user/components/DamAssetLicenceGroupRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/user/components/DamAssetLicenceRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/user/components/DamDistributionServiceSelect.js.map +1 -1
- package/dist/domains/dam/user/components/DamExtSystemRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.js.map +1 -1
- package/dist/domains/dam/user/components/DamUserFilterRemoteAutocomplete.js.map +1 -1
- package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.js.map +1 -1
- package/dist/domains/filters/bookmarks/components/AFilterBookmarkButton.js.map +1 -1
- package/dist/domains/filters/bookmarks/components/AFilterBookmarkButton.vue_vue_type_script_setup_true_lang.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/components/FilterBookmarks.js.map +1 -1
- package/dist/domains/filters/bookmarks/components/FilterBookmarks.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterAdvancedButton.js.map +1 -1
- package/dist/domains/filters/components/AFilterBooleanSelect.js.map +1 -1
- package/dist/domains/filters/components/AFilterDatetimePicker.js.map +1 -1
- package/dist/domains/filters/components/AFilterEmpty.js.map +1 -1
- package/dist/domains/filters/components/AFilterInteger.js.map +1 -1
- package/dist/domains/filters/components/AFilterResetButton.js.map +1 -1
- package/dist/domains/filters/components/AFilterString.js.map +1 -1
- package/dist/domains/filters/components/AFilterString.vue.d.ts +3 -0
- package/dist/domains/filters/components/AFilterString.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/domains/filters/components/AFilterString.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterSubmitButton.js.map +1 -1
- package/dist/domains/filters/components/AFilterTimeInterval.js.map +1 -1
- 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/AFilterWrapper.js.map +1 -1
- package/dist/domains/filters/components/AFilterWrapper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/filters/components/AFilterWrapperSidebar.js.map +1 -1
- package/dist/domains/filters/components/FilterDetailItem.js.map +1 -1
- package/dist/domains/filters/components/FiltersSelected.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatableConfigButton.js.map +1 -1
- package/dist/domains/filters/datatable/components/ADatatableOrdering.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.map +1 -1
- package/dist/domains/form/components/AFormDatetimePicker.js.map +1 -1
- 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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormRemoteCheckbox.js.map +1 -1
- package/dist/domains/form/components/AFormRemoteCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormRemoteSwitch.js.map +1 -1
- package/dist/domains/form/components/AFormRemoteSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormSwitch.js.map +1 -1
- package/dist/domains/form/components/AFormSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormTextField.js.map +1 -1
- package/dist/domains/form/components/AFormTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormTextarea.js.map +1 -1
- package/dist/domains/form/components/AFormTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/AFormValueObjectOptionsSelect.js.map +1 -1
- package/dist/domains/form/components/AFormValueObjectOptionsSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/form/components/ASystemEntityScope.js.map +1 -1
- package/dist/domains/job/components/AJobBaseCreateForm.js.map +1 -1
- package/dist/domains/job/components/AJobBaseCreateForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/job/components/AJobDetailCommon.js.map +1 -1
- package/dist/domains/job/components/AJobPriorityChip.js.map +1 -1
- package/dist/domains/job/components/AJobStatusChip.js.map +1 -1
- 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_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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeChangeParentDialog.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeChangeParentDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeDeleteDialog.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeDeleteDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeDragHandle.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeEmptyState.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeMoveToPositionDialog.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeMoveToPositionDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeNestedRow.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeNestedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeStatus.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeStatus.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeUnsavedLabel.js.map +1 -1
- package/dist/domains/listEditor/components/internal/LeUnsavedLabel.vue_vue_type_script_setup_true_lang.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/ALogDetail.js.map +1 -1
- package/dist/domains/log/components/ALogDetailView.js.map +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/ALogLevelChip.js.map +1 -1
- package/dist/domains/log/components/ALogLevelChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/log/components/ALogListView.js.map +1 -1
- package/dist/domains/permission/components/APermissionEditor.js.map +1 -1
- package/dist/domains/permission/components/APermissionEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/components/APermissionGrantEditor.js.map +1 -1
- package/dist/domains/permission/components/APermissionValueChip.js.map +1 -1
- package/dist/domains/permission/components/APermissionValueChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupDatatable.js.map +1 -1
- 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/APermissionGroupFilter.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupManage.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupManage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/permission/group/components/APermissionGroupRemoteAutocomplete.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/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.js.map +1 -1
- package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/subjectSelect/components/AFilterWrapperSubjectSelect.js.map +1 -1
- package/dist/domains/subjectSelect/components/AFilterWrapperSubjectSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- 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/system/appShell/components/AActionbar.js.map +1 -1
- package/dist/domains/system/appShell/components/AActionbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/appShell/components/AActionbarTarget.js.map +1 -1
- package/dist/domains/system/appShell/components/ALayoutLoader.js.map +1 -1
- package/dist/domains/system/appShell/components/ALayoutSwitch.js.map +1 -1
- package/dist/domains/system/appShell/components/ALayoutSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/components/AAdminSwitcher.js.map +1 -1
- package/dist/domains/system/components/AAdminSwitcher.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/components/AAlerts.js.map +1 -1
- package/dist/domains/system/components/ALanguageSelect.js.map +1 -1
- package/dist/domains/system/components/AThemeSelect.js.map +1 -1
- package/dist/domains/system/components/AThemeSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/system/flags/components/FlagCountry.js.map +1 -1
- package/dist/domains/system/flags/components/FlagEn.js.map +1 -1
- package/dist/domains/system/flags/components/FlagSk.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/components/ASystemBarNewVersion.js.map +1 -1
- package/dist/domains/system/systemBar/components/ASystemBarNewVersion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionCreateButton.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionCreateButton.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/action/components/AActionEditButton.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionEditButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionSaveAndCloseButton.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionSaveAndCloseButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionSaveButton.js.map +1 -1
- package/dist/domains/ui/buttons/action/components/AActionSaveButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/components/ABtnSplit.js.map +1 -1
- package/dist/domains/ui/buttons/components/ABtnSplit.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableCopyIdButton.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableCopyIdButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableDetailButton.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableDetailButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableEditButton.js.map +1 -1
- package/dist/domains/ui/buttons/table/components/ATableEditButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/AAnzuUserAvatar.js.map +1 -1
- package/dist/domains/ui/components/AAnzuUserAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- 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/ABooleanSelect.js.map +1 -1
- package/dist/domains/ui/components/ABooleanValue.js.map +1 -1
- package/dist/domains/ui/components/ACard.js.map +1 -1
- package/dist/domains/ui/components/ACardLoader.js.map +1 -1
- package/dist/domains/ui/components/AChipNoLink.js.map +1 -1
- package/dist/domains/ui/components/ACopyText.js.map +1 -1
- package/dist/domains/ui/components/ACopyText.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ACreateDialog.js.map +1 -1
- package/dist/domains/ui/components/ACreateDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ACurrentUserDropdown.js.map +1 -1
- package/dist/domains/ui/components/ACurrentUserDropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/components/ADialogToolbar.js.map +1 -1
- package/dist/domains/ui/components/AIconGroup.js.map +1 -1
- package/dist/domains/ui/components/AProgress.js.map +1 -1
- package/dist/domains/ui/components/ARow.js.map +1 -1
- package/dist/domains/ui/components/ARow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- 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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/datetime/components/ADatetime.js.map +1 -1
- package/dist/domains/ui/datetime/components/ADatetimePicker.js.map +1 -1
- package/dist/domains/ui/datetime/components/ADatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/datetime/components/TimePicker.js.map +1 -1
- package/dist/domains/ui/file/components/AFileDropzone.js.map +1 -1
- package/dist/domains/ui/file/components/AFileInput.js.map +1 -1
- 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_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/view/components/AGenericView.js.map +1 -1
- package/dist/domains/ui/view/components/AGenericView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/ui/view/components/ALoginView.js.map +1 -1
- 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/ANotFoundView.js.map +1 -1
- package/dist/domains/ui/view/components/AUnauthorizedView.js.map +1 -1
- package/dist/domains/ui/view/components/AUnauthorizedView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/domains/unsavedGuard/components/AUnsavedConfirmDialog.js.map +1 -1
- package/dist/locales/cs/common/alert.js.map +1 -1
- package/dist/locales/cs/common/anzuUser.js.map +1 -1
- package/dist/locales/cs/common/assetSelect.js.map +1 -1
- package/dist/locales/cs/common/button.js.map +1 -1
- package/dist/locales/cs/common/collab.js.map +1 -1
- package/dist/locales/cs/common/confirmDialog.js.map +1 -1
- package/dist/locales/cs/common/customForm.js.map +1 -1
- package/dist/locales/cs/common/customFormElement.js.map +1 -1
- package/dist/locales/cs/common/damImage.js.map +1 -1
- package/dist/locales/cs/common/dayOfWeek.js.map +1 -1
- package/dist/locales/cs/common/filter.js.map +1 -1
- package/dist/locales/cs/common/job.js.map +1 -1
- package/dist/locales/cs/common/linkDto.js.map +1 -1
- package/dist/locales/cs/common/listItemDto.js.map +1 -1
- package/dist/locales/cs/common/log.js.map +1 -1
- package/dist/locales/cs/common/model.js.map +1 -1
- package/dist/locales/cs/common/permission.js.map +1 -1
- package/dist/locales/cs/common/permissionEditor.js.map +1 -1
- package/dist/locales/cs/common/permissionGroup.js.map +1 -1
- package/dist/locales/cs/common/routeSettings.js.map +1 -1
- package/dist/locales/cs/common/sortable.js.map +1 -1
- package/dist/locales/cs/common/subjectSelect.js.map +1 -1
- package/dist/locales/cs/common/system.js.map +1 -1
- package/dist/locales/cs/common/time.js.map +1 -1
- package/dist/locales/cs/common/userSystem.js.map +1 -1
- package/dist/locales/cs/error/apiDependencyExists.js.map +1 -1
- package/dist/locales/cs/error/apiForbiddenOperation.js.map +1 -1
- package/dist/locales/cs/error/apiTimedOut.js.map +1 -1
- package/dist/locales/cs/error/apiValidation.js.map +1 -1
- package/dist/locales/cs/error/jsValidation.js.map +1 -1
- package/dist/locales/cs/vuetify.js.map +1 -1
- package/dist/locales/en/common/alert.js.map +1 -1
- package/dist/locales/en/common/anzuUser.js.map +1 -1
- package/dist/locales/en/common/assetSelect.js.map +1 -1
- package/dist/locales/en/common/button.js.map +1 -1
- package/dist/locales/en/common/collab.js.map +1 -1
- package/dist/locales/en/common/confirmDialog.js.map +1 -1
- package/dist/locales/en/common/customForm.js.map +1 -1
- package/dist/locales/en/common/customFormElement.js.map +1 -1
- package/dist/locales/en/common/damImage.js.map +1 -1
- package/dist/locales/en/common/dayOfWeek.js.map +1 -1
- package/dist/locales/en/common/filter.js.map +1 -1
- package/dist/locales/en/common/job.js.map +1 -1
- package/dist/locales/en/common/linkDto.js.map +1 -1
- package/dist/locales/en/common/listItemDto.js.map +1 -1
- package/dist/locales/en/common/log.js.map +1 -1
- package/dist/locales/en/common/model.js.map +1 -1
- package/dist/locales/en/common/permission.js.map +1 -1
- package/dist/locales/en/common/permissionEditor.js.map +1 -1
- package/dist/locales/en/common/permissionGroup.js.map +1 -1
- package/dist/locales/en/common/routeSettings.js.map +1 -1
- package/dist/locales/en/common/sortable.js.map +1 -1
- package/dist/locales/en/common/subjectSelect.js.map +1 -1
- package/dist/locales/en/common/system.js.map +1 -1
- package/dist/locales/en/common/time.js.map +1 -1
- package/dist/locales/en/common/userSystem.js.map +1 -1
- package/dist/locales/en/error/apiDependencyExists.js.map +1 -1
- package/dist/locales/en/error/apiForbiddenOperation.js.map +1 -1
- package/dist/locales/en/error/apiTimedOut.js.map +1 -1
- package/dist/locales/en/error/apiValidation.js.map +1 -1
- package/dist/locales/en/error/jsValidation.js.map +1 -1
- package/dist/locales/en/vuetify.js.map +1 -1
- package/dist/locales/sk/common/alert.js.map +1 -1
- package/dist/locales/sk/common/anzuUser.js.map +1 -1
- package/dist/locales/sk/common/assetSelect.js.map +1 -1
- package/dist/locales/sk/common/button.js.map +1 -1
- package/dist/locales/sk/common/collab.js.map +1 -1
- package/dist/locales/sk/common/confirmDialog.js.map +1 -1
- package/dist/locales/sk/common/customForm.js.map +1 -1
- package/dist/locales/sk/common/customFormElement.js.map +1 -1
- package/dist/locales/sk/common/damImage.js.map +1 -1
- package/dist/locales/sk/common/dayOfWeek.js.map +1 -1
- package/dist/locales/sk/common/filter.js.map +1 -1
- package/dist/locales/sk/common/job.js.map +1 -1
- package/dist/locales/sk/common/linkDto.js.map +1 -1
- package/dist/locales/sk/common/listItemDto.js.map +1 -1
- package/dist/locales/sk/common/log.js.map +1 -1
- package/dist/locales/sk/common/model.js.map +1 -1
- package/dist/locales/sk/common/permission.js.map +1 -1
- package/dist/locales/sk/common/permissionEditor.js.map +1 -1
- package/dist/locales/sk/common/permissionGroup.js.map +1 -1
- package/dist/locales/sk/common/routeSettings.js.map +1 -1
- package/dist/locales/sk/common/sortable.js.map +1 -1
- package/dist/locales/sk/common/subjectSelect.js.map +1 -1
- package/dist/locales/sk/common/system.js.map +1 -1
- package/dist/locales/sk/common/time.js.map +1 -1
- package/dist/locales/sk/common/userSystem.js.map +1 -1
- package/dist/locales/sk/error/apiDependencyExists.js.map +1 -1
- package/dist/locales/sk/error/apiForbiddenOperation.js.map +1 -1
- package/dist/locales/sk/error/apiTimedOut.js.map +1 -1
- package/dist/locales/sk/error/apiValidation.js.map +1 -1
- package/dist/locales/sk/error/jsValidation.js.map +1 -1
- package/dist/locales/sk/vuetify.js.map +1 -1
- package/package.json +15 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthorRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js","names":["_resolveComponent","_openBlock","_createElementBlock","_Fragment","_createElementVNode","_createBlock","ARow","_withCtx","_renderList","AuthorRemoteAutocompleteCachedAuthorChip","AFormRemoteAutocompleteWithCached","_unref","_withKeys","_component_VListItem","_mergeProps","_withModifiers","_createSlots","_createVNode","_component_VCheckboxBtn","_createCommentVNode","_withDirectives","AuthorCreateButton","_vShow","_toDisplayString","AuthorRemoteAutocompleteCachedAuthorChipConflicts","AFormRemoteAutocompleteWithCached_default","AuthorRemoteAutocompleteCachedAuthorChip_default","AuthorRemoteAutocompleteCachedAuthorChipConflicts_default","AuthorCreateButton_default","ARow_default","useVuelidate","_hoisted_1","_hoisted_2","_hoisted_3","AuthorRemoteAutocompleteWithCached_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","damConfigName","useDamConfigName","modelValueComputed","computed","newValue","search","ref","loadingLocal","fetchedItemsMinimal","useI18n","requiredComputed","useValidate","rules","requiredIf","v$","useAuthorSelectActions","useCommonAdminCoreDamOptions","createAllowed","useAclAllowed","authorCreateAcl","useAuthorInnerFilter","provide","FilterInnerConfigKey","filterConfig","FilterInnerDataKey","filterData","offeredConflicts","isArray","id","addAuthor","addNewAuthorText","searchChange","removeLastComma","useDamCachedAuthors","useCachedOfName","useDamCachedAuthorsForRemoteAutocomplete","afterCreate","addManualToCachedAuthors","author","itemSlotIsSelected","item","authorCreateButton","value","onEnterKeyup","onCommaKeyup","showAdd","_component_ABtnSecondary","resolveComponent","openBlock","createElementBlock","Fragment","createElementVNode","createBlock","withCtx","renderList","_cache","$event","unref","fetchItemsMinimal","withKeys","itemSlotProps","itemSlotItem","VListItem","mergeProps","withModifiers","createSlots","createVNode","VCheckboxBtn","createCommentVNode","chipSlotProps","chipSlotItem","withDirectives","vShow","toDisplayString","t","authorId"],"sources":["../../../../../src/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { DocId, IntegerId } from '@/shared/types/common'\nimport type { ValidationScope } from '@/shared/types/Validation'\nimport { computed, provide, ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useValidate } from '@/shared/validators/vuelidate/useValidate'\nimport useVuelidate from '@vuelidate/core'\nimport {\n useDamCachedAuthors,\n useDamCachedAuthorsForRemoteAutocomplete,\n} from '@/domains/dam/author/composables/cachedAuthors'\nimport type { DamAuthor } from '@/domains/dam/author/types/DamAuthor'\nimport { isArray } from '@/shared/utils/common'\nimport AFormRemoteAutocompleteWithCached from '@/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue'\nimport AuthorRemoteAutocompleteCachedAuthorChip from '@/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue'\nimport AuthorRemoteAutocompleteCachedAuthorChipConflicts from '@/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.vue'\nimport { useAuthorSelectActions } from '@/domains/dam/author/composables/authorActions'\nimport AuthorCreateButton from '@/domains/dam/author/components/AuthorCreateButton.vue'\nimport ARow from '@/domains/ui/components/ARow.vue'\nimport { FilterInnerConfigKey, FilterInnerDataKey } from '@/domains/filters/utils/filterInjectionKeys'\nimport { useAuthorInnerFilter } from '@/domains/dam/author/filter/AuthorFilter'\nimport { useAclAllowed } from '@/domains/auth/composables/aclAllowed'\nimport { useCommonAdminCoreDamOptions } from '@/domains/dam/composables/commonAdminCoreDamOptions'\nimport type { DamFieldsDisabledAs } from '@/domains/dam/uploadQueue/components/uploadQueueBindings'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: DocId | null | DocId[] | any\n extSystem: IntegerId\n queueId?: string | undefined\n label?: string | undefined\n required?: boolean | null\n disabled?: boolean | undefined\n multiple?: boolean\n clearable?: boolean\n authorConflicts?: DocId[]\n dataCy?: string\n validationScope?: ValidationScope\n /** How a disabled field looks: author chips (current library behaviour), or the input and its \"+\" disabled. */\n disabledAs?: DamFieldsDisabledAs\n /** DAM configuration to use. Defaults to the parent component's, else `default`. */\n configName?: string\n }>(),\n {\n label: undefined,\n queueId: undefined,\n required: null,\n disabled: undefined,\n multiple: false,\n clearable: false,\n authorConflicts: undefined,\n dataCy: undefined,\n validationScope: undefined,\n disabledAs: 'chips',\n configName: undefined,\n }\n)\nconst emit = defineEmits<{\n (e: 'update:modelValue', data: DocId | null | DocId[]): void\n}>()\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\nconst modelValueComputed = computed({\n get() {\n return props.modelValue\n },\n set(newValue) {\n emit('update:modelValue', [...newValue])\n },\n})\n\nconst search = ref<string>('')\nconst loadingLocal = ref(false)\nconst fetchedItemsMinimal = ref<Map<IntegerId | DocId, any>>(new Map())\n\nconst { t } = useI18n()\n\nconst requiredComputed = computed(() => !!props.required)\n\nconst { requiredIf } = useValidate()\n\nconst rules = {\n modelValueComputed: {\n required: requiredIf(requiredComputed),\n },\n}\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst v$ = useVuelidate(rules, { modelValueComputed }, { $scope: props.validationScope })\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst { fetchItemsMinimal } = useAuthorSelectActions(props.extSystem, damConfigName)\n\nconst { authorCreateAcl } = useCommonAdminCoreDamOptions(damConfigName)\nconst createAllowed = useAclAllowed(authorCreateAcl ?? undefined)\n\nconst { filterData, filterConfig } = useAuthorInnerFilter()\nprovide(FilterInnerConfigKey, filterConfig)\nprovide(FilterInnerDataKey, filterData)\n\n// Authors the input already has are not offered again.\nconst offeredConflicts = computed(() =>\n (props.authorConflicts ?? []).filter((id) =>\n isArray(modelValueComputed.value) ? !modelValueComputed.value.includes(id) : modelValueComputed.value !== id\n )\n)\n\nconst addAuthor = async (id: null | DocId | undefined) => {\n if (!id) return\n if (!modelValueComputed.value.includes(id)) {\n modelValueComputed.value = [...modelValueComputed.value, id]\n }\n}\n\nconst addNewAuthorText = ref('')\n\nconst searchChange = (newValue: string) => {\n if (newValue.length > 0) addNewAuthorText.value = removeLastComma(newValue)\n}\n\nconst { addManualToCachedAuthors } = useDamCachedAuthors(damConfigName)\n// The inner input reads this cache only once.\nconst useCachedOfName = () => useDamCachedAuthorsForRemoteAutocomplete(damConfigName)\n\nconst afterCreate = (author: DamAuthor) => {\n addManualToCachedAuthors(author)\n if (isArray(modelValueComputed.value)) {\n modelValueComputed.value = [...modelValueComputed.value, author.id]\n search.value = ''\n return\n }\n modelValueComputed.value = author.id\n search.value = ''\n}\n\nconst itemSlotIsSelected = (item: DocId) => {\n if (isArray(modelValueComputed.value)) {\n return modelValueComputed.value.includes(item)\n } else if (modelValueComputed.value) {\n return modelValueComputed.value === item\n }\n return false\n}\n\nconst authorCreateButton = ref<InstanceType<typeof AuthorCreateButton> | null>(null)\n\nconst removeLastComma = (value: string) => {\n if (value.endsWith(',')) return value.slice(0, -1)\n return value\n}\n\nconst onEnterKeyup = () => {\n if (!createAllowed.value) return\n const value = removeLastComma(search.value)\n authorCreateButton.value?.open(value)\n}\n\nconst onCommaKeyup = () => {\n if (!createAllowed.value) return\n const value = removeLastComma(search.value)\n authorCreateButton.value?.open(value)\n}\n\nconst showAdd = computed(() => {\n if (!createAllowed.value) return false\n if (loadingLocal.value) return false\n if (search.value.length < 2 || search.value.length > 255) return false\n if (fetchedItemsMinimal.value.size === 0) return true\n return ![...fetchedItemsMinimal.value.values()].some(\n (item) => item.name?.toLowerCase() === search.value!.toLowerCase()\n )\n})\n</script>\n\n<template>\n <div class=\"d-flex\">\n <ARow\n v-if=\"disabled && disabledAs === 'chips' && multiple\"\n :title=\"label\"\n >\n <AuthorRemoteAutocompleteCachedAuthorChip\n v-for=\"id in modelValueComputed\"\n :id=\"id\"\n :key=\"id\"\n :queue-id=\"queueId\"\n force-rounded\n class=\"mr-1 mb-1\"\n />\n </ARow>\n <ARow\n v-else-if=\"disabled && disabledAs === 'chips' && !multiple\"\n :title=\"label\"\n >\n <AuthorRemoteAutocompleteCachedAuthorChip\n :id=\"modelValueComputed\"\n :key=\"modelValueComputed\"\n :queue-id=\"queueId\"\n force-rounded\n />\n </ARow>\n <AFormRemoteAutocompleteWithCached\n v-else\n v-model=\"modelValueComputed\"\n v-model:search=\"search\"\n v-model:loading-local=\"loadingLocal\"\n v-model:fetched-items-minimal=\"fetchedItemsMinimal\"\n :use-cached=\"useCachedOfName\"\n :v=\"v$\"\n :required=\"requiredComputed\"\n :label=\"label\"\n :fetch-items-minimal=\"fetchItemsMinimal\"\n :multiple=\"multiple\"\n :clearable=\"clearable\"\n :disabled=\"disabled || undefined\"\n filter-by-field=\"text\"\n :filter-sort-by=\"null\"\n :data-cy=\"dataCy\"\n item-title=\"name\"\n item-value=\"id\"\n :min-search-chars=\"2\"\n min-search-text=\"common.damImage.author.filterMinChars\"\n @search-change=\"searchChange\"\n @keyup.enter=\"onEnterKeyup\"\n @keyup.,=\"onCommaKeyup\"\n >\n <template #item=\"{ props: itemSlotProps, item: itemSlotItem }\">\n <VListItem\n v-if=\"itemSlotItem\"\n v-bind=\"itemSlotProps\"\n @click.prevent=\"\"\n >\n <template\n v-if=\"multiple\"\n #prepend\n >\n <VCheckboxBtn\n :model-value=\"itemSlotIsSelected(itemSlotItem.value)\"\n :ripple=\"false\"\n />\n </template>\n <template #title>\n <AuthorRemoteAutocompleteCachedAuthorChip\n :id=\"itemSlotItem.value\"\n :key=\"itemSlotItem.value\"\n :queue-id=\"queueId\"\n :title=\"itemSlotItem.title\"\n text-only\n :force-reviewed=\"itemSlotItem.raw?.raw?.reviewed\"\n />\n </template>\n </VListItem>\n </template>\n <!--\n Pass only the chip's close. Its other props (`onMousedown`)\n would stop a press on the chip from opening the list.\n -->\n <template #chip=\"{ props: chipSlotProps, item: chipSlotItem }\">\n <AuthorRemoteAutocompleteCachedAuthorChip\n v-if=\"chipSlotItem\"\n :id=\"chipSlotItem.value\"\n :key=\"chipSlotItem.value\"\n :chip-props=\"{ 'onClick:close': chipSlotProps['onClick:close'] }\"\n :queue-id=\"queueId\"\n :title=\"chipSlotItem.title\"\n force-rounded\n />\n </template>\n <template #append-item>\n <VListItem\n v-if=\"showAdd\"\n class=\"a-authors-append-item\"\n >\n <ABtnSecondary\n size=\"small\"\n :text=\"addNewAuthorText\"\n prepend-icon=\"mdi-plus-circle\"\n @click.stop=\"onCommaKeyup\"\n />\n </VListItem>\n </template>\n </AFormRemoteAutocompleteWithCached>\n <div v-show=\"!disabled || disabledAs === 'input'\">\n <AuthorCreateButton\n v-if=\"createAllowed\"\n ref=\"authorCreateButton\"\n variant=\"icon\"\n :ext-system=\"extSystem\"\n data-cy=\"add-author\"\n :initial-value=\"addNewAuthorText\"\n disable-redirect\n :disabled=\"disabled\"\n @success=\"afterCreate\"\n />\n </div>\n </div>\n <div\n v-if=\"!disabled && offeredConflicts.length > 0\"\n class=\"d-flex flex-column\"\n >\n <div>\n <span class=\"text-body-small\">{{ t('common.damImage.author.conflicts') }}</span>\n </div>\n <div>\n <AuthorRemoteAutocompleteCachedAuthorChipConflicts\n v-for=\"authorId in offeredConflicts\"\n :id=\"authorId\"\n :key=\"authorId\"\n class=\"mr-1 mt-1\"\n @add-author=\"addAuthor(authorId)\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.a-authors-append-item {\n position: sticky;\n bottom: 0;\n // Use the menu surface color. A white bar showed in the dark theme.\n background-color: rgb(var(--v-theme-surface));\n transform: translateY(8px);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AuthorRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createElementVNode","_createBlock","ARow","_withCtx","_renderList","AuthorRemoteAutocompleteCachedAuthorChip","AFormRemoteAutocompleteWithCached","_unref","_withKeys","_component_VListItem","_mergeProps","_withModifiers","_createVNode","_component_VCheckboxBtn","_withDirectives","AuthorCreateButton","_vShow","_toDisplayString","AuthorRemoteAutocompleteCachedAuthorChipConflicts","AFormRemoteAutocompleteWithCached_default","AuthorRemoteAutocompleteCachedAuthorChip_default","AuthorRemoteAutocompleteCachedAuthorChipConflicts_default","AuthorCreateButton_default","ARow_default","useVuelidate","_hoisted_1","_hoisted_2","_hoisted_3","AuthorRemoteAutocompleteWithCached_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","damConfigName","useDamConfigName","modelValueComputed","computed","newValue","search","ref","loadingLocal","fetchedItemsMinimal","useI18n","requiredComputed","useValidate","rules","requiredIf","v$","useAuthorSelectActions","useCommonAdminCoreDamOptions","createAllowed","useAclAllowed","authorCreateAcl","useAuthorInnerFilter","provide","FilterInnerConfigKey","filterConfig","FilterInnerDataKey","filterData","offeredConflicts","isArray","id","addAuthor","addNewAuthorText","searchChange","removeLastComma","useDamCachedAuthors","useCachedOfName","useDamCachedAuthorsForRemoteAutocomplete","afterCreate","addManualToCachedAuthors","author","itemSlotIsSelected","item","authorCreateButton","value","onEnterKeyup","onCommaKeyup","showAdd","_component_ABtnSecondary","resolveComponent","openBlock","createElementBlock","Fragment","createElementVNode","createBlock","withCtx","renderList","_cache","$event","unref","fetchItemsMinimal","withKeys","itemSlotProps","itemSlotItem","VListItem","mergeProps","withModifiers","createSlots","createVNode","VCheckboxBtn","createCommentVNode","chipSlotProps","chipSlotItem","withDirectives","vShow","toDisplayString","t","authorId"],"sources":["../../../../../src/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { DocId, IntegerId } from '@/shared/types/common'\nimport type { ValidationScope } from '@/shared/types/Validation'\nimport { computed, provide, ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useValidate } from '@/shared/validators/vuelidate/useValidate'\nimport useVuelidate from '@vuelidate/core'\nimport {\n useDamCachedAuthors,\n useDamCachedAuthorsForRemoteAutocomplete,\n} from '@/domains/dam/author/composables/cachedAuthors'\nimport type { DamAuthor } from '@/domains/dam/author/types/DamAuthor'\nimport { isArray } from '@/shared/utils/common'\nimport AFormRemoteAutocompleteWithCached from '@/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue'\nimport AuthorRemoteAutocompleteCachedAuthorChip from '@/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue'\nimport AuthorRemoteAutocompleteCachedAuthorChipConflicts from '@/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.vue'\nimport { useAuthorSelectActions } from '@/domains/dam/author/composables/authorActions'\nimport AuthorCreateButton from '@/domains/dam/author/components/AuthorCreateButton.vue'\nimport ARow from '@/domains/ui/components/ARow.vue'\nimport { FilterInnerConfigKey, FilterInnerDataKey } from '@/domains/filters/utils/filterInjectionKeys'\nimport { useAuthorInnerFilter } from '@/domains/dam/author/filter/AuthorFilter'\nimport { useAclAllowed } from '@/domains/auth/composables/aclAllowed'\nimport { useCommonAdminCoreDamOptions } from '@/domains/dam/composables/commonAdminCoreDamOptions'\nimport type { DamFieldsDisabledAs } from '@/domains/dam/uploadQueue/components/uploadQueueBindings'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: DocId | null | DocId[] | any\n extSystem: IntegerId\n queueId?: string | undefined\n label?: string | undefined\n required?: boolean | null\n disabled?: boolean | undefined\n multiple?: boolean\n clearable?: boolean\n authorConflicts?: DocId[]\n dataCy?: string\n validationScope?: ValidationScope\n /** How a disabled field looks: author chips (current library behaviour), or the input and its \"+\" disabled. */\n disabledAs?: DamFieldsDisabledAs\n /** DAM configuration to use. Defaults to the parent component's, else `default`. */\n configName?: string\n }>(),\n {\n label: undefined,\n queueId: undefined,\n required: null,\n disabled: undefined,\n multiple: false,\n clearable: false,\n authorConflicts: undefined,\n dataCy: undefined,\n validationScope: undefined,\n disabledAs: 'chips',\n configName: undefined,\n }\n)\nconst emit = defineEmits<{\n (e: 'update:modelValue', data: DocId | null | DocId[]): void\n}>()\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\nconst modelValueComputed = computed({\n get() {\n return props.modelValue\n },\n set(newValue) {\n emit('update:modelValue', [...newValue])\n },\n})\n\nconst search = ref<string>('')\nconst loadingLocal = ref(false)\nconst fetchedItemsMinimal = ref<Map<IntegerId | DocId, any>>(new Map())\n\nconst { t } = useI18n()\n\nconst requiredComputed = computed(() => !!props.required)\n\nconst { requiredIf } = useValidate()\n\nconst rules = {\n modelValueComputed: {\n required: requiredIf(requiredComputed),\n },\n}\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst v$ = useVuelidate(rules, { modelValueComputed }, { $scope: props.validationScope })\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst { fetchItemsMinimal } = useAuthorSelectActions(props.extSystem, damConfigName)\n\nconst { authorCreateAcl } = useCommonAdminCoreDamOptions(damConfigName)\nconst createAllowed = useAclAllowed(authorCreateAcl ?? undefined)\n\nconst { filterData, filterConfig } = useAuthorInnerFilter()\nprovide(FilterInnerConfigKey, filterConfig)\nprovide(FilterInnerDataKey, filterData)\n\n// Authors the input already has are not offered again.\nconst offeredConflicts = computed(() =>\n (props.authorConflicts ?? []).filter((id) =>\n isArray(modelValueComputed.value) ? !modelValueComputed.value.includes(id) : modelValueComputed.value !== id\n )\n)\n\nconst addAuthor = async (id: null | DocId | undefined) => {\n if (!id) return\n if (!modelValueComputed.value.includes(id)) {\n modelValueComputed.value = [...modelValueComputed.value, id]\n }\n}\n\nconst addNewAuthorText = ref('')\n\nconst searchChange = (newValue: string) => {\n if (newValue.length > 0) addNewAuthorText.value = removeLastComma(newValue)\n}\n\nconst { addManualToCachedAuthors } = useDamCachedAuthors(damConfigName)\n// The inner input reads this cache only once.\nconst useCachedOfName = () => useDamCachedAuthorsForRemoteAutocomplete(damConfigName)\n\nconst afterCreate = (author: DamAuthor) => {\n addManualToCachedAuthors(author)\n if (isArray(modelValueComputed.value)) {\n modelValueComputed.value = [...modelValueComputed.value, author.id]\n search.value = ''\n return\n }\n modelValueComputed.value = author.id\n search.value = ''\n}\n\nconst itemSlotIsSelected = (item: DocId) => {\n if (isArray(modelValueComputed.value)) {\n return modelValueComputed.value.includes(item)\n } else if (modelValueComputed.value) {\n return modelValueComputed.value === item\n }\n return false\n}\n\nconst authorCreateButton = ref<InstanceType<typeof AuthorCreateButton> | null>(null)\n\nconst removeLastComma = (value: string) => {\n if (value.endsWith(',')) return value.slice(0, -1)\n return value\n}\n\nconst onEnterKeyup = () => {\n if (!createAllowed.value) return\n const value = removeLastComma(search.value)\n authorCreateButton.value?.open(value)\n}\n\nconst onCommaKeyup = () => {\n if (!createAllowed.value) return\n const value = removeLastComma(search.value)\n authorCreateButton.value?.open(value)\n}\n\nconst showAdd = computed(() => {\n if (!createAllowed.value) return false\n if (loadingLocal.value) return false\n if (search.value.length < 2 || search.value.length > 255) return false\n if (fetchedItemsMinimal.value.size === 0) return true\n return ![...fetchedItemsMinimal.value.values()].some(\n (item) => item.name?.toLowerCase() === search.value!.toLowerCase()\n )\n})\n</script>\n\n<template>\n <div class=\"d-flex\">\n <ARow\n v-if=\"disabled && disabledAs === 'chips' && multiple\"\n :title=\"label\"\n >\n <AuthorRemoteAutocompleteCachedAuthorChip\n v-for=\"id in modelValueComputed\"\n :id=\"id\"\n :key=\"id\"\n :queue-id=\"queueId\"\n force-rounded\n class=\"mr-1 mb-1\"\n />\n </ARow>\n <ARow\n v-else-if=\"disabled && disabledAs === 'chips' && !multiple\"\n :title=\"label\"\n >\n <AuthorRemoteAutocompleteCachedAuthorChip\n :id=\"modelValueComputed\"\n :key=\"modelValueComputed\"\n :queue-id=\"queueId\"\n force-rounded\n />\n </ARow>\n <AFormRemoteAutocompleteWithCached\n v-else\n v-model=\"modelValueComputed\"\n v-model:search=\"search\"\n v-model:loading-local=\"loadingLocal\"\n v-model:fetched-items-minimal=\"fetchedItemsMinimal\"\n :use-cached=\"useCachedOfName\"\n :v=\"v$\"\n :required=\"requiredComputed\"\n :label=\"label\"\n :fetch-items-minimal=\"fetchItemsMinimal\"\n :multiple=\"multiple\"\n :clearable=\"clearable\"\n :disabled=\"disabled || undefined\"\n filter-by-field=\"text\"\n :filter-sort-by=\"null\"\n :data-cy=\"dataCy\"\n item-title=\"name\"\n item-value=\"id\"\n :min-search-chars=\"2\"\n min-search-text=\"common.damImage.author.filterMinChars\"\n @search-change=\"searchChange\"\n @keyup.enter=\"onEnterKeyup\"\n @keyup.,=\"onCommaKeyup\"\n >\n <template #item=\"{ props: itemSlotProps, item: itemSlotItem }\">\n <VListItem\n v-if=\"itemSlotItem\"\n v-bind=\"itemSlotProps\"\n @click.prevent=\"\"\n >\n <template\n v-if=\"multiple\"\n #prepend\n >\n <VCheckboxBtn\n :model-value=\"itemSlotIsSelected(itemSlotItem.value)\"\n :ripple=\"false\"\n />\n </template>\n <template #title>\n <AuthorRemoteAutocompleteCachedAuthorChip\n :id=\"itemSlotItem.value\"\n :key=\"itemSlotItem.value\"\n :queue-id=\"queueId\"\n :title=\"itemSlotItem.title\"\n text-only\n :force-reviewed=\"itemSlotItem.raw?.raw?.reviewed\"\n />\n </template>\n </VListItem>\n </template>\n <!--\n Pass only the chip's close. Its other props (`onMousedown`)\n would stop a press on the chip from opening the list.\n -->\n <template #chip=\"{ props: chipSlotProps, item: chipSlotItem }\">\n <AuthorRemoteAutocompleteCachedAuthorChip\n v-if=\"chipSlotItem\"\n :id=\"chipSlotItem.value\"\n :key=\"chipSlotItem.value\"\n :chip-props=\"{ 'onClick:close': chipSlotProps['onClick:close'] }\"\n :queue-id=\"queueId\"\n :title=\"chipSlotItem.title\"\n force-rounded\n />\n </template>\n <template #append-item>\n <VListItem\n v-if=\"showAdd\"\n class=\"a-authors-append-item\"\n >\n <ABtnSecondary\n size=\"small\"\n :text=\"addNewAuthorText\"\n prepend-icon=\"mdi-plus-circle\"\n @click.stop=\"onCommaKeyup\"\n />\n </VListItem>\n </template>\n </AFormRemoteAutocompleteWithCached>\n <div v-show=\"!disabled || disabledAs === 'input'\">\n <AuthorCreateButton\n v-if=\"createAllowed\"\n ref=\"authorCreateButton\"\n variant=\"icon\"\n :ext-system=\"extSystem\"\n data-cy=\"add-author\"\n :initial-value=\"addNewAuthorText\"\n disable-redirect\n :disabled=\"disabled\"\n @success=\"afterCreate\"\n />\n </div>\n </div>\n <div\n v-if=\"!disabled && offeredConflicts.length > 0\"\n class=\"d-flex flex-column\"\n >\n <div>\n <span class=\"text-body-small\">{{ t('common.damImage.author.conflicts') }}</span>\n </div>\n <div>\n <AuthorRemoteAutocompleteCachedAuthorChipConflicts\n v-for=\"authorId in offeredConflicts\"\n :id=\"authorId\"\n :key=\"authorId\"\n class=\"mr-1 mt-1\"\n @add-author=\"addAuthor(authorId)\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.a-authors-append-item {\n position: sticky;\n bottom: 0;\n // Use the menu surface color. A white bar showed in the dark theme.\n background-color: rgb(var(--v-theme-surface));\n transform: translateY(8px);\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAuthorFilterRemoteAutocomplete.js","names":["
|
|
1
|
+
{"version":3,"file":"DamAuthorFilterRemoteAutocomplete.js","names":["DamAuthorFilterRemoteAutocomplete_vue_vue_type_script_setup_true_lang_default","DamAuthorFilterRemoteAutocomplete_default"],"sources":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAuthorFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","AFilterRemoteAutocompleteWithMinimal","_unref","_withCtx","_component_VListItem","_mergeProps","_createVNode","_component_VListItemTitle","_createTextVNode","_toDisplayString","_component_VIcon","
|
|
1
|
+
{"version":3,"file":"DamAuthorFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","AFilterRemoteAutocompleteWithMinimal","_unref","_withCtx","_component_VListItem","_mergeProps","_createVNode","_component_VListItemTitle","_createTextVNode","_toDisplayString","_component_VIcon","_component_VChip","AFilterRemoteAutocompleteWithMinimal_default","DamAuthorFilterRemoteAutocomplete_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","damConfigName","useDamConfigName","useAuthorSelectActions","useAuthorInnerFilter","provide","FilterInnerConfigKey","filterConfig","FilterInnerDataKey","filterData","useI18n","openBlock","createBlock","unref","fetchItemsMinimal","fetchItemsMinimalByIds","_cache","withCtx","itemProps","itemItem","VListItem","mergeProps","createVNode","VListItemTitle","createTextVNode","toDisplayString","VIcon","t","createCommentVNode","chipProps","chipItem","VChip"],"sources":["../../../../../src/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useAuthorSelectActions } from '@/domains/dam/author/composables/authorActions'\nimport { useAuthorInnerFilter } from '@/domains/dam/author/filter/AuthorFilter'\nimport type { IntegerId } from '@/shared/types/common'\nimport { useI18n } from 'vue-i18n'\nimport AFilterRemoteAutocompleteWithMinimal from '@/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.vue'\nimport { provide } from 'vue'\nimport { FilterInnerConfigKey, FilterInnerDataKey } from '@/domains/filters/utils/filterInjectionKeys'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n name: string\n extSystem: IntegerId\n /** DAM configuration to use. Defaults to the parent component's, else `default`. */\n configName?: string\n }>(),\n {\n configName: undefined,\n }\n)\nconst emit = defineEmits<{\n (e: 'change'): void\n}>()\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst { fetchItemsMinimal, fetchItemsMinimalByIds } = useAuthorSelectActions(props.extSystem, damConfigName)\n\nconst { filterData, filterConfig } = useAuthorInnerFilter()\nprovide(FilterInnerConfigKey, filterConfig)\nprovide(FilterInnerDataKey, filterData)\n\nconst { t } = useI18n()\n</script>\n\n<template>\n <AFilterRemoteAutocompleteWithMinimal\n :name=\"name\"\n :fetch-items-minimal=\"fetchItemsMinimal\"\n :fetch-items-minimal-by-ids=\"fetchItemsMinimalByIds\"\n filter-by-field=\"text\"\n :filter-sort-by=\"null\"\n @change=\"emit('change')\"\n >\n <template #item=\"{ props: itemProps, item: itemItem }\">\n <VListItem\n v-if=\"itemItem\"\n v-bind=\"itemProps\"\n title=\"\"\n >\n <VListItemTitle>\n {{ itemItem.title }}\n <VIcon\n v-if=\"itemItem.raw?.raw?.reviewed || itemItem.raw?.reviewed\"\n icon=\"mdi-shield-check\"\n class=\"text-success ml-1\"\n size=\"small\"\n :title=\"t('common.damImage.author.model.flags.reviewed')\"\n />\n </VListItemTitle>\n </VListItem>\n </template>\n <template #chip=\"{ props: chipProps, item: chipItem }\">\n <VChip\n v-if=\"chipItem\"\n v-bind=\"chipProps\"\n close-label=\"common.button.remove\"\n >\n {{ chipItem.title }}\n <VIcon\n v-if=\"chipItem.raw?.raw?.reviewed || chipItem.raw?.reviewed\"\n icon=\"mdi-shield-check\"\n class=\"text-success ml-1\"\n size=\"small\"\n :title=\"t('common.damImage.author.model.flags.reviewed')\"\n />\n </VChip>\n </template>\n </AFilterRemoteAutocompleteWithMinimal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAUA,IAAMgB,IAAQC,GAWRC,IAAOH,GAIPI,IAAgBC,EAAiBJ,EAAM,UAAU,GAGjD,EAAE,sBAAmB,8BAA2BK,EAAuBL,EAAM,WAAWG,CAAa,GAErG,EAAE,eAAY,oBAAiBG,EAAqB;EAE1D,AADAC,EAAQC,GAAsBC,CAAY,GAC1CF,EAAQG,GAAoBC,CAAU;EAEtC,IAAM,EAAE,SAAMC,EAAQ;E,kBAIpB5B,EAAA,GAAAC,EA0CuCC,GAAA;GAzCpC,MAAMe,EAAA;GACN,uBAAqBd,EAAA6B,CAAA;GACrB,8BAA4B7B,EAAA8B,CAAA;GAC7B,mBAAgB;GACf,kBAAgB;GAChB,UAAM,AAAAC,EAAA,QAAA,MAAEhB,EAAI,QAAA;;GAEF,MAAId,GAgBD,EAAA,OAhBYgC,GAAS,MAAQC,QAAQ,CAEzCA,KADRrC,EAAA,GAAAC,EAeYI,GAfZC,EAeY,EAAA,KAAA,EAAA,GAbF8B,GAAS,EACjB,OAAM,GAAE,CAAA,GAAA;IAER,SAAAhC,QASiB,CATjBG,EASiBC,GAAA,MAAA;KARf,SAAAJ,QAAoB,CAAjBK,EAAAC,EAAA2B,EAAS,KAAK,IAAG,KACpB,CAAA,GACQA,EAAS,KAAK,KAAK,YAAYA,EAAS,KAAK,YADrDrC,EAAA,GAAAC,EAMEU,GAAA;;MAJA,MAAK;MACL,OAAM;MACN,MAAK;MACJ,OAAOR,EAAA0C,CAAA,CAAC,CAAA,6CAAA;;;;;;GAKN,MAAIzC,GAcL,EAAA,OAdgB2C,GAAS,MAAQC,QAAQ,CAEzCA,KADRhD,EAAA,GAAAC,EAaQW,GAbRN,EAaQ,EAAA,KAAA,EAAA,GAXEyC,GAAS,EACjB,eAAY,uBAAsB,CAAA,GAAA;IAElC,SAAA3C,QAAoB,CAAjBK,EAAAC,EAAAsC,EAAS,KAAK,IAAG,KACpB,CAAA,GACQA,EAAS,KAAK,KAAK,YAAYA,EAAS,KAAK,YADrDhD,EAAA,GAAAC,EAMEU,GAAA;;KAJA,MAAK;KACL,OAAM;KACN,MAAK;KACJ,OAAOR,EAAA0C,CAAA,CAAC,CAAA,6CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAdminAssetLink.js","names":["
|
|
1
|
+
{"version":3,"file":"DamAdminAssetLink.js","names":["DamAdminAssetLink_vue_vue_type_script_setup_true_lang_default","DamAdminAssetLink_default"],"sources":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ACropper.js","names":["_sfc_main","ACropper_vue_vue_type_script_setup_true_lang_default","ACropper_default"],"sources":["../../../../../src/domains/dam/cropper/components/ACropper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport {\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n} from 'cropperjs'\nimport {\n canvasSizeFor,\n clampRectInside,\n initialSelectionRect,\n isUsableAspectRatio,\n RESIZE_ANCHORS,\n rectsAreClose,\n type Rect,\n type Size,\n} from '@/domains/dam/cropper/utils/cropperGeometry'\nimport type { CropRect } from '@/domains/dam/cropper/utils/cropperTypes'\n\n/**\n * Image cropper built on cropper.js v2 custom elements. Replaces the v1-based `ACropperjs`.\n * Not exported. Its only user is `DamAssetImageRoiSelect`, and it is shaped to that one need.\n * The crop is bound via `v-model` as fractions of the image.\n * `commit` signals that a gesture ended. There is no imperative API.\n * Elements are built in script, not the template. Consumers do not configure `isCustomElement`,\n * and setting properties avoids attribute coercion issues (`NaN`, booleans, fractions).\n */\n\nconst props = withDefaults(\n defineProps<{\n src?: string\n /** The crop as fractions of the image. Null starts from the default box. */\n modelValue?: CropRect | null\n /** `NaN` (the default) leaves the crop free-form. */\n aspectRatio?: number\n containerStyle?: { [key: string]: string } | undefined\n /** Colour over everything outside the crop. Replaces overriding `.cropper-modal`. */\n shadeColor?: string\n }>(),\n {\n src: '',\n modelValue: null,\n aspectRatio: NaN,\n containerStyle: undefined,\n shadeColor: 'rgba(0, 0, 0, 0.5)',\n }\n)\n\nconst emit = defineEmits<{\n (event: 'update:modelValue', crop: CropRect): void\n /** The user finished a gesture. The crop is worth saving. */\n (event: 'commit', crop: CropRect): void\n (event: 'ready'): void\n}>()\n\n// cropper.js registers its elements as a side effect of its entry module. Our `sideEffects`\n// setting lets the consumer's bundler drop that module, so register them here.\n// `$define` is a no-op for an already registered element.\nfor (const element of [\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n]) {\n element.$define()\n}\n\n/**\n * Settings the only caller never varies. Each is behaviour: no checkerboard behind a photo, wheel left\n * to the page, pinch zoom kept for tablets, and the minimum canvas size from cropper.js' stylesheet.\n */\nconst AUTO_CROP_AREA = 0.8\nconst MIN_CONTAINER_WIDTH = 200\nconst MIN_CONTAINER_HEIGHT = 100\n\n// Matches cropper.js v1's stylesheet so both components look the same.\nconst SELECTION_COLOR = 'rgba(51, 153, 255, 0.75)'\nconst FACE_COLOR = 'rgba(255, 255, 255, 0.1)'\nconst GRID_COLOR = 'rgba(238, 238, 238, 0.5)'\nconst CROSSHAIR_COLOR = 'rgba(238, 238, 238, 0.75)'\nconst RESIZE_ACTIONS = [\n 'n-resize',\n 'e-resize',\n 's-resize',\n 'w-resize',\n 'ne-resize',\n 'nw-resize',\n 'se-resize',\n 'sw-resize',\n]\n\ninterface CropperParts {\n canvas: CropperCanvas\n image: CropperImage\n selection: CropperSelection\n}\n\nconst hostEl = useTemplateRef<HTMLDivElement>('hostEl')\nconst loading = ref(true)\n\nlet parts: CropperParts | null = null\nlet natural: Size = { width: 0, height: 0 }\n/** The action cropper.js is performing, so a clamp knows which edge to hold still. */\nlet currentAction: string | null = null\n/** Guards the re-entrant `$change` a clamp performs from being clamped again. */\nlet clamping = false\n/** Ignores the half-applied transforms `$center` emits between its move and its scale. */\nlet centring = false\n/** Invalidates an in-flight build when `src` changes or the component goes away mid-load. */\nlet buildToken = 0\n/** The host box the current layout was computed for, not the last one observed. */\nlet laidOut: Size = { width: 0, height: 0 }\n/** The last emitted crop, so a model written straight back is not treated as new. */\nlet lastEmitted: CropRect | null = null\n/** Watches ancestors that clip the host. Their height limits the available room. */\nlet ancestorObserver: ResizeObserver | null = null\n\nconst create = <T extends HTMLElement>(name: string): T => document.createElement(name) as T\n\n/** The image box in canvas coordinates. Read from layout so panning and zooming are included. */\nconst imageBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const canvasRect = parts.canvas.getBoundingClientRect()\n const imageRect = parts.image.getBoundingClientRect()\n return {\n x: imageRect.left - canvasRect.left,\n y: imageRect.top - canvasRect.top,\n width: imageRect.width,\n height: imageRect.height,\n }\n}\n\n/**\n * Where the crop may be: the image, but never outside the visible canvas.\n * They differ only when the image is zoomed past its frame. Then the frame wins, as in cropper.js v1.\n */\nconst constraintBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const image = imageBounds()\n const canvas = parts.canvas.getBoundingClientRect()\n const left = Math.max(image.x, 0)\n const top = Math.max(image.y, 0)\n const right = Math.min(image.x + image.width, canvas.width)\n const bottom = Math.min(image.y + image.height, canvas.height)\n return { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) }\n}\n\nconst selectionRect = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const { x, y, width, height } = parts.selection\n return { x, y, width, height }\n}\n\nconst applyRect = (rect: Rect) => {\n if (!parts) return\n clamping = true\n parts.selection.$change(rect.x, rect.y, rect.width, rect.height, props.aspectRatio, true)\n clamping = false\n}\n\n/**\n * Re-fits the image to the canvas.\n * `$center` only scales and moves an image marked scalable and translatable. cropper.js allows\n * this itself only while loading, so the flags are set for the call and restored after.\n */\nconst centerImage = () => {\n if (!parts) return\n const { image } = parts\n const { scalable, translatable } = image\n centring = true\n image.scalable = true\n image.translatable = true\n image.$center('contain')\n image.scalable = scalable\n image.translatable = translatable\n centring = false\n}\n\n/**\n * The initial crop of a new picture. Not using cropper.js' `initialCoverage`,\n * because its deferred init runs after a `ready` handler has positioned the crop.\n * Measured against the image, not the canvas. They differ when the image is centred between margins.\n */\nconst seedInitialCrop = () => {\n if (!parts) return\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return\n const initial = initialSelectionRect(bounds, props.aspectRatio, AUTO_CROP_AREA)\n applyRect({ ...initial, x: initial.x + bounds.x, y: initial.y + bounds.y })\n}\n\nconst applyModelOrSeed = () => {\n const model = props.modelValue\n if (model && model.width > 0 && model.height > 0) applyCrop(model)\n else seedInitialCrop()\n emitCrop()\n}\n\n/** Pulls the selection back inside the image after the image moved. */\nconst refit = () => {\n if (!parts || centring) return\n const current = selectionRect()\n if (current.width <= 0 || current.height <= 0) return\n const fitted = clampRectInside(current, constraintBounds(), props.aspectRatio)\n if (!rectsAreClose(current, fitted)) applyRect(fitted)\n}\n\nconst onSelectionChange = (event: Event) => {\n if (clamping || !parts) return\n const detail = (event as CustomEvent<Rect>).detail\n if (!detail) return\n // cropper.js reverses the action when a grip is dragged past the opposite edge. It records\n // this on the canvas before emitting this event, one move ahead of the `action` event.\n // Prefer that value, and fall back in case a future version stops setting it.\n const liveAction = (parts.canvas as unknown as { $action?: unknown }).$action\n const action = typeof liveAction === 'string' && liveAction ? liveAction : currentAction\n const anchor = action ? RESIZE_ANCHORS[action] : undefined\n const clamped = clampRectInside(detail, constraintBounds(), props.aspectRatio, anchor)\n if (rectsAreClose(detail, clamped)) return\n // Rejecting the change and applying the clamped one keeps the crop sliding along the border instead of freezing.\n // The shade reads `defaultPrevented` and follows the new values.\n event.preventDefault()\n applyRect(clamped)\n}\n\nconst onActionStart = (event: Event) => {\n currentAction = (event as CustomEvent<{ action?: string }>).detail?.action ?? null\n}\n\nconst onAction = (event: Event) => {\n const action = (event as CustomEvent<{ action?: string }>).detail?.action\n // cropper.js turns a new \"select\" drag into a corner resize once the direction is known.\n // It reports the new action on the next move. Follow it so the anchor stays correct.\n if (action) currentAction = action\n}\n\nconst onActionEnd = () => {\n currentAction = null\n emitCrop(true)\n}\n\n/**\n * The canvas must never see a wheel event. Its handler always calls\n * `preventDefault()`, which would block page scrolling over the picture.\n * Pinch zoom still works because it arrives as pointer events.\n */\nconst onWheelCapture = (event: WheelEvent) => {\n event.stopPropagation()\n}\n\n/**\n * cropper.js emits `transform` before it writes the new matrix to the element style.\n * Re-fitting at once would measure the old image. After a zoom out the crop would hang over the edge of the new one.\n */\nconst onImageTransform = () => queueMicrotask(refit)\n\nconst teardown = () => {\n if (parts) {\n const { canvas, image, selection } = parts\n selection.removeEventListener('change', onSelectionChange)\n canvas.removeEventListener('actionstart', onActionStart)\n canvas.removeEventListener('action', onAction)\n canvas.removeEventListener('actionend', onActionEnd)\n image.removeEventListener('transform', onImageTransform)\n }\n // Every canvas, not only the one on `parts`. A superseded build still waiting\n // on its image has already added one to the DOM, and nothing tracks it.\n hostEl.value?.querySelectorAll(CropperCanvas.$name).forEach((canvas) => {\n // Disconnecting a `cropper-image` drops its listeners but keeps its request running.\n // The pending `$ready()` promise keeps this component alive until the server answers.\n canvas.querySelectorAll<CropperImage>(CropperImage.$name).forEach((image) => {\n if (image.$image) image.$image.src = ''\n })\n canvas.remove()\n })\n ancestorObserver?.disconnect()\n ancestorObserver = null\n parts = null\n natural = { width: 0, height: 0 }\n laidOut = { width: 0, height: 0 }\n currentAction = null\n}\n\n/**\n * How much of the host's height is actually shown.\n * Usually the host's own `max-height`, which `DamAssetImageRoiSelect` relies on. Ancestors\n * with `overflow: hidden` count too, because what they cut off cannot be scrolled into view.\n * Scrolling ancestors are ignored. There the rest is reachable by scrolling.\n */\nconst clippingAncestorsOf = (host: HTMLElement): HTMLElement[] => {\n const found: HTMLElement[] = []\n let ancestor = host.parentElement\n while (ancestor && ancestor !== document.body && ancestor !== document.documentElement) {\n const { overflowY } = window.getComputedStyle(ancestor)\n if (overflowY === 'hidden' || overflowY === 'clip') found.push(ancestor)\n ancestor = ancestor.parentElement\n }\n return found\n}\n\nconst visibleHeightOf = (host: HTMLElement): number => {\n let available = host.clientHeight\n const hostTop = host.getBoundingClientRect().top\n\n clippingAncestorsOf(host).forEach((ancestor) => {\n const rect = ancestor.getBoundingClientRect()\n // From where the host becomes visible to where the ancestor stops showing content.\n // The ancestor's top matters when the host starts above it.\n // Content off the top is as unreachable as content off the bottom.\n const room = rect.bottom - Math.max(rect.top, hostTop)\n if (room > 0) available = Math.min(available, room)\n })\n\n return available\n}\n\n/**\n * Sizes the canvas to the room the host gives it, in two passes.\n * The picture's height follows from its width, but a frame with\n * `max-height` only shows how much it reveals once it has content.\n * This keeps a tall picture in a short frame scaled to fit, as in v1. A\n * part cut off by `overflow: hidden` could not be reached by the crop.\n */\nconst sizeCanvas = (canvas: CropperCanvas, host: HTMLElement, availableWidth: number): Size => {\n const size = canvasSizeFor(natural, availableWidth, MIN_CONTAINER_WIDTH, MIN_CONTAINER_HEIGHT)\n canvas.style.width = `${size.width}px`\n canvas.style.height = `${size.height}px`\n\n const visibleHeight = visibleHeightOf(host)\n if (visibleHeight > 0 && visibleHeight < size.height) {\n size.height = Math.max(visibleHeight, MIN_CONTAINER_HEIGHT)\n canvas.style.height = `${size.height}px`\n }\n return size\n}\n\nconst buildSelectionChildren = (selection: CropperSelection) => {\n const grid = create<CropperGrid>(CropperGrid.$name)\n grid.rows = 3\n grid.columns = 3\n grid.covered = true\n grid.themeColor = GRID_COLOR\n grid.setAttribute('role', 'grid')\n selection.appendChild(grid)\n\n const crosshair = create<CropperCrosshair>(CropperCrosshair.$name)\n crosshair.centered = true\n crosshair.themeColor = CROSSHAIR_COLOR\n selection.appendChild(crosshair)\n\n const face = create<CropperHandle>(CropperHandle.$name)\n face.action = 'move'\n face.themeColor = FACE_COLOR\n selection.appendChild(face)\n\n RESIZE_ACTIONS.forEach((action) => {\n const handle = create<CropperHandle>(CropperHandle.$name)\n handle.action = action\n handle.themeColor = SELECTION_COLOR\n selection.appendChild(handle)\n })\n}\n\nconst build = async () => {\n const token = ++buildToken\n teardown()\n loading.value = true\n\n const host = hostEl.value\n if (!host || !props.src) {\n // Nothing to load. A visible spinner would make an empty cropper look stuck.\n loading.value = false\n return\n }\n\n const canvas = create<CropperCanvas>(CropperCanvas.$name)\n canvas.background = false\n canvas.themeColor = SELECTION_COLOR\n canvas.style.display = 'block'\n sizeCanvas(canvas, host, host.clientWidth)\n\n const image = create<CropperImage>(CropperImage.$name)\n image.alt = ''\n image.initialFit = 'contain'\n image.rotatable = false\n image.skewable = false\n image.translatable = false\n image.scalable = true\n image.src = props.src\n\n const shade = create<CropperShade>(CropperShade.$name)\n shade.themeColor = props.shadeColor\n // Hidden until the first crop box exists, or it would flash across the whole canvas.\n shade.hidden = true\n\n const selectHandle = create<CropperHandle>(CropperHandle.$name)\n selectHandle.action = 'select'\n selectHandle.plain = true\n\n const selection = create<CropperSelection>(CropperSelection.$name)\n selection.themeColor = SELECTION_COLOR\n selection.movable = true\n selection.resizable = true\n selection.outlined = true\n // Keep sub-pixel values. Rounding would drift the natural-pixel crop data that callers persist.\n selection.precise = true\n selection.aspectRatio = props.aspectRatio\n buildSelectionChildren(selection)\n\n // Listeners are added before anything is connected, so the current\n // action is known before the elements' own handlers react.\n canvas.addEventListener('actionstart', onActionStart)\n canvas.addEventListener('action', onAction)\n canvas.addEventListener('actionend', onActionEnd)\n image.addEventListener('transform', onImageTransform)\n selection.addEventListener('change', onSelectionChange)\n\n canvas.append(image, shade, selectHandle, selection)\n // Attach the whole tree at once. Each element links to its\n // siblings on connect, and the shade looks for the selection.\n // Appending children one by one leaves the shade on an empty canvas, and it never follows the crop.\n host.appendChild(canvas)\n // Second pass, now that the host has content for its constraints to act on.\n sizeCanvas(canvas, host, host.clientWidth)\n\n let loaded: HTMLImageElement\n try {\n // The element makes the only request. Its promise returns the loaded picture.\n loaded = await image.$ready()\n } catch {\n // Matches cropper.js v1, which never became ready on a broken source.\n canvas.remove()\n if (token === buildToken) loading.value = false\n return\n }\n if (token !== buildToken) {\n canvas.remove()\n return\n }\n\n parts = { canvas, image, selection }\n // The natural size is known only now. Sizing here avoids a separate request just to measure the image.\n natural = { width: loaded.naturalWidth, height: loaded.naturalHeight }\n sizeCanvas(canvas, host, host.clientWidth)\n\n // A prop changed during loading found no elements for the watchers to\n // update. Re-apply the two variable props. This is idempotent otherwise.\n shade.themeColor = props.shadeColor\n selection.aspectRatio = props.aspectRatio\n\n centerImage()\n\n laidOut = hostBox(host)\n observeAncestors(host)\n applyModelOrSeed()\n\n loading.value = false\n emit('ready')\n}\n\nconst currentCrop = (): CropRect | null => {\n if (!parts) return null\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return null\n const rect = selectionRect()\n return {\n x: (rect.x - bounds.x) / bounds.width,\n y: (rect.y - bounds.y) / bounds.height,\n width: rect.width / bounds.width,\n height: rect.height / bounds.height,\n }\n}\n\n/** Applies a crop given in fractions to the canvas, clamped to the picture. */\nconst applyCrop = (crop: CropRect) => {\n const bounds = imageBounds()\n if (!parts || bounds.width <= 0 || bounds.height <= 0) return\n applyRect(\n clampRectInside(\n {\n x: bounds.x + crop.x * bounds.width,\n y: bounds.y + crop.y * bounds.height,\n width: crop.width * bounds.width,\n height: crop.height * bounds.height,\n },\n constraintBounds(),\n props.aspectRatio\n )\n )\n}\n\nconst cropsAreClose = (a: CropRect | null, b: CropRect | null): boolean =>\n a !== null &&\n b !== null &&\n Math.abs(a.x - b.x) < 0.0005 &&\n Math.abs(a.y - b.y) < 0.0005 &&\n Math.abs(a.width - b.width) < 0.0005 &&\n Math.abs(a.height - b.height) < 0.0005\n\n/**\n * Emits the crop. Also called after the component adjusts the crop itself. A stored region\n * rarely matches the configured ratio, and the binding should show the actual crop.\n */\nconst emitCrop = (alsoCommit = false) => {\n const crop = currentCrop()\n if (!crop) return\n if (alsoCommit || !cropsAreClose(crop, lastEmitted)) {\n lastEmitted = crop\n emit('update:modelValue', crop)\n }\n if (alsoCommit) emit('commit', crop)\n}\n\n/** The host's room: its width and the height that is actually shown. */\nconst hostBox = (host: HTMLElement): Size => ({ width: host.clientWidth, height: visibleHeightOf(host) })\n\n/** Re-fits the image to the new container and keeps the user's crop. */\nconst relayout = () => {\n const host = hostEl.value\n if (!parts || !host) return\n // No crop means the last layout had no size. Fall back to the bound\n // crop, which a cropper built inside a closed panel has held all along.\n const wanted = currentCrop() ?? props.modelValue\n\n const size = sizeCanvas(parts.canvas, host, host.clientWidth)\n laidOut = hostBox(host)\n // Re-read the ancestors too. A cropper can move between frames,\n // and the current clipping ancestor is the one that matters.\n observeAncestors(host)\n centerImage()\n if (size.width <= 0 || size.height <= 0) return\n\n if (wanted && wanted.width > 0) applyCrop(wanted)\n else applyModelOrSeed()\n emitCrop()\n}\n\nconst onHostBoxChanged = () => {\n const host = hostEl.value\n if (!host) return\n const box = hostBox(host)\n if (box.width <= 0 || box.height <= 0) return\n // Compare with the box the current layout was built for, so a\n // size seen during loading is not treated as already laid out.\n if (box.width === laidOut.width && box.height === laidOut.height) return\n if (!parts) return\n // Deferred a frame. Resizing the canvas inside the observer\n // callback makes Chromium report an undelivered-notification loop.\n requestAnimationFrame(() => relayout())\n}\n\n// Height matters as much as width. The DAM sizes the cropper with `calc(100vh\n// - 160px)`, so a shorter window shrinks the frame without changing its width.\nuseResizeObserver(hostEl, onHostBoxChanged)\n\n/** A clipping ancestor can change how much it shows without the host box changing. */\nconst observeAncestors = (host: HTMLElement) => {\n ancestorObserver?.disconnect()\n const ancestors = clippingAncestorsOf(host)\n if (ancestors.length === 0) {\n ancestorObserver = null\n return\n }\n ancestorObserver = new ResizeObserver(onHostBoxChanged)\n ancestors.forEach((ancestor) => ancestorObserver?.observe(ancestor))\n}\n\nwatch(\n () => props.src,\n () => {\n build()\n }\n)\n\nwatch(\n () => props.modelValue,\n (model) => {\n // Ignore the echo of the crop just emitted. Otherwise parent and component would keep writing to each other.\n if (!parts || !model || cropsAreClose(model, lastEmitted)) return\n applyCrop(model)\n emitCrop()\n },\n { deep: true }\n)\n\nwatch(\n () => props.shadeColor,\n (shadeColor) => {\n const shade = parts?.canvas.querySelector<CropperShade>(CropperShade.$name)\n if (shade) shade.themeColor = shadeColor\n }\n)\n\nwatch(\n () => props.aspectRatio,\n (aspectRatio) => {\n if (!parts) return\n parts.selection.aspectRatio = aspectRatio\n if (!isUsableAspectRatio(aspectRatio)) return\n const current = selectionRect()\n applyRect(clampRectInside({ ...current, height: current.width / aspectRatio }, constraintBounds(), aspectRatio))\n }\n)\n\nonMounted(() => {\n build()\n})\n\nonBeforeUnmount(() => {\n buildToken += 1\n teardown()\n})\n</script>\n\n<template>\n <div class=\"a-cropper d-flex flex-column\">\n <div\n v-if=\"loading\"\n class=\"d-flex w-100 align-center justify-center\"\n >\n <VProgressCircular\n class=\"position-absolute\"\n indeterminate\n />\n </div>\n\n <div\n ref=\"hostEl\"\n class=\"a-cropper__container\"\n :style=\"containerStyle\"\n @wheel.capture=\"onWheelCapture\"\n />\n </div>\n</template>\n\n<style lang=\"scss\">\n// Full width even as a flex item, such as in the asset detail dialog. The canvas is sized from the\n// host's width, and a shrink-wrapped root has none to give, so every picture got the 200px minimum.\n.a-cropper {\n width: 100%;\n}\n\n// `cropper-crosshair` is sized in `em`. Without its own size the centre marker would scale with the admin's font.\n// 7px matches the plus sign of v1's `.cropper-center`.\n.a-cropper cropper-crosshair {\n font-size: 7px;\n}\n\n// Recreates v1's `.cropper-line` on each crop edge: a 5px band of the selection colour at 10%\n// opacity, 3px outside and 2px inside the border. It makes the outline read as a grabbable edge.\n// Drawn as two shadows, so it does not depend on the v2 grip sizes.\n.a-cropper cropper-selection[outlined] {\n box-shadow:\n inset 0 0 0 2px rgb(51 153 255 / 10%),\n 0 0 0 3px rgb(51 153 255 / 10%);\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ACropper.js","names":["ACropper_vue_vue_type_script_setup_true_lang_default","ACropper_default"],"sources":[],"mappings":""}
|
package/dist/domains/dam/cropper/components/ACropper.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ACropper.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_component_VProgressCircular","_createCommentVNode","_createElementVNode","_normalizeStyle","CropperCanvas","CropperImage","CropperShade","CropperHandle","CropperSelection","CropperGrid","CropperCrosshair","_hoisted_1","_hoisted_2","AUTO_CROP_AREA","MIN_CONTAINER_WIDTH","MIN_CONTAINER_HEIGHT","SELECTION_COLOR","FACE_COLOR","GRID_COLOR","CROSSHAIR_COLOR","ACropper_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","element","RESIZE_ACTIONS","hostEl","useTemplateRef","loading","ref","parts","natural","currentAction","clamping","centring","buildToken","laidOut","lastEmitted","ancestorObserver","create","name","imageBounds","canvasRect","imageRect","constraintBounds","image","canvas","left","top","right","bottom","selectionRect","applyRect","rect","centerImage","scalable","translatable","seedInitialCrop","bounds","initial","initialSelectionRect","applyModelOrSeed","model","applyCrop","emitCrop","refit","current","fitted","clampRectInside","rectsAreClose","onSelectionChange","detail","event","liveAction","action","anchor","RESIZE_ANCHORS","clamped","onActionStart","onAction","onActionEnd","onWheelCapture","onImageTransform","teardown","selection","clippingAncestorsOf","found","ancestor","host","overflowY","visibleHeightOf","available","hostTop","room","sizeCanvas","size","canvasSizeFor","availableWidth","visibleHeight","buildSelectionChildren","grid","crosshair","face","handle","build","token","shade","selectHandle","loaded","hostBox","observeAncestors","currentCrop","crop","cropsAreClose","a","b","alsoCommit","relayout","wanted","onHostBoxChanged","box","ancestors","watch","shadeColor","aspectRatio","isUsableAspectRatio","onMounted","onBeforeUnmount","openBlock","createElementBlock","createVNode","VProgressCircular","createCommentVNode","createElementVNode","normalizeStyle"],"sources":["../../../../../src/domains/dam/cropper/components/ACropper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport {\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n} from 'cropperjs'\nimport {\n canvasSizeFor,\n clampRectInside,\n initialSelectionRect,\n isUsableAspectRatio,\n RESIZE_ANCHORS,\n rectsAreClose,\n type Rect,\n type Size,\n} from '@/domains/dam/cropper/utils/cropperGeometry'\nimport type { CropRect } from '@/domains/dam/cropper/utils/cropperTypes'\n\n/**\n * Image cropper built on cropper.js v2 custom elements. Replaces the v1-based `ACropperjs`.\n * Not exported. Its only user is `DamAssetImageRoiSelect`, and it is shaped to that one need.\n * The crop is bound via `v-model` as fractions of the image.\n * `commit` signals that a gesture ended. There is no imperative API.\n * Elements are built in script, not the template. Consumers do not configure `isCustomElement`,\n * and setting properties avoids attribute coercion issues (`NaN`, booleans, fractions).\n */\n\nconst props = withDefaults(\n defineProps<{\n src?: string\n /** The crop as fractions of the image. Null starts from the default box. */\n modelValue?: CropRect | null\n /** `NaN` (the default) leaves the crop free-form. */\n aspectRatio?: number\n containerStyle?: { [key: string]: string } | undefined\n /** Colour over everything outside the crop. Replaces overriding `.cropper-modal`. */\n shadeColor?: string\n }>(),\n {\n src: '',\n modelValue: null,\n aspectRatio: NaN,\n containerStyle: undefined,\n shadeColor: 'rgba(0, 0, 0, 0.5)',\n }\n)\n\nconst emit = defineEmits<{\n (event: 'update:modelValue', crop: CropRect): void\n /** The user finished a gesture. The crop is worth saving. */\n (event: 'commit', crop: CropRect): void\n (event: 'ready'): void\n}>()\n\n// cropper.js registers its elements as a side effect of its entry module. Our `sideEffects`\n// setting lets the consumer's bundler drop that module, so register them here.\n// `$define` is a no-op for an already registered element.\nfor (const element of [\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n]) {\n element.$define()\n}\n\n/**\n * Settings the only caller never varies. Each is behaviour: no checkerboard behind a photo, wheel left\n * to the page, pinch zoom kept for tablets, and the minimum canvas size from cropper.js' stylesheet.\n */\nconst AUTO_CROP_AREA = 0.8\nconst MIN_CONTAINER_WIDTH = 200\nconst MIN_CONTAINER_HEIGHT = 100\n\n// Matches cropper.js v1's stylesheet so both components look the same.\nconst SELECTION_COLOR = 'rgba(51, 153, 255, 0.75)'\nconst FACE_COLOR = 'rgba(255, 255, 255, 0.1)'\nconst GRID_COLOR = 'rgba(238, 238, 238, 0.5)'\nconst CROSSHAIR_COLOR = 'rgba(238, 238, 238, 0.75)'\nconst RESIZE_ACTIONS = [\n 'n-resize',\n 'e-resize',\n 's-resize',\n 'w-resize',\n 'ne-resize',\n 'nw-resize',\n 'se-resize',\n 'sw-resize',\n]\n\ninterface CropperParts {\n canvas: CropperCanvas\n image: CropperImage\n selection: CropperSelection\n}\n\nconst hostEl = useTemplateRef<HTMLDivElement>('hostEl')\nconst loading = ref(true)\n\nlet parts: CropperParts | null = null\nlet natural: Size = { width: 0, height: 0 }\n/** The action cropper.js is performing, so a clamp knows which edge to hold still. */\nlet currentAction: string | null = null\n/** Guards the re-entrant `$change` a clamp performs from being clamped again. */\nlet clamping = false\n/** Ignores the half-applied transforms `$center` emits between its move and its scale. */\nlet centring = false\n/** Invalidates an in-flight build when `src` changes or the component goes away mid-load. */\nlet buildToken = 0\n/** The host box the current layout was computed for, not the last one observed. */\nlet laidOut: Size = { width: 0, height: 0 }\n/** The last emitted crop, so a model written straight back is not treated as new. */\nlet lastEmitted: CropRect | null = null\n/** Watches ancestors that clip the host. Their height limits the available room. */\nlet ancestorObserver: ResizeObserver | null = null\n\nconst create = <T extends HTMLElement>(name: string): T => document.createElement(name) as T\n\n/** The image box in canvas coordinates. Read from layout so panning and zooming are included. */\nconst imageBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const canvasRect = parts.canvas.getBoundingClientRect()\n const imageRect = parts.image.getBoundingClientRect()\n return {\n x: imageRect.left - canvasRect.left,\n y: imageRect.top - canvasRect.top,\n width: imageRect.width,\n height: imageRect.height,\n }\n}\n\n/**\n * Where the crop may be: the image, but never outside the visible canvas.\n * They differ only when the image is zoomed past its frame. Then the frame wins, as in cropper.js v1.\n */\nconst constraintBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const image = imageBounds()\n const canvas = parts.canvas.getBoundingClientRect()\n const left = Math.max(image.x, 0)\n const top = Math.max(image.y, 0)\n const right = Math.min(image.x + image.width, canvas.width)\n const bottom = Math.min(image.y + image.height, canvas.height)\n return { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) }\n}\n\nconst selectionRect = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const { x, y, width, height } = parts.selection\n return { x, y, width, height }\n}\n\nconst applyRect = (rect: Rect) => {\n if (!parts) return\n clamping = true\n parts.selection.$change(rect.x, rect.y, rect.width, rect.height, props.aspectRatio, true)\n clamping = false\n}\n\n/**\n * Re-fits the image to the canvas.\n * `$center` only scales and moves an image marked scalable and translatable. cropper.js allows\n * this itself only while loading, so the flags are set for the call and restored after.\n */\nconst centerImage = () => {\n if (!parts) return\n const { image } = parts\n const { scalable, translatable } = image\n centring = true\n image.scalable = true\n image.translatable = true\n image.$center('contain')\n image.scalable = scalable\n image.translatable = translatable\n centring = false\n}\n\n/**\n * The initial crop of a new picture. Not using cropper.js' `initialCoverage`,\n * because its deferred init runs after a `ready` handler has positioned the crop.\n * Measured against the image, not the canvas. They differ when the image is centred between margins.\n */\nconst seedInitialCrop = () => {\n if (!parts) return\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return\n const initial = initialSelectionRect(bounds, props.aspectRatio, AUTO_CROP_AREA)\n applyRect({ ...initial, x: initial.x + bounds.x, y: initial.y + bounds.y })\n}\n\nconst applyModelOrSeed = () => {\n const model = props.modelValue\n if (model && model.width > 0 && model.height > 0) applyCrop(model)\n else seedInitialCrop()\n emitCrop()\n}\n\n/** Pulls the selection back inside the image after the image moved. */\nconst refit = () => {\n if (!parts || centring) return\n const current = selectionRect()\n if (current.width <= 0 || current.height <= 0) return\n const fitted = clampRectInside(current, constraintBounds(), props.aspectRatio)\n if (!rectsAreClose(current, fitted)) applyRect(fitted)\n}\n\nconst onSelectionChange = (event: Event) => {\n if (clamping || !parts) return\n const detail = (event as CustomEvent<Rect>).detail\n if (!detail) return\n // cropper.js reverses the action when a grip is dragged past the opposite edge. It records\n // this on the canvas before emitting this event, one move ahead of the `action` event.\n // Prefer that value, and fall back in case a future version stops setting it.\n const liveAction = (parts.canvas as unknown as { $action?: unknown }).$action\n const action = typeof liveAction === 'string' && liveAction ? liveAction : currentAction\n const anchor = action ? RESIZE_ANCHORS[action] : undefined\n const clamped = clampRectInside(detail, constraintBounds(), props.aspectRatio, anchor)\n if (rectsAreClose(detail, clamped)) return\n // Rejecting the change and applying the clamped one keeps the crop sliding along the border instead of freezing.\n // The shade reads `defaultPrevented` and follows the new values.\n event.preventDefault()\n applyRect(clamped)\n}\n\nconst onActionStart = (event: Event) => {\n currentAction = (event as CustomEvent<{ action?: string }>).detail?.action ?? null\n}\n\nconst onAction = (event: Event) => {\n const action = (event as CustomEvent<{ action?: string }>).detail?.action\n // cropper.js turns a new \"select\" drag into a corner resize once the direction is known.\n // It reports the new action on the next move. Follow it so the anchor stays correct.\n if (action) currentAction = action\n}\n\nconst onActionEnd = () => {\n currentAction = null\n emitCrop(true)\n}\n\n/**\n * The canvas must never see a wheel event. Its handler always calls\n * `preventDefault()`, which would block page scrolling over the picture.\n * Pinch zoom still works because it arrives as pointer events.\n */\nconst onWheelCapture = (event: WheelEvent) => {\n event.stopPropagation()\n}\n\n/**\n * cropper.js emits `transform` before it writes the new matrix to the element style.\n * Re-fitting at once would measure the old image. After a zoom out the crop would hang over the edge of the new one.\n */\nconst onImageTransform = () => queueMicrotask(refit)\n\nconst teardown = () => {\n if (parts) {\n const { canvas, image, selection } = parts\n selection.removeEventListener('change', onSelectionChange)\n canvas.removeEventListener('actionstart', onActionStart)\n canvas.removeEventListener('action', onAction)\n canvas.removeEventListener('actionend', onActionEnd)\n image.removeEventListener('transform', onImageTransform)\n }\n // Every canvas, not only the one on `parts`. A superseded build still waiting\n // on its image has already added one to the DOM, and nothing tracks it.\n hostEl.value?.querySelectorAll(CropperCanvas.$name).forEach((canvas) => {\n // Disconnecting a `cropper-image` drops its listeners but keeps its request running.\n // The pending `$ready()` promise keeps this component alive until the server answers.\n canvas.querySelectorAll<CropperImage>(CropperImage.$name).forEach((image) => {\n if (image.$image) image.$image.src = ''\n })\n canvas.remove()\n })\n ancestorObserver?.disconnect()\n ancestorObserver = null\n parts = null\n natural = { width: 0, height: 0 }\n laidOut = { width: 0, height: 0 }\n currentAction = null\n}\n\n/**\n * How much of the host's height is actually shown.\n * Usually the host's own `max-height`, which `DamAssetImageRoiSelect` relies on. Ancestors\n * with `overflow: hidden` count too, because what they cut off cannot be scrolled into view.\n * Scrolling ancestors are ignored. There the rest is reachable by scrolling.\n */\nconst clippingAncestorsOf = (host: HTMLElement): HTMLElement[] => {\n const found: HTMLElement[] = []\n let ancestor = host.parentElement\n while (ancestor && ancestor !== document.body && ancestor !== document.documentElement) {\n const { overflowY } = window.getComputedStyle(ancestor)\n if (overflowY === 'hidden' || overflowY === 'clip') found.push(ancestor)\n ancestor = ancestor.parentElement\n }\n return found\n}\n\nconst visibleHeightOf = (host: HTMLElement): number => {\n let available = host.clientHeight\n const hostTop = host.getBoundingClientRect().top\n\n clippingAncestorsOf(host).forEach((ancestor) => {\n const rect = ancestor.getBoundingClientRect()\n // From where the host becomes visible to where the ancestor stops showing content.\n // The ancestor's top matters when the host starts above it.\n // Content off the top is as unreachable as content off the bottom.\n const room = rect.bottom - Math.max(rect.top, hostTop)\n if (room > 0) available = Math.min(available, room)\n })\n\n return available\n}\n\n/**\n * Sizes the canvas to the room the host gives it, in two passes.\n * The picture's height follows from its width, but a frame with\n * `max-height` only shows how much it reveals once it has content.\n * This keeps a tall picture in a short frame scaled to fit, as in v1. A\n * part cut off by `overflow: hidden` could not be reached by the crop.\n */\nconst sizeCanvas = (canvas: CropperCanvas, host: HTMLElement, availableWidth: number): Size => {\n const size = canvasSizeFor(natural, availableWidth, MIN_CONTAINER_WIDTH, MIN_CONTAINER_HEIGHT)\n canvas.style.width = `${size.width}px`\n canvas.style.height = `${size.height}px`\n\n const visibleHeight = visibleHeightOf(host)\n if (visibleHeight > 0 && visibleHeight < size.height) {\n size.height = Math.max(visibleHeight, MIN_CONTAINER_HEIGHT)\n canvas.style.height = `${size.height}px`\n }\n return size\n}\n\nconst buildSelectionChildren = (selection: CropperSelection) => {\n const grid = create<CropperGrid>(CropperGrid.$name)\n grid.rows = 3\n grid.columns = 3\n grid.covered = true\n grid.themeColor = GRID_COLOR\n grid.setAttribute('role', 'grid')\n selection.appendChild(grid)\n\n const crosshair = create<CropperCrosshair>(CropperCrosshair.$name)\n crosshair.centered = true\n crosshair.themeColor = CROSSHAIR_COLOR\n selection.appendChild(crosshair)\n\n const face = create<CropperHandle>(CropperHandle.$name)\n face.action = 'move'\n face.themeColor = FACE_COLOR\n selection.appendChild(face)\n\n RESIZE_ACTIONS.forEach((action) => {\n const handle = create<CropperHandle>(CropperHandle.$name)\n handle.action = action\n handle.themeColor = SELECTION_COLOR\n selection.appendChild(handle)\n })\n}\n\nconst build = async () => {\n const token = ++buildToken\n teardown()\n loading.value = true\n\n const host = hostEl.value\n if (!host || !props.src) {\n // Nothing to load. A visible spinner would make an empty cropper look stuck.\n loading.value = false\n return\n }\n\n const canvas = create<CropperCanvas>(CropperCanvas.$name)\n canvas.background = false\n canvas.themeColor = SELECTION_COLOR\n canvas.style.display = 'block'\n sizeCanvas(canvas, host, host.clientWidth)\n\n const image = create<CropperImage>(CropperImage.$name)\n image.alt = ''\n image.initialFit = 'contain'\n image.rotatable = false\n image.skewable = false\n image.translatable = false\n image.scalable = true\n image.src = props.src\n\n const shade = create<CropperShade>(CropperShade.$name)\n shade.themeColor = props.shadeColor\n // Hidden until the first crop box exists, or it would flash across the whole canvas.\n shade.hidden = true\n\n const selectHandle = create<CropperHandle>(CropperHandle.$name)\n selectHandle.action = 'select'\n selectHandle.plain = true\n\n const selection = create<CropperSelection>(CropperSelection.$name)\n selection.themeColor = SELECTION_COLOR\n selection.movable = true\n selection.resizable = true\n selection.outlined = true\n // Keep sub-pixel values. Rounding would drift the natural-pixel crop data that callers persist.\n selection.precise = true\n selection.aspectRatio = props.aspectRatio\n buildSelectionChildren(selection)\n\n // Listeners are added before anything is connected, so the current\n // action is known before the elements' own handlers react.\n canvas.addEventListener('actionstart', onActionStart)\n canvas.addEventListener('action', onAction)\n canvas.addEventListener('actionend', onActionEnd)\n image.addEventListener('transform', onImageTransform)\n selection.addEventListener('change', onSelectionChange)\n\n canvas.append(image, shade, selectHandle, selection)\n // Attach the whole tree at once. Each element links to its\n // siblings on connect, and the shade looks for the selection.\n // Appending children one by one leaves the shade on an empty canvas, and it never follows the crop.\n host.appendChild(canvas)\n // Second pass, now that the host has content for its constraints to act on.\n sizeCanvas(canvas, host, host.clientWidth)\n\n let loaded: HTMLImageElement\n try {\n // The element makes the only request. Its promise returns the loaded picture.\n loaded = await image.$ready()\n } catch {\n // Matches cropper.js v1, which never became ready on a broken source.\n canvas.remove()\n if (token === buildToken) loading.value = false\n return\n }\n if (token !== buildToken) {\n canvas.remove()\n return\n }\n\n parts = { canvas, image, selection }\n // The natural size is known only now. Sizing here avoids a separate request just to measure the image.\n natural = { width: loaded.naturalWidth, height: loaded.naturalHeight }\n sizeCanvas(canvas, host, host.clientWidth)\n\n // A prop changed during loading found no elements for the watchers to\n // update. Re-apply the two variable props. This is idempotent otherwise.\n shade.themeColor = props.shadeColor\n selection.aspectRatio = props.aspectRatio\n\n centerImage()\n\n laidOut = hostBox(host)\n observeAncestors(host)\n applyModelOrSeed()\n\n loading.value = false\n emit('ready')\n}\n\nconst currentCrop = (): CropRect | null => {\n if (!parts) return null\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return null\n const rect = selectionRect()\n return {\n x: (rect.x - bounds.x) / bounds.width,\n y: (rect.y - bounds.y) / bounds.height,\n width: rect.width / bounds.width,\n height: rect.height / bounds.height,\n }\n}\n\n/** Applies a crop given in fractions to the canvas, clamped to the picture. */\nconst applyCrop = (crop: CropRect) => {\n const bounds = imageBounds()\n if (!parts || bounds.width <= 0 || bounds.height <= 0) return\n applyRect(\n clampRectInside(\n {\n x: bounds.x + crop.x * bounds.width,\n y: bounds.y + crop.y * bounds.height,\n width: crop.width * bounds.width,\n height: crop.height * bounds.height,\n },\n constraintBounds(),\n props.aspectRatio\n )\n )\n}\n\nconst cropsAreClose = (a: CropRect | null, b: CropRect | null): boolean =>\n a !== null &&\n b !== null &&\n Math.abs(a.x - b.x) < 0.0005 &&\n Math.abs(a.y - b.y) < 0.0005 &&\n Math.abs(a.width - b.width) < 0.0005 &&\n Math.abs(a.height - b.height) < 0.0005\n\n/**\n * Emits the crop. Also called after the component adjusts the crop itself. A stored region\n * rarely matches the configured ratio, and the binding should show the actual crop.\n */\nconst emitCrop = (alsoCommit = false) => {\n const crop = currentCrop()\n if (!crop) return\n if (alsoCommit || !cropsAreClose(crop, lastEmitted)) {\n lastEmitted = crop\n emit('update:modelValue', crop)\n }\n if (alsoCommit) emit('commit', crop)\n}\n\n/** The host's room: its width and the height that is actually shown. */\nconst hostBox = (host: HTMLElement): Size => ({ width: host.clientWidth, height: visibleHeightOf(host) })\n\n/** Re-fits the image to the new container and keeps the user's crop. */\nconst relayout = () => {\n const host = hostEl.value\n if (!parts || !host) return\n // No crop means the last layout had no size. Fall back to the bound\n // crop, which a cropper built inside a closed panel has held all along.\n const wanted = currentCrop() ?? props.modelValue\n\n const size = sizeCanvas(parts.canvas, host, host.clientWidth)\n laidOut = hostBox(host)\n // Re-read the ancestors too. A cropper can move between frames,\n // and the current clipping ancestor is the one that matters.\n observeAncestors(host)\n centerImage()\n if (size.width <= 0 || size.height <= 0) return\n\n if (wanted && wanted.width > 0) applyCrop(wanted)\n else applyModelOrSeed()\n emitCrop()\n}\n\nconst onHostBoxChanged = () => {\n const host = hostEl.value\n if (!host) return\n const box = hostBox(host)\n if (box.width <= 0 || box.height <= 0) return\n // Compare with the box the current layout was built for, so a\n // size seen during loading is not treated as already laid out.\n if (box.width === laidOut.width && box.height === laidOut.height) return\n if (!parts) return\n // Deferred a frame. Resizing the canvas inside the observer\n // callback makes Chromium report an undelivered-notification loop.\n requestAnimationFrame(() => relayout())\n}\n\n// Height matters as much as width. The DAM sizes the cropper with `calc(100vh\n// - 160px)`, so a shorter window shrinks the frame without changing its width.\nuseResizeObserver(hostEl, onHostBoxChanged)\n\n/** A clipping ancestor can change how much it shows without the host box changing. */\nconst observeAncestors = (host: HTMLElement) => {\n ancestorObserver?.disconnect()\n const ancestors = clippingAncestorsOf(host)\n if (ancestors.length === 0) {\n ancestorObserver = null\n return\n }\n ancestorObserver = new ResizeObserver(onHostBoxChanged)\n ancestors.forEach((ancestor) => ancestorObserver?.observe(ancestor))\n}\n\nwatch(\n () => props.src,\n () => {\n build()\n }\n)\n\nwatch(\n () => props.modelValue,\n (model) => {\n // Ignore the echo of the crop just emitted. Otherwise parent and component would keep writing to each other.\n if (!parts || !model || cropsAreClose(model, lastEmitted)) return\n applyCrop(model)\n emitCrop()\n },\n { deep: true }\n)\n\nwatch(\n () => props.shadeColor,\n (shadeColor) => {\n const shade = parts?.canvas.querySelector<CropperShade>(CropperShade.$name)\n if (shade) shade.themeColor = shadeColor\n }\n)\n\nwatch(\n () => props.aspectRatio,\n (aspectRatio) => {\n if (!parts) return\n parts.selection.aspectRatio = aspectRatio\n if (!isUsableAspectRatio(aspectRatio)) return\n const current = selectionRect()\n applyRect(clampRectInside({ ...current, height: current.width / aspectRatio }, constraintBounds(), aspectRatio))\n }\n)\n\nonMounted(() => {\n build()\n})\n\nonBeforeUnmount(() => {\n buildToken += 1\n teardown()\n})\n</script>\n\n<template>\n <div class=\"a-cropper d-flex flex-column\">\n <div\n v-if=\"loading\"\n class=\"d-flex w-100 align-center justify-center\"\n >\n <VProgressCircular\n class=\"position-absolute\"\n indeterminate\n />\n </div>\n\n <div\n ref=\"hostEl\"\n class=\"a-cropper__container\"\n :style=\"containerStyle\"\n @wheel.capture=\"onWheelCapture\"\n />\n </div>\n</template>\n\n<style lang=\"scss\">\n// Full width even as a flex item, such as in the asset detail dialog. The canvas is sized from the\n// host's width, and a shrink-wrapped root has none to give, so every picture got the 200px minimum.\n.a-cropper {\n width: 100%;\n}\n\n// `cropper-crosshair` is sized in `em`. Without its own size the centre marker would scale with the admin's font.\n// 7px matches the plus sign of v1's `.cropper-center`.\n.a-cropper cropper-crosshair {\n font-size: 7px;\n}\n\n// Recreates v1's `.cropper-line` on each crop edge: a 5px band of the selection colour at 10%\n// opacity, 3px outside and 2px inside the border. It makes the outline read as a grabbable edge.\n// Drawn as two shadows, so it does not depend on the v2 grip sizes.\n.a-cropper cropper-selection[outlined] {\n box-shadow:\n inset 0 0 0 2px rgb(51 153 255 / 10%),\n 0 0 0 3px rgb(51 153 255 / 10%);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ACropper.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_component_VProgressCircular","_createElementVNode","_normalizeStyle","CropperCanvas","CropperImage","CropperShade","CropperHandle","CropperSelection","CropperGrid","CropperCrosshair","_hoisted_1","_hoisted_2","AUTO_CROP_AREA","MIN_CONTAINER_WIDTH","MIN_CONTAINER_HEIGHT","SELECTION_COLOR","FACE_COLOR","GRID_COLOR","CROSSHAIR_COLOR","ACropper_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","element","RESIZE_ACTIONS","hostEl","useTemplateRef","loading","ref","parts","natural","currentAction","clamping","centring","buildToken","laidOut","lastEmitted","ancestorObserver","create","name","imageBounds","canvasRect","imageRect","constraintBounds","image","canvas","left","top","right","bottom","selectionRect","applyRect","rect","centerImage","scalable","translatable","seedInitialCrop","bounds","initial","initialSelectionRect","applyModelOrSeed","model","applyCrop","emitCrop","refit","current","fitted","clampRectInside","rectsAreClose","onSelectionChange","detail","event","liveAction","action","anchor","RESIZE_ANCHORS","clamped","onActionStart","onAction","onActionEnd","onWheelCapture","onImageTransform","teardown","selection","clippingAncestorsOf","found","ancestor","host","overflowY","visibleHeightOf","available","hostTop","room","sizeCanvas","size","canvasSizeFor","availableWidth","visibleHeight","buildSelectionChildren","grid","crosshair","face","handle","build","token","shade","selectHandle","loaded","hostBox","observeAncestors","currentCrop","crop","cropsAreClose","a","b","alsoCommit","relayout","wanted","onHostBoxChanged","box","ancestors","watch","shadeColor","aspectRatio","isUsableAspectRatio","onMounted","onBeforeUnmount","openBlock","createElementBlock","createVNode","VProgressCircular","createCommentVNode","createElementVNode","normalizeStyle"],"sources":["../../../../../src/domains/dam/cropper/components/ACropper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport {\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n} from 'cropperjs'\nimport {\n canvasSizeFor,\n clampRectInside,\n initialSelectionRect,\n isUsableAspectRatio,\n RESIZE_ANCHORS,\n rectsAreClose,\n type Rect,\n type Size,\n} from '@/domains/dam/cropper/utils/cropperGeometry'\nimport type { CropRect } from '@/domains/dam/cropper/utils/cropperTypes'\n\n/**\n * Image cropper built on cropper.js v2 custom elements. Replaces the v1-based `ACropperjs`.\n * Not exported. Its only user is `DamAssetImageRoiSelect`, and it is shaped to that one need.\n * The crop is bound via `v-model` as fractions of the image.\n * `commit` signals that a gesture ended. There is no imperative API.\n * Elements are built in script, not the template. Consumers do not configure `isCustomElement`,\n * and setting properties avoids attribute coercion issues (`NaN`, booleans, fractions).\n */\n\nconst props = withDefaults(\n defineProps<{\n src?: string\n /** The crop as fractions of the image. Null starts from the default box. */\n modelValue?: CropRect | null\n /** `NaN` (the default) leaves the crop free-form. */\n aspectRatio?: number\n containerStyle?: { [key: string]: string } | undefined\n /** Colour over everything outside the crop. Replaces overriding `.cropper-modal`. */\n shadeColor?: string\n }>(),\n {\n src: '',\n modelValue: null,\n aspectRatio: NaN,\n containerStyle: undefined,\n shadeColor: 'rgba(0, 0, 0, 0.5)',\n }\n)\n\nconst emit = defineEmits<{\n (event: 'update:modelValue', crop: CropRect): void\n /** The user finished a gesture. The crop is worth saving. */\n (event: 'commit', crop: CropRect): void\n (event: 'ready'): void\n}>()\n\n// cropper.js registers its elements as a side effect of its entry module. Our `sideEffects`\n// setting lets the consumer's bundler drop that module, so register them here.\n// `$define` is a no-op for an already registered element.\nfor (const element of [\n CropperCanvas,\n CropperCrosshair,\n CropperGrid,\n CropperHandle,\n CropperImage,\n CropperSelection,\n CropperShade,\n]) {\n element.$define()\n}\n\n/**\n * Settings the only caller never varies. Each is behaviour: no checkerboard behind a photo, wheel left\n * to the page, pinch zoom kept for tablets, and the minimum canvas size from cropper.js' stylesheet.\n */\nconst AUTO_CROP_AREA = 0.8\nconst MIN_CONTAINER_WIDTH = 200\nconst MIN_CONTAINER_HEIGHT = 100\n\n// Matches cropper.js v1's stylesheet so both components look the same.\nconst SELECTION_COLOR = 'rgba(51, 153, 255, 0.75)'\nconst FACE_COLOR = 'rgba(255, 255, 255, 0.1)'\nconst GRID_COLOR = 'rgba(238, 238, 238, 0.5)'\nconst CROSSHAIR_COLOR = 'rgba(238, 238, 238, 0.75)'\nconst RESIZE_ACTIONS = [\n 'n-resize',\n 'e-resize',\n 's-resize',\n 'w-resize',\n 'ne-resize',\n 'nw-resize',\n 'se-resize',\n 'sw-resize',\n]\n\ninterface CropperParts {\n canvas: CropperCanvas\n image: CropperImage\n selection: CropperSelection\n}\n\nconst hostEl = useTemplateRef<HTMLDivElement>('hostEl')\nconst loading = ref(true)\n\nlet parts: CropperParts | null = null\nlet natural: Size = { width: 0, height: 0 }\n/** The action cropper.js is performing, so a clamp knows which edge to hold still. */\nlet currentAction: string | null = null\n/** Guards the re-entrant `$change` a clamp performs from being clamped again. */\nlet clamping = false\n/** Ignores the half-applied transforms `$center` emits between its move and its scale. */\nlet centring = false\n/** Invalidates an in-flight build when `src` changes or the component goes away mid-load. */\nlet buildToken = 0\n/** The host box the current layout was computed for, not the last one observed. */\nlet laidOut: Size = { width: 0, height: 0 }\n/** The last emitted crop, so a model written straight back is not treated as new. */\nlet lastEmitted: CropRect | null = null\n/** Watches ancestors that clip the host. Their height limits the available room. */\nlet ancestorObserver: ResizeObserver | null = null\n\nconst create = <T extends HTMLElement>(name: string): T => document.createElement(name) as T\n\n/** The image box in canvas coordinates. Read from layout so panning and zooming are included. */\nconst imageBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const canvasRect = parts.canvas.getBoundingClientRect()\n const imageRect = parts.image.getBoundingClientRect()\n return {\n x: imageRect.left - canvasRect.left,\n y: imageRect.top - canvasRect.top,\n width: imageRect.width,\n height: imageRect.height,\n }\n}\n\n/**\n * Where the crop may be: the image, but never outside the visible canvas.\n * They differ only when the image is zoomed past its frame. Then the frame wins, as in cropper.js v1.\n */\nconst constraintBounds = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const image = imageBounds()\n const canvas = parts.canvas.getBoundingClientRect()\n const left = Math.max(image.x, 0)\n const top = Math.max(image.y, 0)\n const right = Math.min(image.x + image.width, canvas.width)\n const bottom = Math.min(image.y + image.height, canvas.height)\n return { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) }\n}\n\nconst selectionRect = (): Rect => {\n if (!parts) return { x: 0, y: 0, width: 0, height: 0 }\n const { x, y, width, height } = parts.selection\n return { x, y, width, height }\n}\n\nconst applyRect = (rect: Rect) => {\n if (!parts) return\n clamping = true\n parts.selection.$change(rect.x, rect.y, rect.width, rect.height, props.aspectRatio, true)\n clamping = false\n}\n\n/**\n * Re-fits the image to the canvas.\n * `$center` only scales and moves an image marked scalable and translatable. cropper.js allows\n * this itself only while loading, so the flags are set for the call and restored after.\n */\nconst centerImage = () => {\n if (!parts) return\n const { image } = parts\n const { scalable, translatable } = image\n centring = true\n image.scalable = true\n image.translatable = true\n image.$center('contain')\n image.scalable = scalable\n image.translatable = translatable\n centring = false\n}\n\n/**\n * The initial crop of a new picture. Not using cropper.js' `initialCoverage`,\n * because its deferred init runs after a `ready` handler has positioned the crop.\n * Measured against the image, not the canvas. They differ when the image is centred between margins.\n */\nconst seedInitialCrop = () => {\n if (!parts) return\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return\n const initial = initialSelectionRect(bounds, props.aspectRatio, AUTO_CROP_AREA)\n applyRect({ ...initial, x: initial.x + bounds.x, y: initial.y + bounds.y })\n}\n\nconst applyModelOrSeed = () => {\n const model = props.modelValue\n if (model && model.width > 0 && model.height > 0) applyCrop(model)\n else seedInitialCrop()\n emitCrop()\n}\n\n/** Pulls the selection back inside the image after the image moved. */\nconst refit = () => {\n if (!parts || centring) return\n const current = selectionRect()\n if (current.width <= 0 || current.height <= 0) return\n const fitted = clampRectInside(current, constraintBounds(), props.aspectRatio)\n if (!rectsAreClose(current, fitted)) applyRect(fitted)\n}\n\nconst onSelectionChange = (event: Event) => {\n if (clamping || !parts) return\n const detail = (event as CustomEvent<Rect>).detail\n if (!detail) return\n // cropper.js reverses the action when a grip is dragged past the opposite edge. It records\n // this on the canvas before emitting this event, one move ahead of the `action` event.\n // Prefer that value, and fall back in case a future version stops setting it.\n const liveAction = (parts.canvas as unknown as { $action?: unknown }).$action\n const action = typeof liveAction === 'string' && liveAction ? liveAction : currentAction\n const anchor = action ? RESIZE_ANCHORS[action] : undefined\n const clamped = clampRectInside(detail, constraintBounds(), props.aspectRatio, anchor)\n if (rectsAreClose(detail, clamped)) return\n // Rejecting the change and applying the clamped one keeps the crop sliding along the border instead of freezing.\n // The shade reads `defaultPrevented` and follows the new values.\n event.preventDefault()\n applyRect(clamped)\n}\n\nconst onActionStart = (event: Event) => {\n currentAction = (event as CustomEvent<{ action?: string }>).detail?.action ?? null\n}\n\nconst onAction = (event: Event) => {\n const action = (event as CustomEvent<{ action?: string }>).detail?.action\n // cropper.js turns a new \"select\" drag into a corner resize once the direction is known.\n // It reports the new action on the next move. Follow it so the anchor stays correct.\n if (action) currentAction = action\n}\n\nconst onActionEnd = () => {\n currentAction = null\n emitCrop(true)\n}\n\n/**\n * The canvas must never see a wheel event. Its handler always calls\n * `preventDefault()`, which would block page scrolling over the picture.\n * Pinch zoom still works because it arrives as pointer events.\n */\nconst onWheelCapture = (event: WheelEvent) => {\n event.stopPropagation()\n}\n\n/**\n * cropper.js emits `transform` before it writes the new matrix to the element style.\n * Re-fitting at once would measure the old image. After a zoom out the crop would hang over the edge of the new one.\n */\nconst onImageTransform = () => queueMicrotask(refit)\n\nconst teardown = () => {\n if (parts) {\n const { canvas, image, selection } = parts\n selection.removeEventListener('change', onSelectionChange)\n canvas.removeEventListener('actionstart', onActionStart)\n canvas.removeEventListener('action', onAction)\n canvas.removeEventListener('actionend', onActionEnd)\n image.removeEventListener('transform', onImageTransform)\n }\n // Every canvas, not only the one on `parts`. A superseded build still waiting\n // on its image has already added one to the DOM, and nothing tracks it.\n hostEl.value?.querySelectorAll(CropperCanvas.$name).forEach((canvas) => {\n // Disconnecting a `cropper-image` drops its listeners but keeps its request running.\n // The pending `$ready()` promise keeps this component alive until the server answers.\n canvas.querySelectorAll<CropperImage>(CropperImage.$name).forEach((image) => {\n if (image.$image) image.$image.src = ''\n })\n canvas.remove()\n })\n ancestorObserver?.disconnect()\n ancestorObserver = null\n parts = null\n natural = { width: 0, height: 0 }\n laidOut = { width: 0, height: 0 }\n currentAction = null\n}\n\n/**\n * How much of the host's height is actually shown.\n * Usually the host's own `max-height`, which `DamAssetImageRoiSelect` relies on. Ancestors\n * with `overflow: hidden` count too, because what they cut off cannot be scrolled into view.\n * Scrolling ancestors are ignored. There the rest is reachable by scrolling.\n */\nconst clippingAncestorsOf = (host: HTMLElement): HTMLElement[] => {\n const found: HTMLElement[] = []\n let ancestor = host.parentElement\n while (ancestor && ancestor !== document.body && ancestor !== document.documentElement) {\n const { overflowY } = window.getComputedStyle(ancestor)\n if (overflowY === 'hidden' || overflowY === 'clip') found.push(ancestor)\n ancestor = ancestor.parentElement\n }\n return found\n}\n\nconst visibleHeightOf = (host: HTMLElement): number => {\n let available = host.clientHeight\n const hostTop = host.getBoundingClientRect().top\n\n clippingAncestorsOf(host).forEach((ancestor) => {\n const rect = ancestor.getBoundingClientRect()\n // From where the host becomes visible to where the ancestor stops showing content.\n // The ancestor's top matters when the host starts above it.\n // Content off the top is as unreachable as content off the bottom.\n const room = rect.bottom - Math.max(rect.top, hostTop)\n if (room > 0) available = Math.min(available, room)\n })\n\n return available\n}\n\n/**\n * Sizes the canvas to the room the host gives it, in two passes.\n * The picture's height follows from its width, but a frame with\n * `max-height` only shows how much it reveals once it has content.\n * This keeps a tall picture in a short frame scaled to fit, as in v1. A\n * part cut off by `overflow: hidden` could not be reached by the crop.\n */\nconst sizeCanvas = (canvas: CropperCanvas, host: HTMLElement, availableWidth: number): Size => {\n const size = canvasSizeFor(natural, availableWidth, MIN_CONTAINER_WIDTH, MIN_CONTAINER_HEIGHT)\n canvas.style.width = `${size.width}px`\n canvas.style.height = `${size.height}px`\n\n const visibleHeight = visibleHeightOf(host)\n if (visibleHeight > 0 && visibleHeight < size.height) {\n size.height = Math.max(visibleHeight, MIN_CONTAINER_HEIGHT)\n canvas.style.height = `${size.height}px`\n }\n return size\n}\n\nconst buildSelectionChildren = (selection: CropperSelection) => {\n const grid = create<CropperGrid>(CropperGrid.$name)\n grid.rows = 3\n grid.columns = 3\n grid.covered = true\n grid.themeColor = GRID_COLOR\n grid.setAttribute('role', 'grid')\n selection.appendChild(grid)\n\n const crosshair = create<CropperCrosshair>(CropperCrosshair.$name)\n crosshair.centered = true\n crosshair.themeColor = CROSSHAIR_COLOR\n selection.appendChild(crosshair)\n\n const face = create<CropperHandle>(CropperHandle.$name)\n face.action = 'move'\n face.themeColor = FACE_COLOR\n selection.appendChild(face)\n\n RESIZE_ACTIONS.forEach((action) => {\n const handle = create<CropperHandle>(CropperHandle.$name)\n handle.action = action\n handle.themeColor = SELECTION_COLOR\n selection.appendChild(handle)\n })\n}\n\nconst build = async () => {\n const token = ++buildToken\n teardown()\n loading.value = true\n\n const host = hostEl.value\n if (!host || !props.src) {\n // Nothing to load. A visible spinner would make an empty cropper look stuck.\n loading.value = false\n return\n }\n\n const canvas = create<CropperCanvas>(CropperCanvas.$name)\n canvas.background = false\n canvas.themeColor = SELECTION_COLOR\n canvas.style.display = 'block'\n sizeCanvas(canvas, host, host.clientWidth)\n\n const image = create<CropperImage>(CropperImage.$name)\n image.alt = ''\n image.initialFit = 'contain'\n image.rotatable = false\n image.skewable = false\n image.translatable = false\n image.scalable = true\n image.src = props.src\n\n const shade = create<CropperShade>(CropperShade.$name)\n shade.themeColor = props.shadeColor\n // Hidden until the first crop box exists, or it would flash across the whole canvas.\n shade.hidden = true\n\n const selectHandle = create<CropperHandle>(CropperHandle.$name)\n selectHandle.action = 'select'\n selectHandle.plain = true\n\n const selection = create<CropperSelection>(CropperSelection.$name)\n selection.themeColor = SELECTION_COLOR\n selection.movable = true\n selection.resizable = true\n selection.outlined = true\n // Keep sub-pixel values. Rounding would drift the natural-pixel crop data that callers persist.\n selection.precise = true\n selection.aspectRatio = props.aspectRatio\n buildSelectionChildren(selection)\n\n // Listeners are added before anything is connected, so the current\n // action is known before the elements' own handlers react.\n canvas.addEventListener('actionstart', onActionStart)\n canvas.addEventListener('action', onAction)\n canvas.addEventListener('actionend', onActionEnd)\n image.addEventListener('transform', onImageTransform)\n selection.addEventListener('change', onSelectionChange)\n\n canvas.append(image, shade, selectHandle, selection)\n // Attach the whole tree at once. Each element links to its\n // siblings on connect, and the shade looks for the selection.\n // Appending children one by one leaves the shade on an empty canvas, and it never follows the crop.\n host.appendChild(canvas)\n // Second pass, now that the host has content for its constraints to act on.\n sizeCanvas(canvas, host, host.clientWidth)\n\n let loaded: HTMLImageElement\n try {\n // The element makes the only request. Its promise returns the loaded picture.\n loaded = await image.$ready()\n } catch {\n // Matches cropper.js v1, which never became ready on a broken source.\n canvas.remove()\n if (token === buildToken) loading.value = false\n return\n }\n if (token !== buildToken) {\n canvas.remove()\n return\n }\n\n parts = { canvas, image, selection }\n // The natural size is known only now. Sizing here avoids a separate request just to measure the image.\n natural = { width: loaded.naturalWidth, height: loaded.naturalHeight }\n sizeCanvas(canvas, host, host.clientWidth)\n\n // A prop changed during loading found no elements for the watchers to\n // update. Re-apply the two variable props. This is idempotent otherwise.\n shade.themeColor = props.shadeColor\n selection.aspectRatio = props.aspectRatio\n\n centerImage()\n\n laidOut = hostBox(host)\n observeAncestors(host)\n applyModelOrSeed()\n\n loading.value = false\n emit('ready')\n}\n\nconst currentCrop = (): CropRect | null => {\n if (!parts) return null\n const bounds = imageBounds()\n if (bounds.width <= 0 || bounds.height <= 0) return null\n const rect = selectionRect()\n return {\n x: (rect.x - bounds.x) / bounds.width,\n y: (rect.y - bounds.y) / bounds.height,\n width: rect.width / bounds.width,\n height: rect.height / bounds.height,\n }\n}\n\n/** Applies a crop given in fractions to the canvas, clamped to the picture. */\nconst applyCrop = (crop: CropRect) => {\n const bounds = imageBounds()\n if (!parts || bounds.width <= 0 || bounds.height <= 0) return\n applyRect(\n clampRectInside(\n {\n x: bounds.x + crop.x * bounds.width,\n y: bounds.y + crop.y * bounds.height,\n width: crop.width * bounds.width,\n height: crop.height * bounds.height,\n },\n constraintBounds(),\n props.aspectRatio\n )\n )\n}\n\nconst cropsAreClose = (a: CropRect | null, b: CropRect | null): boolean =>\n a !== null &&\n b !== null &&\n Math.abs(a.x - b.x) < 0.0005 &&\n Math.abs(a.y - b.y) < 0.0005 &&\n Math.abs(a.width - b.width) < 0.0005 &&\n Math.abs(a.height - b.height) < 0.0005\n\n/**\n * Emits the crop. Also called after the component adjusts the crop itself. A stored region\n * rarely matches the configured ratio, and the binding should show the actual crop.\n */\nconst emitCrop = (alsoCommit = false) => {\n const crop = currentCrop()\n if (!crop) return\n if (alsoCommit || !cropsAreClose(crop, lastEmitted)) {\n lastEmitted = crop\n emit('update:modelValue', crop)\n }\n if (alsoCommit) emit('commit', crop)\n}\n\n/** The host's room: its width and the height that is actually shown. */\nconst hostBox = (host: HTMLElement): Size => ({ width: host.clientWidth, height: visibleHeightOf(host) })\n\n/** Re-fits the image to the new container and keeps the user's crop. */\nconst relayout = () => {\n const host = hostEl.value\n if (!parts || !host) return\n // No crop means the last layout had no size. Fall back to the bound\n // crop, which a cropper built inside a closed panel has held all along.\n const wanted = currentCrop() ?? props.modelValue\n\n const size = sizeCanvas(parts.canvas, host, host.clientWidth)\n laidOut = hostBox(host)\n // Re-read the ancestors too. A cropper can move between frames,\n // and the current clipping ancestor is the one that matters.\n observeAncestors(host)\n centerImage()\n if (size.width <= 0 || size.height <= 0) return\n\n if (wanted && wanted.width > 0) applyCrop(wanted)\n else applyModelOrSeed()\n emitCrop()\n}\n\nconst onHostBoxChanged = () => {\n const host = hostEl.value\n if (!host) return\n const box = hostBox(host)\n if (box.width <= 0 || box.height <= 0) return\n // Compare with the box the current layout was built for, so a\n // size seen during loading is not treated as already laid out.\n if (box.width === laidOut.width && box.height === laidOut.height) return\n if (!parts) return\n // Deferred a frame. Resizing the canvas inside the observer\n // callback makes Chromium report an undelivered-notification loop.\n requestAnimationFrame(() => relayout())\n}\n\n// Height matters as much as width. The DAM sizes the cropper with `calc(100vh\n// - 160px)`, so a shorter window shrinks the frame without changing its width.\nuseResizeObserver(hostEl, onHostBoxChanged)\n\n/** A clipping ancestor can change how much it shows without the host box changing. */\nconst observeAncestors = (host: HTMLElement) => {\n ancestorObserver?.disconnect()\n const ancestors = clippingAncestorsOf(host)\n if (ancestors.length === 0) {\n ancestorObserver = null\n return\n }\n ancestorObserver = new ResizeObserver(onHostBoxChanged)\n ancestors.forEach((ancestor) => ancestorObserver?.observe(ancestor))\n}\n\nwatch(\n () => props.src,\n () => {\n build()\n }\n)\n\nwatch(\n () => props.modelValue,\n (model) => {\n // Ignore the echo of the crop just emitted. Otherwise parent and component would keep writing to each other.\n if (!parts || !model || cropsAreClose(model, lastEmitted)) return\n applyCrop(model)\n emitCrop()\n },\n { deep: true }\n)\n\nwatch(\n () => props.shadeColor,\n (shadeColor) => {\n const shade = parts?.canvas.querySelector<CropperShade>(CropperShade.$name)\n if (shade) shade.themeColor = shadeColor\n }\n)\n\nwatch(\n () => props.aspectRatio,\n (aspectRatio) => {\n if (!parts) return\n parts.selection.aspectRatio = aspectRatio\n if (!isUsableAspectRatio(aspectRatio)) return\n const current = selectionRect()\n applyRect(clampRectInside({ ...current, height: current.width / aspectRatio }, constraintBounds(), aspectRatio))\n }\n)\n\nonMounted(() => {\n build()\n})\n\nonBeforeUnmount(() => {\n buildToken += 1\n teardown()\n})\n</script>\n\n<template>\n <div class=\"a-cropper d-flex flex-column\">\n <div\n v-if=\"loading\"\n class=\"d-flex w-100 align-center justify-center\"\n >\n <VProgressCircular\n class=\"position-absolute\"\n indeterminate\n />\n </div>\n\n <div\n ref=\"hostEl\"\n class=\"a-cropper__container\"\n :style=\"containerStyle\"\n @wheel.capture=\"onWheelCapture\"\n />\n </div>\n</template>\n\n<style lang=\"scss\">\n// Full width even as a flex item, such as in the asset detail dialog. The canvas is sized from the\n// host's width, and a shrink-wrapped root has none to give, so every picture got the 200px minimum.\n.a-cropper {\n width: 100%;\n}\n\n// `cropper-crosshair` is sized in `em`. Without its own size the centre marker would scale with the admin's font.\n// 7px matches the plus sign of v1's `.cropper-center`.\n.a-cropper cropper-crosshair {\n font-size: 7px;\n}\n\n// Recreates v1's `.cropper-line` on each crop edge: a 5px band of the selection colour at 10%\n// opacity, 3px outside and 2px inside the border. It makes the outline read as a grabbable edge.\n// Drawn as two shadows, so it does not depend on the v2 grip sizes.\n.a-cropper cropper-selection[outlined] {\n box-shadow:\n inset 0 0 0 2px rgb(51 153 255 / 10%),\n 0 0 0 3px rgb(51 153 255 / 10%);\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAssetImageRoiSelect.js","names":["
|
|
1
|
+
{"version":3,"file":"DamAssetImageRoiSelect.js","names":["DamAssetImageRoiSelect_vue_vue_type_script_setup_true_lang_default","DamAssetImageRoiSelect_default"],"sources":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAssetImageRoiSelect.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createVNode","_component_VProgressCircular","_createCommentVNode","_unref","_createBlock","ACropper","_component_VImg","ACropper_default","_hoisted_1","cropperShadeColor","DamAssetImageRoiSelect_vue_vue_type_script_setup_true_lang_default","props","__props","damConfigName","useDamConfigName","useAlerts","cropperContainerStyle","imageRoiStore","useImageRoiStore","useCommonAdminCoreDamOptions","useDamConfigState","configExtSystem","getDamConfigExtSystem","isUndefined","imageUrl","computed","crop","ref","readStoredRegion","roi","imageFile","regionToCrop","watch","unmounted","reloadTimer","savedRegions","saving","loaderShown","busy","on","savesPending","readPending","settleBusy","isStillShown","saved","reloadSavedFile","file","fetchImageFile","damClient","endPointImage","error","showErrorsDefault","saveRoi","region","cropToRegion","committed","updateRoi","endPointRoi","showRecordWas","showCropper","onUnmounted","openBlock","createElementBlock","Fragment","createVNode","VProgressCircular","createCommentVNode","unref","createBlock","_cache","$event","VImg"],"sources":["../../../../../src/domains/dam/cropper/components/DamAssetImageRoiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport { useImageRoiStore } from '@/domains/dam/cropper/store/imageRoiStore'\nimport { updateRoi } from '@/domains/dam/api/damImageRoiApi'\nimport { useCommonAdminCoreDamOptions } from '@/domains/dam/composables/commonAdminCoreDamOptions'\nimport { cropToRegion, regionToCrop } from '@/domains/dam/cropper/utils/cropperJsService'\nimport ACropper from '@/domains/dam/cropper/components/ACropper.vue'\nimport type { CropRect } from '@/domains/dam/cropper/utils/cropperTypes'\nimport { useDamConfigState } from '@/domains/dam/config/composables/damConfigState'\nimport type { DocId, IntegerId } from '@/shared/types/common'\nimport { isUndefined } from '@/shared/utils/common'\nimport { fetchImageFile } from '@/domains/dam/api/damImageApi'\nimport type { AssetFileImage } from '@/domains/dam/types/AssetFile'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n extSystem: IntegerId\n configName?: string\n readonly?: boolean\n }>(),\n {\n configName: undefined,\n readonly: false,\n }\n)\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\nconst { showRecordWas, showErrorsDefault } = useAlerts()\n\nconst cropperContainerStyle = { overflow: 'hidden', maxHeight: 'calc(100vh - 160px)' }\n// Shade outside the region uses the admin's light grey instead of cropper.js' black.\n// The v2 elements style inside a shadow root, so the colour is passed in rather than set with a selector.\nconst cropperShadeColor = 'rgba(241, 244, 246, 0.5)'\n\nconst imageRoiStore = useImageRoiStore()\n\nconst { damClient, endPointImage, endPointRoi } = useCommonAdminCoreDamOptions(damConfigName)\nconst { getDamConfigExtSystem } = useDamConfigState(undefined, damConfigName)\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst configExtSystem = getDamConfigExtSystem(props.extSystem)\n\nif (isUndefined(configExtSystem)) {\n throw new Error('DamAssetImageRoiSelect: Ext system must be initialised.')\n}\n\nconst imageUrl = computed(() => {\n if (imageRoiStore.imageFile && imageRoiStore.imageFile.links?.image_detail) {\n return imageRoiStore.imageFile.links.image_detail.url + '?manipulated=' + imageRoiStore.imageFile.manipulatedAt\n }\n return ''\n})\n\n/** The stored region in the cropper's format: fractions of the picture. */\nconst crop = ref<CropRect | null>(null)\n\nconst readStoredRegion = () => {\n const { roi, imageFile } = imageRoiStore\n crop.value =\n roi && imageFile ? regionToCrop(roi, imageFile.imageAttributes.width, imageFile.imageAttributes.height) : null\n}\nreadStoredRegion()\nwatch(() => imageRoiStore.roi, readStoredRegion)\n\n// Two seconds after a save, the region file is read again because the DAM has redrawn it.\n// The read result is applied only if the store still holds the same file, the saved region and the cropper. A\n// rotation, another slot or another asset changes the file. admin-dam's slot change removes the region at once.\n// Only the read after the latest save is applied. An older read answering last would bring back the earlier drawing.\n// The save and read use the cropper's own loader, never one someone else turned on.\n// `cropperBusy` tells the region panel to offer no refresh meanwhile. After the read, region\n// previews are redrawn. A cropper gone before its save answered does not wait for a redraw.\ninterface SavedRegion {\n save: number\n file: AssetFileImage\n regionId: DocId\n}\nlet unmounted = false\nlet reloadTimer: ReturnType<typeof setTimeout> | undefined\nlet savedRegions = 0\nconst saving = ref(false)\nconst loaderShown = computed(() => imageRoiStore.loader || saving.value)\nconst busy = (on: boolean) => {\n saving.value = on\n imageRoiStore.setCropperBusy(on)\n}\n// Pending saves and whether the read after the latest answered\n// save is still due. The cropper is busy until neither is left.\n// Two commits make two saves. The older one's end must not clear the busy state while the newer one waits.\n// A cropper that goes away clears the busy state, as the store flag may already belong to another cropper.\nlet savesPending = 0\nlet readPending = false\nconst settleBusy = () => {\n if (!unmounted) busy(savesPending > 0 || readPending)\n}\nconst isStillShown = (saved: SavedRegion) =>\n !unmounted &&\n saved.save === savedRegions &&\n imageRoiStore.imageFile === saved.file &&\n imageRoiStore.roi?.id === saved.regionId\n\nconst reloadSavedFile = async (saved: SavedRegion) => {\n try {\n if (!isStillShown(saved)) return\n try {\n const file = await fetchImageFile(damClient, endPointImage, saved.file.id)\n if (isStillShown(saved)) {\n imageRoiStore.setImageFile(file)\n imageRoiStore.forceReloadRoiPreviews()\n }\n } catch (error) {\n if (isStillShown(saved)) showErrorsDefault(error)\n }\n } finally {\n // A newer save waits for a read of its own.\n if (saved.save === savedRegions) {\n readPending = false\n settleBusy()\n }\n }\n}\n\nconst saveRoi = async (committed: CropRect) => {\n const { roi, imageFile } = imageRoiStore\n if (!roi || !imageFile || props.readonly) return\n\n const region = cropToRegion(committed, roi, imageFile.imageAttributes.width, imageFile.imageAttributes.height)\n savesPending++\n busy(true)\n try {\n await updateRoi(damClient, endPointRoi, region.id, region)\n showRecordWas('updated')\n if (unmounted) return\n const saved: SavedRegion = { save: ++savedRegions, file: imageFile, regionId: region.id }\n readPending = true\n clearTimeout(reloadTimer)\n reloadTimer = setTimeout(() => reloadSavedFile(saved), 2000)\n } catch (error) {\n showErrorsDefault(error)\n } finally {\n savesPending--\n settleBusy()\n }\n}\n\nconst showCropper = computed(() => {\n if (imageRoiStore.imageFile && imageUrl.value.length > 0 && !loaderShown.value) {\n return true\n }\n return false\n})\n\nonUnmounted(() => {\n unmounted = true\n clearTimeout(reloadTimer)\n imageRoiStore.setCropperBusy(false)\n crop.value = null\n})\n</script>\n\n<template>\n <div\n v-if=\"loaderShown\"\n class=\"d-flex w-100 align-center justify-center\"\n >\n <VProgressCircular indeterminate />\n </div>\n <ACropper\n v-if=\"showCropper && configExtSystem.image && !readonly\"\n :key=\"imageRoiStore.imageFile?.manipulatedAt || 0\"\n v-model=\"crop\"\n :aspect-ratio=\"configExtSystem.image.roiWidth / configExtSystem.image.roiHeight\"\n :container-style=\"cropperContainerStyle\"\n :shade-color=\"cropperShadeColor\"\n :src=\"imageUrl\"\n @commit=\"saveRoi\"\n />\n <VImg\n v-else-if=\"showCropper\"\n :src=\"imageUrl\"\n :max-height=\"cropperContainerStyle.maxHeight\"\n data-cy=\"roi-readonly-image\"\n />\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DamAssetImageRoiSelect.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_component_VProgressCircular","_unref","_createBlock","ACropper","_component_VImg","ACropper_default","_hoisted_1","cropperShadeColor","DamAssetImageRoiSelect_vue_vue_type_script_setup_true_lang_default","props","__props","damConfigName","useDamConfigName","useAlerts","cropperContainerStyle","imageRoiStore","useImageRoiStore","useCommonAdminCoreDamOptions","useDamConfigState","configExtSystem","getDamConfigExtSystem","isUndefined","imageUrl","computed","crop","ref","readStoredRegion","roi","imageFile","regionToCrop","watch","unmounted","reloadTimer","savedRegions","saving","loaderShown","busy","on","savesPending","readPending","settleBusy","isStillShown","saved","reloadSavedFile","file","fetchImageFile","damClient","endPointImage","error","showErrorsDefault","saveRoi","region","cropToRegion","committed","updateRoi","endPointRoi","showRecordWas","showCropper","onUnmounted","openBlock","createElementBlock","Fragment","createVNode","VProgressCircular","createCommentVNode","unref","createBlock","_cache","$event","VImg"],"sources":["../../../../../src/domains/dam/cropper/components/DamAssetImageRoiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\nimport { useAlerts } from '@/domains/system/composables/alerts'\nimport { useImageRoiStore } from '@/domains/dam/cropper/store/imageRoiStore'\nimport { updateRoi } from '@/domains/dam/api/damImageRoiApi'\nimport { useCommonAdminCoreDamOptions } from '@/domains/dam/composables/commonAdminCoreDamOptions'\nimport { cropToRegion, regionToCrop } from '@/domains/dam/cropper/utils/cropperJsService'\nimport ACropper from '@/domains/dam/cropper/components/ACropper.vue'\nimport type { CropRect } from '@/domains/dam/cropper/utils/cropperTypes'\nimport { useDamConfigState } from '@/domains/dam/config/composables/damConfigState'\nimport type { DocId, IntegerId } from '@/shared/types/common'\nimport { isUndefined } from '@/shared/utils/common'\nimport { fetchImageFile } from '@/domains/dam/api/damImageApi'\nimport type { AssetFileImage } from '@/domains/dam/types/AssetFile'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n extSystem: IntegerId\n configName?: string\n readonly?: boolean\n }>(),\n {\n configName: undefined,\n readonly: false,\n }\n)\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\nconst { showRecordWas, showErrorsDefault } = useAlerts()\n\nconst cropperContainerStyle = { overflow: 'hidden', maxHeight: 'calc(100vh - 160px)' }\n// Shade outside the region uses the admin's light grey instead of cropper.js' black.\n// The v2 elements style inside a shadow root, so the colour is passed in rather than set with a selector.\nconst cropperShadeColor = 'rgba(241, 244, 246, 0.5)'\n\nconst imageRoiStore = useImageRoiStore()\n\nconst { damClient, endPointImage, endPointRoi } = useCommonAdminCoreDamOptions(damConfigName)\nconst { getDamConfigExtSystem } = useDamConfigState(undefined, damConfigName)\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst configExtSystem = getDamConfigExtSystem(props.extSystem)\n\nif (isUndefined(configExtSystem)) {\n throw new Error('DamAssetImageRoiSelect: Ext system must be initialised.')\n}\n\nconst imageUrl = computed(() => {\n if (imageRoiStore.imageFile && imageRoiStore.imageFile.links?.image_detail) {\n return imageRoiStore.imageFile.links.image_detail.url + '?manipulated=' + imageRoiStore.imageFile.manipulatedAt\n }\n return ''\n})\n\n/** The stored region in the cropper's format: fractions of the picture. */\nconst crop = ref<CropRect | null>(null)\n\nconst readStoredRegion = () => {\n const { roi, imageFile } = imageRoiStore\n crop.value =\n roi && imageFile ? regionToCrop(roi, imageFile.imageAttributes.width, imageFile.imageAttributes.height) : null\n}\nreadStoredRegion()\nwatch(() => imageRoiStore.roi, readStoredRegion)\n\n// Two seconds after a save, the region file is read again because the DAM has redrawn it.\n// The read result is applied only if the store still holds the same file, the saved region and the cropper. A\n// rotation, another slot or another asset changes the file. admin-dam's slot change removes the region at once.\n// Only the read after the latest save is applied. An older read answering last would bring back the earlier drawing.\n// The save and read use the cropper's own loader, never one someone else turned on.\n// `cropperBusy` tells the region panel to offer no refresh meanwhile. After the read, region\n// previews are redrawn. A cropper gone before its save answered does not wait for a redraw.\ninterface SavedRegion {\n save: number\n file: AssetFileImage\n regionId: DocId\n}\nlet unmounted = false\nlet reloadTimer: ReturnType<typeof setTimeout> | undefined\nlet savedRegions = 0\nconst saving = ref(false)\nconst loaderShown = computed(() => imageRoiStore.loader || saving.value)\nconst busy = (on: boolean) => {\n saving.value = on\n imageRoiStore.setCropperBusy(on)\n}\n// Pending saves and whether the read after the latest answered\n// save is still due. The cropper is busy until neither is left.\n// Two commits make two saves. The older one's end must not clear the busy state while the newer one waits.\n// A cropper that goes away clears the busy state, as the store flag may already belong to another cropper.\nlet savesPending = 0\nlet readPending = false\nconst settleBusy = () => {\n if (!unmounted) busy(savesPending > 0 || readPending)\n}\nconst isStillShown = (saved: SavedRegion) =>\n !unmounted &&\n saved.save === savedRegions &&\n imageRoiStore.imageFile === saved.file &&\n imageRoiStore.roi?.id === saved.regionId\n\nconst reloadSavedFile = async (saved: SavedRegion) => {\n try {\n if (!isStillShown(saved)) return\n try {\n const file = await fetchImageFile(damClient, endPointImage, saved.file.id)\n if (isStillShown(saved)) {\n imageRoiStore.setImageFile(file)\n imageRoiStore.forceReloadRoiPreviews()\n }\n } catch (error) {\n if (isStillShown(saved)) showErrorsDefault(error)\n }\n } finally {\n // A newer save waits for a read of its own.\n if (saved.save === savedRegions) {\n readPending = false\n settleBusy()\n }\n }\n}\n\nconst saveRoi = async (committed: CropRect) => {\n const { roi, imageFile } = imageRoiStore\n if (!roi || !imageFile || props.readonly) return\n\n const region = cropToRegion(committed, roi, imageFile.imageAttributes.width, imageFile.imageAttributes.height)\n savesPending++\n busy(true)\n try {\n await updateRoi(damClient, endPointRoi, region.id, region)\n showRecordWas('updated')\n if (unmounted) return\n const saved: SavedRegion = { save: ++savedRegions, file: imageFile, regionId: region.id }\n readPending = true\n clearTimeout(reloadTimer)\n reloadTimer = setTimeout(() => reloadSavedFile(saved), 2000)\n } catch (error) {\n showErrorsDefault(error)\n } finally {\n savesPending--\n settleBusy()\n }\n}\n\nconst showCropper = computed(() => {\n if (imageRoiStore.imageFile && imageUrl.value.length > 0 && !loaderShown.value) {\n return true\n }\n return false\n})\n\nonUnmounted(() => {\n unmounted = true\n clearTimeout(reloadTimer)\n imageRoiStore.setCropperBusy(false)\n crop.value = null\n})\n</script>\n\n<template>\n <div\n v-if=\"loaderShown\"\n class=\"d-flex w-100 align-center justify-center\"\n >\n <VProgressCircular indeterminate />\n </div>\n <ACropper\n v-if=\"showCropper && configExtSystem.image && !readonly\"\n :key=\"imageRoiStore.imageFile?.manipulatedAt || 0\"\n v-model=\"crop\"\n :aspect-ratio=\"configExtSystem.image.roiWidth / configExtSystem.image.roiHeight\"\n :container-style=\"cropperContainerStyle\"\n :shade-color=\"cropperShadeColor\"\n :src=\"imageUrl\"\n @commit=\"saveRoi\"\n />\n <VImg\n v-else-if=\"showCropper\"\n :src=\"imageUrl\"\n :max-height=\"cropperContainerStyle.maxHeight\"\n data-cy=\"roi-readonly-image\"\n />\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAssetImageRoiSelectLazy.js","names":["
|
|
1
|
+
{"version":3,"file":"DamAssetImageRoiSelectLazy.js","names":["DamAssetImageRoiSelectLazy_vue_vue_type_script_setup_true_lang_default","DamAssetImageRoiSelectLazy_default"],"sources":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamAssetImageRoiSelectLazy.vue_vue_type_script_setup_true_lang.js","names":["props","
|
|
1
|
+
{"version":3,"file":"DamAssetImageRoiSelectLazy.vue_vue_type_script_setup_true_lang.js","names":["props","_openBlock","_createBlock","_resolveDynamicComponent","_unref","_createElementBlock","_createElementVNode","_toDisplayString","_createVNode","_withModifiers","_withCtx","_createTextVNode","_component_VProgressCircular","_hoisted_1","_hoisted_2","DamAssetImageRoiSelectLazy_vue_vue_type_script_setup_true_lang_default","damConfigName","useDamConfigName","__props","useI18n","roiSelect","shallowRef","loadFailed","ref","load","loadDamAssetImageRoiSelect","onMounted","_component_ABtnTertiary","resolveComponent","openBlock","createBlock","resolveDynamicComponent","unref","createElementBlock","createElementVNode","toDisplayString","t","createVNode","withModifiers","withCtx","createTextVNode","VProgressCircular"],"sources":["../../../../../src/domains/dam/cropper/components/DamAssetImageRoiSelectLazy.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { type Component, onMounted, ref, shallowRef } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { loadDamAssetImageRoiSelect } from '@/domains/dam/cropper/utils/damAssetImageRoiSelectLoader'\nimport type { IntegerId } from '@/shared/types/common'\nimport { useDamConfigName } from '@/domains/dam/composables/damConfigName'\n\nconst props = withDefaults(\n defineProps<{\n extSystem: IntegerId\n configName?: string\n readonly?: boolean\n }>(),\n {\n configName: undefined,\n readonly: false,\n }\n)\n// eslint-disable-next-line vue/no-setup-props-reactivity-loss\nconst damConfigName = useDamConfigName(props.configName)\n\nconst { t } = useI18n()\n\nconst roiSelect = shallowRef<Component>()\nconst loadFailed = ref(false)\n\nconst load = async () => {\n loadFailed.value = false\n try {\n roiSelect.value = await loadDamAssetImageRoiSelect()\n } catch {\n loadFailed.value = true\n }\n}\n\nonMounted(load)\n</script>\n\n<template>\n <component\n :is=\"roiSelect\"\n v-if=\"roiSelect\"\n :ext-system=\"extSystem\"\n :config-name=\"damConfigName\"\n :readonly=\"readonly\"\n />\n <div\n v-else-if=\"loadFailed\"\n class=\"d-flex align-center ga-2\"\n >\n <span class=\"text-error\">{{ t('common.alert.unknownError') }}</span>\n <ABtnTertiary\n data-cy=\"button-retry-roi-select\"\n @click.stop=\"load\"\n >\n {{ t('common.button.retry') }}\n </ABtnTertiary>\n </div>\n <VProgressCircular\n v-else\n indeterminate\n color=\"primary\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAmBA,IAAMgB,IAAgBC,EAAiBjB,EAAM,UAAU,GAEjD,EAAE,SAAMmB,EAAQ,GAEhBC,IAAYC,EAAsB,GAClCC,IAAaC,EAAI,EAAK,GAEtBC,IAAO,YAAY;GACvB,EAAW,QAAQ;GACnB,IAAI;IACF,EAAU,QAAQ,MAAMC,EAA2B;GACrD,QAAQ;IACN,EAAW,QAAQ;GACrB;EACF;E,OAEAC,EAAUF,CAAI,I;;GAMJ,OAAAJ,EAAA,SAFRnB,EAAA,GAAAC,EAMEC,EALKiB,EAAA,KAAS,GAAA;;IAEb,cAAYF,EAAA;IACZ,eAAad,EAAAY,CAAA;IACb,UAAUE,EAAA;;;;;G,MAGAI,EAAA,SADbrB,EAAA,GAAAI,EAWM,OAXNQ,GAWM,CAPJP,EAAoE,QAApEQ,GAAoEP,EAAxCH,EAAAgC,CAAA,CAAC,CAAA,2BAAA,CAAA,GAAA,CAAA,GAC7B5B,EAKemB,GAAA;IAJb,WAAQ;IACP,SAAKlB,EAAOe,GAAI,CAAA,MAAA,CAAA;;IAEjB,SAAAd,QAA8B,CAA3BC,EAAAJ,EAAAH,EAAAgC,CAAA,CAAC,CAAA,qBAAA,CAAA,GAAA,CAAA,C;;G,SAGRnC,EAAA,GAAAC,EAIEU,GAAA;;IAFA,eAAA;IACA,OAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AImageMediaWidget.js","names":["
|
|
1
|
+
{"version":3,"file":"AImageMediaWidget.js","names":["AImageMediaWidget_vue_vue_type_script_setup_true_lang_default","AImageMediaWidget_default"],"sources":[],"mappings":""}
|