├── .DS_Store ├── .github ├── ISSUE_TEMPLATE │ └── config.yml ├── dependabot.yml └── workflows │ ├── contributors.yml │ ├── dependabot-auto-merge.yml │ ├── main.yml │ ├── php-cs-fixer.yml │ ├── phpstan.yml │ ├── run-tests.yml │ └── update-changelog.yml ├── .gitignore ├── .idea ├── .gitignore ├── blade.xml ├── filament-confirm-delete.iml ├── laravel-idea-personal.xml ├── laravel-idea.xml ├── modules.xml ├── php.xml ├── phpunit.xml └── vcs.xml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── art ├── .DS_Store └── screenshot.png ├── build └── report.junit.xml ├── composer.json ├── composer.lock ├── config └── filament-safely-delete.php ├── phpstan-baseline.neon ├── phpstan.neon.dist ├── phpunit.xml.dist ├── resources └── lang │ └── en │ └── actions.php ├── src ├── Concerns │ └── HasFieldConfirmation.php ├── Exceptions │ ├── ModelNotSoftDeletedException.php │ └── RevertableTraitNotImplemented.php ├── FilamentSafelyDeleteServiceProvider.php ├── Pages │ ├── Actions │ │ └── DeleteAction.php │ └── Concerns │ │ └── HasRevertableRecord.php └── Tables │ └── Actions │ ├── DeleteAction.php │ └── RevertableDeleteAction.php └── tests ├── Features ├── ActionPageTest.php └── ActionTableTest.php ├── Migrations └── post_migration.php ├── Pest.php ├── Resources ├── Models │ └── Post.php ├── Pages │ └── ListPost.php └── PostResource.php └── TestCase.php /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konnco/filament-safely-delete/62e74a855125db316e72191fc7a2401065050962/.DS_Store -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a question 4 | url: https://github.com/konnco/filament-import/discussions/new?category=q-a 5 | about: Ask the community for help 6 | - name: Request a feature 7 | url: https://github.com/konnco/filament-import/discussions/new?category=ideas 8 | about: Share ideas for new features 9 | - name: Report a security issue 10 | url: https://github.com/konnco/filament-import/security/policy 11 | about: Learn how to notify us for sensitive bugs 12 | - name: Report a bug 13 | url: https://github.com/konnco/filament-import/issues/new 14 | about: Report a reproducible bug 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Please see the documentation for all configuration options: 2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 3 | 4 | version: 2 5 | updates: 6 | 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | labels: 12 | - "dependencies" -------------------------------------------------------------------------------- /.github/workflows/contributors.yml: -------------------------------------------------------------------------------- 1 | name: Add contributors 2 | on: 3 | schedule: 4 | - cron: '20 20 * * *' 5 | # push: 6 | # branches: 7 | # - master 8 | 9 | jobs: 10 | add-contributors: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: BobAnkh/add-contributors@master 15 | with: 16 | CONTRIBUTOR: '### Contributors' 17 | COLUMN_PER_ROW: '6' 18 | ACCESS_TOKEN: ${{secrets.GITHUB_TOKEN}} 19 | IMG_WIDTH: '100' 20 | FONT_SIZE: '14' 21 | PATH: '/README.md' 22 | COMMIT_MESSAGE: 'docs(README): update contributors' 23 | AVATAR_SHAPE: 'round' 24 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: dependabot-auto-merge 2 | on: pull_request_target 3 | 4 | permissions: 5 | pull-requests: write 6 | contents: write 7 | 8 | jobs: 9 | dependabot: 10 | runs-on: ubuntu-latest 11 | if: ${{ github.actor == 'dependabot[bot]' }} 12 | steps: 13 | 14 | - name: Dependabot metadata 15 | id: metadata 16 | uses: dependabot/fetch-metadata@v1.6.0 17 | with: 18 | github-token: "${{ secrets.GITHUB_TOKEN }}" 19 | 20 | - name: Auto-merge Dependabot PRs for semver-minor updates 21 | if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor'}} 22 | run: gh pr merge --auto --merge "$PR_URL" 23 | env: 24 | PR_URL: ${{github.event.pull_request.html_url}} 25 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 26 | 27 | - name: Auto-merge Dependabot PRs for semver-patch updates 28 | if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}} 29 | run: gh pr merge --auto --merge "$PR_URL" 30 | env: 31 | PR_URL: ${{github.event.pull_request.html_url}} 32 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | jobs: 7 | contrib-readme-job: 8 | runs-on: ubuntu-latest 9 | name: A job to automate contrib in readme 10 | steps: 11 | - name: Contribute List 12 | uses: akhilmhdh/contributors-readme-action@v2.3.6 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.github/workflows/php-cs-fixer.yml: -------------------------------------------------------------------------------- 1 | name: Fix PHP code style issues 2 | 3 | on: [push] 4 | 5 | jobs: 6 | php-code-styling: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v3 12 | with: 13 | ref: ${{ github.head_ref }} 14 | 15 | - name: Fix PHP code style issues 16 | uses: aglipanci/laravel-pint-action@2.3.0 17 | 18 | - name: Commit changes 19 | uses: stefanzweifel/git-auto-commit-action@v4 20 | with: 21 | commit_message: Fix styling 22 | -------------------------------------------------------------------------------- /.github/workflows/phpstan.yml: -------------------------------------------------------------------------------- 1 | name: PHPStan 2 | 3 | on: 4 | push: 5 | paths: 6 | - "**.php" 7 | - "phpstan.neon.dist" 8 | 9 | jobs: 10 | phpstan: 11 | name: phpstan 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Setup PHP 17 | uses: shivammathur/setup-php@v2 18 | with: 19 | php-version: "8.1" 20 | coverage: none 21 | 22 | - name: Install composer dependencies 23 | uses: ramsey/composer-install@v1 24 | 25 | - name: Run PHPStan 26 | run: ./vendor/bin/phpstan --error-format=github 27 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: run-tests 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | test: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: true 14 | matrix: 15 | os: [ubuntu-latest, windows-latest] 16 | php: [8.1] 17 | laravel: [9.*] 18 | stability: [prefer-stable] 19 | include: 20 | - laravel: 9.* 21 | testbench: 7.* 22 | 23 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v3 28 | 29 | - name: Setup PHP 30 | uses: shivammathur/setup-php@v2 31 | with: 32 | php-version: ${{ matrix.php }} 33 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo 34 | coverage: none 35 | 36 | - name: Setup problem matchers 37 | run: | 38 | echo "::add-matcher::${{ runner.tool_cache }}/php.json" 39 | echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" 40 | - name: Install dependencies 41 | run: | 42 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update 43 | composer update --${{ matrix.stability }} --prefer-dist --no-interaction 44 | - name: Execute tests 45 | run: vendor/bin/pest 46 | -------------------------------------------------------------------------------- /.github/workflows/update-changelog.yml: -------------------------------------------------------------------------------- 1 | name: "Update Changelog" 2 | 3 | on: 4 | release: 5 | types: [released] 6 | 7 | jobs: 8 | update: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | with: 15 | ref: main 16 | 17 | - name: Update Changelog 18 | uses: stefanzweifel/changelog-updater-action@v1 19 | with: 20 | latest-version: ${{ github.event.release.name }} 21 | release-notes: ${{ github.event.release.body }} 22 | 23 | - name: Commit updated CHANGELOG 24 | uses: stefanzweifel/git-auto-commit-action@v4 25 | with: 26 | branch: main 27 | commit_message: Update CHANGELOG 28 | file_pattern: CHANGELOG.md -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | .phpunit.result.cache 3 | 4 | build/phpstan 5 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/blade.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /.idea/filament-confirm-delete.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /.idea/laravel-idea-personal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/laravel-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /.idea/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `konnco/filament-safely-delete` will be documented in this file. 4 | 5 | ## 0.3.2 - 2023-02-24 6 | 7 | ### What's Changed 8 | 9 | - Skip validation in testing environment by @thyseus in https://github.com/konnco/filament-safely-delete/pull/3 10 | - Bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 by @dependabot in https://github.com/konnco/filament-safely-delete/pull/4 11 | - Bump dependabot/fetch-metadata from 1.3.4 to 1.3.5 by @dependabot in https://github.com/konnco/filament-safely-delete/pull/5 12 | - Bump dependabot/fetch-metadata from 1.3.5 to 1.3.6 by @dependabot in https://github.com/konnco/filament-safely-delete/pull/8 13 | - Allow usage in Laravel 10 by @thyseus in https://github.com/konnco/filament-safely-delete/pull/9 14 | 15 | ### New Contributors 16 | 17 | - @thyseus made their first contribution in https://github.com/konnco/filament-safely-delete/pull/3 18 | 19 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/0.3.1...0.3.2 20 | 21 | ## 0.3.1 - 2022-09-27 22 | 23 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/0.3.0...0.3.1 24 | 25 | ## 0.3.0 - 2022-09-27 26 | 27 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/0.2.0...0.3.0 28 | 29 | Added Undo Button for RevertableDeleteAction 30 | 31 | ## 0.2.0 - 2022-09-27 32 | 33 | ### What's Changed 34 | 35 | - Update DeleteAction.php by @ijalnasution in https://github.com/konnco/filament-safely-delete/pull/2 36 | 37 | ### New Contributors 38 | 39 | - @ijalnasution made their first contribution in https://github.com/konnco/filament-safely-delete/pull/2 40 | 41 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/0.1.0...0.2.0 42 | 43 | ## 0.1.0 - 2022-09-27 44 | 45 | ### What's Changed 46 | 47 | - Bump actions/checkout from 2 to 3 by @dependabot in https://github.com/konnco/filament-safely-delete/pull/1 48 | 49 | ### New Contributors 50 | 51 | - @dependabot made their first contribution in https://github.com/konnco/filament-safely-delete/pull/1 52 | 53 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/v.1.0.0...0.1.0 54 | 55 | ## v.1.0.0 - 2022-09-26 56 | 57 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/compare/v.0.1.0...v.1.0.0 58 | 59 | ## v.0.1.0 - 2022-09-26 60 | 61 | **Full Changelog**: https://github.com/konnco/filament-safely-delete/commits/v.0.1.0 62 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) :vendor_name 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Screenshot of Login](./art/screenshot.png) 2 | 3 | # Filament Confirm Delete 4 | 5 | 6 | FILAMENT 2.x 7 | 8 | 9 | Packagist 10 | 11 | 12 | Downloads 13 | 14 | 15 | [![Code Styles](https://github.com/konnco/filament-safely-delete/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/konnco/filament-safely-delete/actions/workflows/php-cs-fixer.yml) 16 | [![run-tests](https://github.com/konnco/filament-safely-delete/actions/workflows/run-tests.yml/badge.svg)](https://github.com/konnco/filament-safely-delete/actions/workflows/run-tests.yml) 17 | 18 | This plugin is intended for those of you who are worried about your data being accidentally deleted. 19 | 20 | ## Installation 21 | 22 | You can install the package via composer: 23 | 24 | ```bash 25 | composer require konnco/filament-safely-delete 26 | ``` 27 | 28 | ## Usage 29 | 30 | import the actions into the `Resource` page 31 | 32 | ```php 33 | use Konnco\FilamentSafelyDelete\Tables\Actions\RevertableDeleteAction; 34 | 35 | class PostResource extends Resource 36 | { 37 | public static function table(Table $table): Table 38 | { 39 | return $table 40 | ->columns([ 41 | Tables\Columns\TextColumn::make('title'), 42 | Tables\Columns\TextColumn::make('slug'), 43 | Tables\Columns\TextColumn::make('body'), 44 | ]) 45 | ->filters([ 46 | // 47 | ]) 48 | ->actions([ 49 | Tables\Actions\EditAction::make(), 50 | DeleteAction::make() 51 | ->usingField('title') 52 | ]) 53 | ->bulkActions([ 54 | Tables\Actions\DeleteBulkAction::make(), 55 | ]); 56 | } 57 | } 58 | ``` 59 | 60 | ### Undo Delete 61 | You can also use to delete undo in your resource. 62 | 63 | ```php 64 | use Konnco\FilamentSafelyDelete\Tables\Actions\RevertableDeleteAction; 65 | 66 | class PostResource extends Resource 67 | { 68 | public static function table(Table $table): Table 69 | { 70 | return $table 71 | ->columns([ 72 | Tables\Columns\TextColumn::make('title'), 73 | Tables\Columns\TextColumn::make('slug'), 74 | Tables\Columns\TextColumn::make('body'), 75 | ]) 76 | ->filters([ 77 | // 78 | ]) 79 | ->actions([ 80 | Tables\Actions\EditAction::make(), 81 | RevertableDeleteAction::make() 82 | ]) 83 | ->bulkActions([ 84 | Tables\Actions\DeleteBulkAction::make(), 85 | ]); 86 | } 87 | } 88 | ``` 89 | 90 | and implementing `HasRevertableRecord` traits in your `ListRecords` 91 | ```php 92 | use Konnco\FilamentSafelyDelete\Pages\Concerns\HasRevertableRecord; 93 | 94 | class ListBlogPosts extends ListRecords 95 | { 96 | use HasRevertableRecord; 97 | ``` 98 | 99 | 100 | ## Testing 101 | 102 | ```bash 103 | composer test 104 | ``` 105 | 106 | ## Changelog 107 | 108 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 109 | 110 | ## Contributing 111 | 112 | Please see [CONTRIBUTING](https://github.com/konnco/.github/blob/main/CONTRIBUTING.md) for details. 113 | 114 | ## Security Vulnerabilities 115 | 116 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 117 | 118 | ### Contributors 119 | 120 | 121 | 122 | 129 | 136 | 143 | 144 |
123 | 124 | Franky 125 |
126 | Franky So 127 |
128 |
130 | 131 | Herbert 132 |
133 | Herbert Maschke 134 |
135 |
137 | 138 | abangijal/ 139 |
140 | abangijal 141 |
142 |
145 | 146 | 147 | 148 | 149 | 156 | 163 | 170 |
150 | 151 | frankyso 152 |
153 | Franky So 154 |
155 |
157 | 158 | thyseus 159 |
160 | Herbert Maschke 161 |
162 |
164 | 165 | ijalnasution 166 |
167 | Abangijal 168 |
169 |
171 | 172 | -------------------------------------------------------------------------------- /art/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konnco/filament-safely-delete/62e74a855125db316e72191fc7a2401065050962/art/.DS_Store -------------------------------------------------------------------------------- /art/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konnco/filament-safely-delete/62e74a855125db316e72191fc7a2401065050962/art/screenshot.png -------------------------------------------------------------------------------- /build/report.junit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "konnco/filament-safely-delete", 3 | "description": "", 4 | "keywords": [ 5 | "import", 6 | "laravel", 7 | "filament-safely-delete" 8 | ], 9 | "autoload": { 10 | "psr-4": { 11 | "Konnco\\FilamentSafelyDelete\\": "src/" 12 | } 13 | }, 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "Franky So", 18 | "email": "frankyso.mail@gmail.com" 19 | } 20 | ], 21 | "require": { 22 | "php": "^8.0", 23 | "filament/filament": "^2.0", 24 | "filament/notifications": "^2.0", 25 | "illuminate/contracts": "^9.0|^10.0", 26 | "illuminate/support": "^9.0|^10.0", 27 | "spatie/laravel-package-tools": "^1.9.2" 28 | }, 29 | "require-dev": { 30 | "laravel/pint": "^1.0", 31 | "nunomaduro/collision": "^6.0", 32 | "nunomaduro/larastan": "^2.0.1", 33 | "orchestra/testbench": "^7.0", 34 | "pestphp/pest": "^1.21", 35 | "pestphp/pest-plugin-laravel": "^1.1", 36 | "phpstan/extension-installer": "^1.1", 37 | "phpstan/phpstan-deprecation-rules": "^1.0", 38 | "phpstan/phpstan-phpunit": "^1.0", 39 | "phpunit/phpunit": "^9.5|^10.0" 40 | }, 41 | "autoload-dev": { 42 | "psr-4": { 43 | "Konnco\\FilamentSafelyDelete\\Tests\\": "tests" 44 | } 45 | }, 46 | "scripts": { 47 | "analyse": "vendor/bin/phpstan analyse", 48 | "test": "vendor/bin/pest", 49 | "test-coverage": "vendor/bin/pest --coverage", 50 | "format": "vendor/bin/pint" 51 | }, 52 | "config": { 53 | "sort-packages": true, 54 | "allow-plugins": { 55 | "pestphp/pest-plugin": true, 56 | "phpstan/extension-installer": true 57 | } 58 | }, 59 | "minimum-stability": "dev", 60 | "prefer-stable": true, 61 | "extra": { 62 | "laravel": { 63 | "providers": [ 64 | "Konnco\\FilamentSafelyDelete\\FilamentSafelyDeleteServiceProvider" 65 | ] 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /config/filament-safely-delete.php: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | tests 24 | 25 | 26 | 27 | 28 | ./src 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /resources/lang/en/actions.php: -------------------------------------------------------------------------------- 1 | 'Type ":name"', 5 | 'validation' => 'The keyword must be ":name"', 6 | ]; 7 | -------------------------------------------------------------------------------- /src/Concerns/HasFieldConfirmation.php: -------------------------------------------------------------------------------- 1 | usingField = $usingField; 12 | 13 | return $this; 14 | } 15 | 16 | public function getUsingField(): string 17 | { 18 | return $this->usingField; 19 | } 20 | 21 | public function getDeleteRecordConfirmationTypingText(): string 22 | { 23 | return $this->getRecord()?->{$this->getUsingField()} ?? ''; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Exceptions/ModelNotSoftDeletedException.php: -------------------------------------------------------------------------------- 1 | name('filament-safely-delete') 13 | ->hasConfigFile() 14 | ->hasTranslations(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Pages/Actions/DeleteAction.php: -------------------------------------------------------------------------------- 1 | form([ 24 | TextInput::make('name') 25 | ->label(fn () => trans('filament-safely-delete::actions.input_label', ['name' => $this->getDeleteRecordConfirmationTypingText()])) 26 | ->rules([ 27 | function () { 28 | return function (string $attribute, $value, Closure $fail) { 29 | if ($value !== $this->getDeleteRecordConfirmationTypingText()) { 30 | $fail(trans('filament-safely-delete::actions.validation', ['name' => $this->getDeleteRecordConfirmationTypingText()])); 31 | } 32 | }; 33 | }, 34 | ]) 35 | ->required(), 36 | ]); 37 | 38 | $this->action(function (array $data, Model $record): void { 39 | if ($data['name'] === $this->getDeleteRecordConfirmationTypingText()) { 40 | $this->process(static fn (Model $record) => $record->delete()); 41 | $this->success(); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Pages/Concerns/HasRevertableRecord.php: -------------------------------------------------------------------------------- 1 | listeners = array_merge($this->listeners, [ 12 | 'undoDeleteRecord', 13 | ]); 14 | } 15 | 16 | public function undoDeleteRecord($id) 17 | { 18 | $model = $this->getModel()::withTrashed()->find($id); 19 | $model->restore(); 20 | 21 | Notification::make() 22 | ->title('Restored!') 23 | ->success() 24 | ->send(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Tables/Actions/DeleteAction.php: -------------------------------------------------------------------------------- 1 | form([ 24 | TextInput::make('name') 25 | ->label(fn () => trans('filament-safely-delete::actions.input_label', ['name' => $this->getDeleteRecordConfirmationTypingText()])) 26 | ->rules([ 27 | function () { 28 | return function (string $attribute, $value, Closure $fail) { 29 | if ($value !== $this->getDeleteRecordConfirmationTypingText()) { 30 | $fail(trans('filament-safely-delete::actions.validation', ['name' => $this->getDeleteRecordConfirmationTypingText()])); 31 | } 32 | }; 33 | }, 34 | ]) 35 | ->required(), 36 | ]); 37 | 38 | $this->action(function (array $data, Model $record): void { 39 | if ($data['name'] === $this->getDeleteRecordConfirmationTypingText()) { 40 | $this->process(static fn (Model $record) => $record->delete()); 41 | $this->success(); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Tables/Actions/RevertableDeleteAction.php: -------------------------------------------------------------------------------- 1 | color('danger'); 21 | $this->groupedIcon('heroicon-s-trash'); 22 | $this->icon('heroicon-s-trash'); 23 | $this->label(__('filament-support::actions/delete.single.label')); 24 | 25 | $this->action(function (array $data, Model $record): void { 26 | $this->ensureModelIsSoftDeleted(); 27 | $this->ensureListRecordHasImplementedRevertTrait(); 28 | 29 | $this->process(static fn (Model $record) => $record->delete()); 30 | 31 | Notification::make() 32 | ->title('Deleted') 33 | ->success() 34 | ->body('**'.$this->getModelLabel().'** have been deleted.') 35 | ->actions([ 36 | Action::make('undo') 37 | ->color('secondary') 38 | ->button() 39 | ->emit('undoDeleteRecord', [$record->id]) 40 | ->close(), 41 | ]) 42 | ->send(); 43 | }); 44 | } 45 | 46 | /** 47 | * @throws Throwable 48 | * @throws RevertableTraitNotImplemented 49 | */ 50 | protected function ensureModelIsSoftDeleted(): void 51 | { 52 | throw_if( 53 | ! in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->getModel())), 54 | new RevertableTraitNotImplemented 55 | ); 56 | } 57 | 58 | protected function ensureListRecordHasImplementedRevertTrait() 59 | { 60 | throw_if( 61 | ! in_array('Konnco\FilamentSafelyDelete\Pages\Concerns\HasRevertableRecord', class_uses($this->getLivewire())), 62 | new RevertableTraitNotImplemented('You need to implement trait Konnco\FilamentSafelyDelete\Pages\Concerns\HasRevertableRecord into '.get_class($this->getLivewire())) 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Features/ActionPageTest.php: -------------------------------------------------------------------------------- 1 | forceFill(['title' => fake()->title, 'slug' => fake()->slug, 'body' => fake()->text]); 10 | $post->save(); 11 | 12 | livewire() 13 | ->callTableAction(DeleteAction::class, $post, data: [ 14 | 'name' => $post->title, 15 | ])->assertHasNoTableActionErrors(); 16 | 17 | assertDatabaseCount(Post::class, 0); 18 | }); 19 | 20 | it('can validate the confirmation name', function () { 21 | $post = (new Post)->forceFill(['title' => fake()->title, 'slug' => fake()->slug, 'body' => fake()->text]); 22 | $post->save(); 23 | 24 | livewire() 25 | ->callTableAction(DeleteAction::class, $post, data: [ 26 | 'name' => $post->title.Str::random(2), 27 | ])->assertHasTableActionErrors(); 28 | 29 | assertDatabaseCount(Post::class, 1); 30 | }); 31 | 32 | //it('can delete with bulk actions and should type member current password', function () { 33 | //}); 34 | 35 | //it('can change the method into delete rollback functions', function () { 36 | //}); 37 | 38 | //it('can change the method into delete rollback functions', function () { 39 | //}); 40 | -------------------------------------------------------------------------------- /tests/Features/ActionTableTest.php: -------------------------------------------------------------------------------- 1 | forceFill(['title' => fake()->title, 'slug' => fake()->slug, 'body' => fake()->text]); 10 | $post->save(); 11 | 12 | livewire() 13 | ->callTableAction(DeleteAction::class, $post, data: [ 14 | 'name' => $post->title, 15 | ])->assertHasNoTableActionErrors(); 16 | 17 | assertDatabaseCount(Post::class, 0); 18 | }); 19 | 20 | it('can validate the confirmation name', function () { 21 | $post = (new Post)->forceFill(['title' => fake()->title, 'slug' => fake()->slug, 'body' => fake()->text]); 22 | $post->save(); 23 | 24 | livewire() 25 | ->callTableAction(DeleteAction::class, $post, data: [ 26 | 'name' => $post->title.Str::random(2), 27 | ])->assertHasTableActionErrors(); 28 | 29 | assertDatabaseCount(Post::class, 1); 30 | }); 31 | 32 | //it('can delete with bulk actions and should type member current password', function () { 33 | //}); 34 | 35 | //it('can change the method into delete rollback functions', function () { 36 | //}); 37 | 38 | //it('can change the method into delete rollback functions', function () { 39 | //}); 40 | -------------------------------------------------------------------------------- /tests/Migrations/post_migration.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('title'); 17 | $table->string('slug'); 18 | $table->string('body'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('posts'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /tests/Pest.php: -------------------------------------------------------------------------------- 1 | in(__DIR__); 8 | 9 | function livewire() 10 | { 11 | return Livewire::test(ListPost::class); 12 | } 13 | -------------------------------------------------------------------------------- /tests/Resources/Models/Post.php: -------------------------------------------------------------------------------- 1 | schema([ 22 | Forms\Components\TextInput::make('title') 23 | ->required() 24 | ->maxLength(255), 25 | Forms\Components\TextInput::make('slug') 26 | ->required() 27 | ->maxLength(255), 28 | Forms\Components\TextInput::make('body') 29 | ->required() 30 | ->maxLength(255), 31 | ]); 32 | } 33 | 34 | public static function table(Table $table): Table 35 | { 36 | return $table 37 | ->columns([ 38 | Tables\Columns\TextColumn::make('title'), 39 | Tables\Columns\TextColumn::make('slug'), 40 | Tables\Columns\TextColumn::make('body'), 41 | Tables\Columns\TextColumn::make('created_at') 42 | ->dateTime(), 43 | Tables\Columns\TextColumn::make('updated_at') 44 | ->dateTime(), 45 | ]) 46 | ->filters([ 47 | // 48 | ]) 49 | ->actions([ 50 | Tables\Actions\EditAction::make(), 51 | DeleteAction::make('delete') 52 | ->usingField('title'), 53 | ]) 54 | ->bulkActions([ 55 | Tables\Actions\DeleteBulkAction::make(), 56 | ]); 57 | } 58 | 59 | public static function getRelations(): array 60 | { 61 | return [ 62 | // 63 | ]; 64 | } 65 | 66 | public static function getPages(): array 67 | { 68 | return [ 69 | 'index' => ListPost::route('/'), 70 | ]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | set('database.default', 'sqlite'); 41 | config()->set('database.connections.sqlite', [ 42 | 'driver' => 'sqlite', 43 | 'database' => ':memory:', 44 | 'prefix' => '', 45 | ]); 46 | 47 | $migration = include __DIR__.'/Migrations/post_migration.php'; 48 | $migration->up(); 49 | 50 | config()->set('filament.resources.namespace', 'Konnco\\FilamentSafelyDelete\\Tests\\Resources'); 51 | config()->set('filament.resources.path', __DIR__.'/Resources'); 52 | 53 | config()->set('app.key', '6rE9Nz59bGRbeMATftriyQjrpF7DcOQm'); 54 | } 55 | } 56 | --------------------------------------------------------------------------------