Skip to content

Commit

Permalink
Add resource
Browse files Browse the repository at this point in the history
  • Loading branch information
a21ns1g4ts committed Dec 2, 2024
1 parent 12eb8fa commit 911b05c
Show file tree
Hide file tree
Showing 12 changed files with 577 additions and 33 deletions.
33 changes: 5 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# This is my package filament-short-url
# Filament ShortURL

![Art](./art.png)

[![Latest Version on Packagist](https://img.shields.io/packagist/v/a21ns1g4ts/filament-short-url.svg?style=flat-square)](https://packagist.org/packages/a21ns1g4ts/filament-short-url)
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/a21ns1g4ts/filament-short-url/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/a21ns1g4ts/filament-short-url/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/a21ns1g4ts/filament-short-url/fix-php-code-styling.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/a21ns1g4ts/filament-short-url/actions?query=workflow%3A"Fix+PHP+code+styling"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/a21ns1g4ts/filament-short-url.svg?style=flat-square)](https://packagist.org/packages/a21ns1g4ts/filament-short-url)


### Filament for https://github.com/ash-jc-allen/short-url

This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.

Expand All @@ -20,36 +23,10 @@ composer require a21ns1g4ts/filament-short-url
You can publish and run the migrations with:

```bash
php artisan vendor:publish --tag="filament-short-url-migrations"
php artisan vendor:publish --provider="AshAllenDesign\ShortURL\Providers\ShortURLProvider"
php artisan migrate
```

You can publish the config file with:

```bash
php artisan vendor:publish --tag="filament-short-url-config"
```

Optionally, you can publish the views using

```bash
php artisan vendor:publish --tag="filament-short-url-views"
```

This is the contents of the published config file:

```php
return [
];
```

## Usage

```php
$filamentShortUrl = new A21ns1g4ts\FilamentShortUrl();
echo $filamentShortUrl->echoPhrase('Hello, A21ns1g4ts!');
```

## Testing

```bash
Expand Down
Binary file added art.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
],
"require": {
"php": "^8.1",
"ashallendesign/short-url": "^8.1",
"filament/filament": "^3.0",
"spatie/laravel-package-tools": "^1.15.0"
},
Expand Down
294 changes: 294 additions & 0 deletions src/Filament/Resources/ShortUrlResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
<?php

namespace A21ns1g4ts\FilamentShortUrl\Filament\Resources;

use A21ns1g4ts\FilamentShortUrl\Filament\Resources\ShortUrlResource\Pages;
use A21ns1g4ts\FilamentShortUrl\Filament\Resources\ShortUrlResource\Widgets\ShortUrlStats;
use AshAllenDesign\ShortURL\Models\ShortURL;
use Filament\Forms;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Infolists\Components;
use Filament\Infolists\Infolist;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Pages\SubNavigationPosition;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;

class ShortUrlResource extends Resource
{
protected static ?string $model = ShortURL::class;

protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

protected static SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;

public static function isScopedToTenant(): bool
{
return false;
}

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make()
->schema([
Group::make()
->schema([
Forms\Components\TextInput::make('destination_url')
->required()
->live()
->maxLength(255)
->url()
->columnSpan(['lg' => 3, 'xs' => 6]),
Forms\Components\TextInput::make('default_short_url')
->readOnly()
->maxLength(255)
->columnSpan(['xl' => 2, 'xs' => 6]),
Forms\Components\TextInput::make('url_key')
->readOnly()
->maxLength(255)
->columnSpan(['xl' => 1, 'xs' => 6]),
])
->columns(6)
->columnSpanFull(),
Group::make()
->schema([
Toggle::make('single_use')
->disabledOn('create')
->columns(1),
Toggle::make('forward_query_params')
->disabledOn('create')
->columns(1),
Toggle::make('track_visits')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_ip_address')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_operating_system')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_operating_system_version')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_browser')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_browser_version')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_referer_url')
->disabledOn('create')
->default(true)
->columns(1),
Toggle::make('track_device_type')
->disabledOn('create')
->default(true)
->columns(1),
])
->columns(5)
->columnSpanFull(),
Group::make()
->schema([
Forms\Components\DateTimePicker::make('activated_at'),
Forms\Components\DateTimePicker::make('deactivated_at'),
])
->columns(3)
->columnSpanFull(),
])
->columns(2),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('destination_url')
->copyable()
->copyableState(fn (string $state): string => "URL: {$state}")
->limit(100)
->color('primary')
->tooltip(function (Tables\Columns\TextColumn $column): ?string {
$state = $column->getState();
if (strlen($state) <= $column->getCharacterLimit()) {
return null;
}

return $state;
})
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('default_short_url')
->copyable()
->color('primary')
->copyableState(fn (string $state): string => "URL: {$state}")
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('visits_count')
->label('Visits')
->badge()
->color('gray')
->sortable()
->summarize(Sum::make()->label('Total Visits'))
->counts('visits'),
Tables\Columns\TextColumn::make('activated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deactivated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\Filter::make('published_at')
->form([
Forms\Components\DatePicker::make('activated_at'),
Forms\Components\DatePicker::make('deactivated_at'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['activated_at'] ?? null,
fn (Builder $query, $date): Builder => $query->whereDate('activated_at', '>=', $date),
)
->when(
$data['deactivated_at'] ?? null,
fn (Builder $query, $date): Builder => $query->whereDate('deactivated_at', '<=', $date),
);
})
->indicateUsing(function (array $data): array {
$indicators = [];
if ($data['deactivated_at'] ?? null) {
$indicators['deactivated_at'] = 'Activated from '.Carbon::parse($data['published_from'])->toFormattedDateString();
}
if ($data['deactivated_at'] ?? null) {
$indicators['deactivated_at'] = 'Deactivated until '.Carbon::parse($data['deactivated_at'])->toFormattedDateString();
}

return $indicators;
}),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
]);
// ->groupedBulkActions([
// Tables\Actions\DeleteBulkAction::make()
// ->action(function () {
// Notification::make()
// ->title('Now, now, don\'t be cheeky, leave some records for others to play with!')
// ->warning()
// ->send();
// }),
// ]);
}

public static function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
Components\Section::make()
->schema([
Components\Split::make([
Components\Grid::make(3)
->schema([
Components\Group::make([
Components\Group::make([
Components\TextEntry::make('destination_url')
->copyable()
->color('primary'),
Components\TextEntry::make('default_short_url')
->copyable()
->color('primary'),
]),
]),
Components\Group::make([
Components\Group::make([
Components\TextEntry::make('activated_at'),
Components\TextEntry::make('deactivated_at'),
]),
]),
Components\Group::make([
Components\Group::make([
Components\TextEntry::make('created_at'),
Components\TextEntry::make('updated_at'),
]),
]),
]),
])
->from('lg'),
]),
Components\Section::make()
->schema([
Components\Group::make([
Components\IconEntry::make('single_use'),
Components\IconEntry::make('forward_query_params'),
Components\IconEntry::make('track_ip_address'),
Components\IconEntry::make('track_operating_system'),
Components\IconEntry::make('track_operating_system_version'),
Components\IconEntry::make('track_browser'),
Components\IconEntry::make('track_browser_version'),
Components\IconEntry::make('track_referer_url'),
Components\IconEntry::make('track_device_type'),
])->columns(5),
]),
]);
}

public static function getRelations(): array
{
return [];
}

public static function getWidgets(): array
{
return [
ShortUrlStats::class,
];
}

public static function getRecordSubNavigation(Page $page): array
{
return $page->generateNavigationItems([
Pages\ViewShortUrl::class,
Pages\EditShortUrl::class,
Pages\ListShortUrlVisits::class,
]);
}

public static function getPages(): array
{
return [
'index' => Pages\ListShortUrls::route('/'),
'create' => Pages\CreateShortUrl::route('/create'),
'view' => Pages\ViewShortUrl::route('/{record}'),
'edit' => Pages\EditShortUrl::route('/{record}/edit'),
'visits' => Pages\ListShortUrlVisits::route('/{record}/visits'),
];
}
}
34 changes: 34 additions & 0 deletions src/Filament/Resources/ShortUrlResource/Pages/CreateShortUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace A21ns1g4ts\FilamentShortUrl\Filament\Resources\ShortUrlResource\Pages;

use A21ns1g4ts\FilamentShortUrl\Filament\Resources\ShortUrlResource;
use AshAllenDesign\ShortURL\Classes\Builder;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

class CreateShortUrl extends CreateRecord
{
protected static string $resource = ShortUrlResource::class;

protected function handleRecordCreation(array $data): Model
{
$shortUrl = app(Builder::class)->destinationUrl($data['destination_url'])
->when($data['activated_at'], fn (Builder $builder) => $builder->activateAt(Carbon::parse($data['activated_at'])))
->when($data['deactivated_at'], fn (Builder $builder) => $builder->deactivateAt(Carbon::parse($data['deactivated_at'])))
->make();

return $shortUrl;
}

protected function getHeaderActions(): array
{
return [
Actions\Action::make('index')
->label('List')
->url(ListShortUrls::getUrl()),
];
}
}
Loading

0 comments on commit 911b05c

Please sign in to comment.