Repository: statamic-rad-pack/runway (php)

Issue:
Save & Publish button isn't right when Revisions are enabled
### Description

When there are unsaved changes the button says `Save & Publish` instead of `Save Changes`, because I don't necessarily want to publish this revision yet.

### Steps to reproduce

1. enable revisions
2. edit a published model
3. look at the button

### Environment


Environment
Application Name: Zakat Foundation of America
Laravel Version: 11.13.0
PHP Version: 8.3.8
Composer Version: 2.7.6
Environment: local
Debug Mode: ENABLED
URL: zakat.test
Maintenance Mode: OFF
Timezone: America/Los_Angeles
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: null
Cache: file
Database: mysql
Logs: stack / daily
Mail: smtp
Queue: sync
Session: file

Livewire
Livewire: v3.5.1

Statamic
Addons: 13
Sites: 3 (zakat.org (EN), zakat.org (AR), zfinstitute.com (ZFI))
Stache Watcher: Disabled
Static Caching: Disabled
Version: 5.11.0 PRO

Statamic Addons
aryehraber/statamic-captcha: 1.12.0
edalzell/forma: 3.0.1
jacksleight/statamic-bard-mutator: 2.3.1
jacksleight/statamic-distill: 0.7.1
jonassiewertsen/statamic-livewire: 3.6.0
statamic-rad-pack/runway: 7.5.1
statamic/seo-pro: 6.0.3
transformstudios/events: 5.4.3
transformstudios/front: 3.0.1
transformstudios/github: dev-main
transformstudios/neon: dev-feature/enable-revisions
transformstudios/review: 5.0
transformstudios/simple: 5.1.7


Pull request:
[7.x] When revisions are enabled, set the save button to Save Changes
Fixes #540 

Patch:
diff --git a/composer.json b/composer.json
index 7e1a51f..6059dd2 100644
--- a/composer.json
+++ b/composer.json
@@ -20,7 +20,10 @@
             "StatamicRadPack\\Runway\\Tests\\": "tests",
             "StatamicRadPack\\Runway\\Tests\\Fixtures\\": "tests/__fixtures__/app",
             "StatamicRadPack\\Runway\\Tests\\Fixtures\\Database\\Factories\\": "tests/__fixtures__/database/factories"
-        }
+        },
+        "classmap": [
+            "tests/__fixtures__/database"
+        ]
     },
     "extra": {
         "statamic": {
diff --git a/resources/js/components/Publish/PublishForm.vue b/resources/js/components/Publish/PublishForm.vue
index c7489c9..f8d0034 100644
--- a/resources/js/components/Publish/PublishForm.vue
+++ b/resources/js/components/Publish/PublishForm.vue
@@ -5,7 +5,7 @@
         <div class="flex items-center mb-6">
             <h1 class="flex-1">
                 <div class="flex items-center">
-                    <span v-html="$options.filters.striptags(__(title))" />
+                    <span v-html="$options.filters.striptags(title)" />
                 </div>
             </h1>
 
@@ -116,11 +116,11 @@
                                 <label class="publish-field-label font-medium mb-2" v-text="__('Revisions')"/>
                                 <div class="mb-1 flex items-center" v-if="published">
                                     <span class="text-green-600 w-6 text-center">&check;</span>
-                                    <span class="text-2xs" v-text="__('Entry has a published version')"></span>
+                                    <span class="text-2xs" v-text="__('Model has a published version')"></span>
                                 </div>
                                 <div class="mb-1 flex items-center" v-else>
                                     <span class="text-orange w-6 text-center">!</span>
-                                    <span class="text-2xs" v-text="__('Entry has not been published')"></span>
+                                    <span class="text-2xs" v-text="__('Model has not been published')"></span>
                                 </div>
                                 <div class="mb-1 flex items-center" v-if="!isWorkingCopy && published">
                                     <span class="text-green-600 w-6 text-center">&check;</span>
@@ -330,6 +330,8 @@ export default {
 
         saveText() {
             switch(true) {
+                case this.revisionsEnabled:
+                    return __('Save Changes');
                 case this.isUnpublishing:
                     return __('Save & Unpublish');
                 case this.publishStatesEnabled && this.isDraft:
diff --git a/src/Actions/Publish.php b/src/Actions/Publish.php
index d6bbacd..9bcafdb 100644
--- a/src/Actions/Publish.php
+++ b/src/Actions/Publish.php
@@ -22,11 +22,7 @@ class Publish extends Action
 
     public function visibleToBulk($items)
     {
-        if ($items->filter(fn ($item) => $item->published())->count() > 0) {
-            return false;
-        }
-
-        return true;
+        return $items->every(fn ($item) => $this->visibleTo($item));
     }
 
     public function authorize($user, $item)
diff --git a/src/Actions/Unpublish.php b/src/Actions/Unpublish.php
index a731a50..3fa1d67 100644
--- a/src/Actions/Unpublish.php
+++ b/src/Actions/Unpublish.php
@@ -22,11 +22,7 @@ class Unpublish extends Action
 
     public function visibleToBulk($items)
     {
-        if ($items->reject(fn ($item) => $item->published())->count() > 0) {
-            return false;
-        }
-
-        return true;
+        return $items->every(fn ($item) => $this->visibleTo($item));
     }
 
     public function authorize($user, $item)


Test patch:
diff --git a/tests/Actions/PublishTest.php b/tests/Actions/PublishTest.php
index ae709c1..27aac13 100644
--- a/tests/Actions/PublishTest.php
+++ b/tests/Actions/PublishTest.php
@@ -72,6 +72,18 @@ class PublishTest extends TestCase
         $this->assertTrue($visibleToBulk);
     }
 
+    /** @test */
+    public function is_not_visible_in_bulk_to_entry()
+    {
+        Collection::make('posts')->save();
+
+        Entry::make()->collection('posts')->slug('hello-world')->save();
+
+        $visibleTo = (new Publish())->context([])->visibleToBulk(Entry::all());
+
+        $this->assertFalse($visibleTo);
+    }
+
     /** @test */
     public function is_not_visible_to_eloquent_models_in_bulk_when_not_all_models_are_unpublished()
     {
diff --git a/tests/Actions/UnpublishTest.php b/tests/Actions/UnpublishTest.php
index db2eb42..e056217 100644
--- a/tests/Actions/UnpublishTest.php
+++ b/tests/Actions/UnpublishTest.php
@@ -62,6 +62,18 @@ class UnpublishTest extends TestCase
         $this->assertFalse($visibleTo);
     }
 
+    /** @test */
+    public function is_not_visible_in_bulk_to_entry()
+    {
+        Collection::make('posts')->save();
+
+        Entry::make()->collection('posts')->slug('hello-world')->save();
+
+        $visibleTo = (new Unpublish())->context([])->visibleToBulk(Entry::all());
+
+        $this->assertFalse($visibleTo);
+    }
+
     /** @test */
     public function is_visible_to_eloquent_models_in_bulk()
     {
diff --git a/tests/Http/Controllers/CP/ModelRevisionsControllerTest.php b/tests/Http/Controllers/CP/ModelRevisionsControllerTest.php
index 9866038..603caa7 100644
--- a/tests/Http/Controllers/CP/ModelRevisionsControllerTest.php
+++ b/tests/Http/Controllers/CP/ModelRevisionsControllerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Http\Controllers\CP;
+namespace StatamicRadPack\Runway\Tests\Http\Controllers\CP;
 
 use Illuminate\Support\Carbon;
 use Statamic\Facades\Folder;
diff --git a/tests/Http/Controllers/CP/PublishedModelsControllerTest.php b/tests/Http/Controllers/CP/PublishedModelsControllerTest.php
index 832957d..98afa38 100644
--- a/tests/Http/Controllers/CP/PublishedModelsControllerTest.php
+++ b/tests/Http/Controllers/CP/PublishedModelsControllerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Http\Controllers\CP;
+namespace StatamicRadPack\Runway\Tests\Http\Controllers\CP;
 
 use Statamic\Facades\Folder;
 use Statamic\Facades\User;
diff --git a/tests/Http/Controllers/CP/RestoreModelRevisionController.php b/tests/Http/Controllers/CP/RestoreModelRevisionController.php
index 07676e0..233cedb 100644
--- a/tests/Http/Controllers/CP/RestoreModelRevisionController.php
+++ b/tests/Http/Controllers/CP/RestoreModelRevisionController.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Http\Controllers\CP;
+namespace StatamicRadPack\Runway\Tests\Http\Controllers\CP;
 
 use Statamic\Facades\Folder;
 use Statamic\Facades\User;