diff --git a/lang/en/messages.php b/lang/en/messages.php index 9ed47bf6e81..46b55198a72 100644 --- a/lang/en/messages.php +++ b/lang/en/messages.php @@ -21,8 +21,15 @@ 'blueprints_intro' => 'Blueprints define and organize fields into content models for collections, forms, and other data.', 'blueprints_title_instructions' => 'Use a singular noun, such as \'Article\' or \'Product\'', 'cache_utility_application_cache_description' => 'Laravel\'s unified cache used by Statamic, third party addons, and composer packages.', + 'cache_utility_asset_images_cleared' => '{1} Cleared :count cached image (:size) for :asset in :time.|[0,*] Cleared :count cached images (:size) for :asset in :time.', + 'cache_utility_coverage' => '{1} :cached of :total warmable URL cached.|[0,*] :cached of :total warmable URLs cached.', 'cache_utility_description' => 'Manage and view important information about Statamic\'s various caching layers.', 'cache_utility_image_cache_description' => 'The image cache stores copies of all transformed and resized images.', + 'cache_utility_images_cleared' => '{1} Cleared :count cached image (:size) from :container in :time.|[0,*] Cleared :count cached images (:size) from :container in :time.', + 'cache_utility_invalidated' => '{1} Cleared :count cached page in :time.|[0,*] Cleared :count cached pages in :time.', + 'cache_utility_matches' => '{0} No cached pages match these URLs.|{1} :count cached page matches.|[2,*] :count cached pages match.', + 'cache_utility_pages_cache_failed' => '{1} :count page could not be cached.|[0,*] :count pages could not be cached.', + 'cache_utility_pages_cached' => '{1} Cached :count page.|[0,*] Cached :count pages.', 'cache_utility_stache_description' => 'The Stache is Statamic\'s content store that functions much like a database. It is generated automatically from the content files.', 'cache_utility_static_cache_description' => 'Static pages bypass Statamic completely and are rendered directly from the server for maximum performance.', 'choose_entry_localization_deletion_behavior' => 'Choose the action you wish to perform on the localized entries.', diff --git a/resources/js/components/ui/Listing/BulkActionsFloatingToolbar.vue b/resources/js/components/ui/Listing/BulkActionsFloatingToolbar.vue index 63aef1f3230..65a1498aa96 100644 --- a/resources/js/components/ui/Listing/BulkActionsFloatingToolbar.vue +++ b/resources/js/components/ui/Listing/BulkActionsFloatingToolbar.vue @@ -8,7 +8,7 @@ * Select-all-matching uses A (always reserved so actions skip it). */ import { Motion } from 'motion-v'; -import { computed, onMounted, onUnmounted } from 'vue'; +import { computed, onMounted, onUnmounted, ref } from 'vue'; import { Button, ButtonGroup, Icon } from '@ui'; // ——— Keyboard shortcut constants ——— @@ -38,6 +38,7 @@ const props = defineProps({ const hasSelections = computed(() => (props.selections?.length ?? 0) > 0); const showSelectAllMatching = computed(() => !!props.canSelectAllMatching); const isSelectingAllMatching = computed(() => !!props.selectingAllMatching); +const toolbar = ref(null); /** True if this action is the built-in delete (by handle or trash icon). */ function isDeleteAction(action) { @@ -75,9 +76,11 @@ const actionsWithShortcuts = computed(() => { // ——— Keyboard handler: skip when overlays or form controls have focus ——— function hasOpenOverlay() { - return !!document.querySelector( + const overlays = document.querySelectorAll( '[data-ui-modal-content], [data-ui-dropdown-menu], .stack-content, [role="dialog"]' ); + + return Array.from(overlays).some((overlay) => !overlay.contains(toolbar.value)); } function isInsideFormControl(event) { @@ -143,6 +146,7 @@ onUnmounted(() => document.removeEventListener('keydown', onKeydown, true)); :transition="{ duration: 0.2, ease: 'easeInOut' }" >
diff --git a/resources/js/components/utilities/CacheBulkActions.vue b/resources/js/components/utilities/CacheBulkActions.vue new file mode 100644 index 00000000000..a437e6cbf52 --- /dev/null +++ b/resources/js/components/utilities/CacheBulkActions.vue @@ -0,0 +1,64 @@ + + + diff --git a/resources/js/components/utilities/CacheListing.vue b/resources/js/components/utilities/CacheListing.vue new file mode 100644 index 00000000000..66ea4885c0b --- /dev/null +++ b/resources/js/components/utilities/CacheListing.vue @@ -0,0 +1,113 @@ + + + diff --git a/resources/js/components/utilities/ImageCacheAssets.vue b/resources/js/components/utilities/ImageCacheAssets.vue new file mode 100644 index 00000000000..a237432b017 --- /dev/null +++ b/resources/js/components/utilities/ImageCacheAssets.vue @@ -0,0 +1,161 @@ + + + diff --git a/resources/js/components/utilities/ImageCacheBreadcrumbs.vue b/resources/js/components/utilities/ImageCacheBreadcrumbs.vue new file mode 100644 index 00000000000..e1b18764405 --- /dev/null +++ b/resources/js/components/utilities/ImageCacheBreadcrumbs.vue @@ -0,0 +1,71 @@ + + + diff --git a/resources/js/components/utilities/ImageCacheExplorer.vue b/resources/js/components/utilities/ImageCacheExplorer.vue new file mode 100644 index 00000000000..77350723ae0 --- /dev/null +++ b/resources/js/components/utilities/ImageCacheExplorer.vue @@ -0,0 +1,195 @@ + + + diff --git a/resources/js/components/utilities/ImageCacheVariants.vue b/resources/js/components/utilities/ImageCacheVariants.vue new file mode 100644 index 00000000000..17c105f1459 --- /dev/null +++ b/resources/js/components/utilities/ImageCacheVariants.vue @@ -0,0 +1,179 @@ + + + diff --git a/resources/js/components/utilities/StaticCacheExplorer.vue b/resources/js/components/utilities/StaticCacheExplorer.vue new file mode 100644 index 00000000000..8dc267a4089 --- /dev/null +++ b/resources/js/components/utilities/StaticCacheExplorer.vue @@ -0,0 +1,257 @@ + + + diff --git a/resources/js/pages/utilities/Cache.vue b/resources/js/pages/utilities/Cache.vue index b6c34b95792..da77ba1fadb 100644 --- a/resources/js/pages/utilities/Cache.vue +++ b/resources/js/pages/utilities/Cache.vue @@ -1,237 +1,569 @@