Skip to content

Commit

Permalink
Merge pull request #1 from TappNetwork/add_table_column_and_filter
Browse files Browse the repository at this point in the history
Add table column and filter
  • Loading branch information
andreia authored May 8, 2022
2 parents a314053 + 483b087 commit bf2e67b
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 71 deletions.
48 changes: 46 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ composer require tapp/filament-timezone-field

## Usage

### Form Field

Add to your Filament resource:

```php
Expand All @@ -26,11 +28,11 @@ public static function form(Form $form): Form
}
```

### Appareance
#### Appareance

![Filament Timezone Field](https://raw.githubusercontent.com/TappNetwork/filament-timezone-field/main/docs/filament-timezone-field.png)

### Options
#### Options

To use GMT instead of UTC (default is UTC), add the `->timezoneType('GMT')` method:

Expand Down Expand Up @@ -66,3 +68,45 @@ public static function form(Form $form): Form
]);
}
```

### Table Column

```php
use Tapp\FilamentTimezoneField\Tables\Columns\TimezoneColumn;

public static function table(Table $table): Table
{
return $table
->columns([
//...
TimezoneColumn::make('timezone')
->timezoneType('GMT')
->formattedOffsetAndTimezone(),
])
// ...
}
```

#### Options

| Method | Description |
| --- | --- |
| ->formattedTimezone() | Show formatted timezone name |
| ->formattedOffsetAndTimezone() | Show formatted offset and timezone name |
| ->timezoneType('GMT') | Use GMT instead of UTC |

### Table Filter

```php
use Tapp\FilamentTimezoneField\Tables\Filters\TimezoneSelectFilter;

public static function table(Table $table): Table
{
return $table
//...
->filters([
TimezoneSelectFilter::make('timezone'),
// ...
])
}
```
38 changes: 38 additions & 0 deletions src/Concerns/CanFormatTimezone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Tapp\FilamentTimezoneField\Concerns;

use DateTime;
use DateTimeZone;

trait CanFormatTimezone
{
protected function getFormattedOffset(string $offset): string
{
$hours = intval($offset / 3600);
$minutes = abs(intval($offset % 3600 / 60));

return $this->getTimezoneType().($offset ? sprintf('%+03d:%02d', $hours, $minutes) : '');
}

protected function getFormattedTimezoneName(string $name): string
{
return str_replace(
['/', '_', 'St '],
[', ', ' ', 'St. '],
$name
);
}

protected function getFormattedOffsetAndTimezone(string $offset, string $timezone): string
{
return sprintf('(%s) %s', $this->getFormattedOffset($offset), $this->getFormattedTimezoneName($timezone));
}

public function getOffset(string $timezone): string
{
$now = new DateTime('now', new DateTimeZone($this->getTimezoneType()));

return $now->setTimezone(new DateTimeZone($timezone))->getOffset();
}
}
37 changes: 37 additions & 0 deletions src/Concerns/HasTimezoneOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Tapp\FilamentTimezoneField\Concerns;

use DateTime;
use DateTimeZone;

trait HasTimezoneOptions
{
public function getOptions(): array
{
$options = $this->getTimezones();

$this->options = $options;

return $this->options;
}

public function getTimezones(): array
{
$timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL);

$data = [];

$now = new DateTime('now', new DateTimeZone($this->getTimezoneType()));

foreach ($timezones as $timezone) {
$offsets[] = $offset = $now->setTimezone(new DateTimeZone($timezone))->getOffset();

$data[$timezone] = $this->getFormattedOffsetAndTimezone($offset, $timezone);
}

array_multisort($offsets, $data);

return $data;
}
}
29 changes: 29 additions & 0 deletions src/Concerns/HasTimezoneType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Tapp\FilamentTimezoneField\Concerns;

trait HasTimezoneType
{
protected string | null $timezoneType = null;

protected array $allowedTimezoneTypes = [
'UTC',
'GMT',
];

public function timezoneType(string | null $type): static
{
$this->timezoneType = strtoupper($type);

return $this;
}

public function getTimezoneType(): string
{
if ($this->timezoneType === null && !in_array($this->timezoneType, $this->allowedTimezoneTypes)) {
$this->timezoneType = 'UTC';
}

return $this->timezoneType;
}
}
76 changes: 7 additions & 69 deletions src/Forms/Components/TimezoneSelect.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,16 @@

namespace Tapp\FilamentTimezoneField\Forms\Components;

use DateTimeZone;
use Filament\Forms\Components\Select;
use Tapp\FilamentTimezoneField\Concerns\CanFormatTimezone;
use Tapp\FilamentTimezoneField\Concerns\HasTimezoneOptions;
use Tapp\FilamentTimezoneField\Concerns\HasTimezoneType;

class TimezoneSelect extends Select
{
protected string $view = 'forms::components.select';

protected string | null $timezoneType = null;

protected array $allowedTimezoneTypes = [
'UTC',
'GMT',
];

public function getOptions(): array
{
$options = $this->getTimezones();

$this->options = $options;

return $this->options;
}

public function timezoneType(string | null $type): static
{
$this->timezoneType = strtoupper($type);

return $this;
}

public function getTimezoneType(): string
{
if ($this->timezoneType === null && !in_array($this->timezoneType, $this->allowedTimezoneTypes)) {
$this->timezoneType = 'UTC';
}

return $this->timezoneType;
}
use CanFormatTimezone;
use HasTimezoneOptions;
use HasTimezoneType;

public function getTimezones(): array
{
$timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL);

$data = [];

$now = new \DateTime('now', new DateTimeZone($this->getTimezoneType()));

foreach ($timezones as $timezone) {
$offsets[] = $offset = $now->setTimezone(new DateTimeZone($timezone))->getOffset();

$data[$timezone] = sprintf('(%s) %s', $this->getFormattedOffset($offset), $this->getFormattedTimezoneName($timezone));
}

array_multisort($offsets, $data);

return $data;
}

protected function getFormattedOffset(string $offset): string
{
$hours = intval($offset / 3600);
$minutes = abs(intval($offset % 3600 / 60));

return $this->getTimezoneType().($offset ? sprintf('%+03d:%02d', $hours, $minutes) : '');
}

protected function getFormattedTimezoneName(string $name): string
{
return str_replace(
['/', '_', 'St '],
[', ', ' ', 'St. '],
$name
);
}
protected string $view = 'forms::components.select';
}
34 changes: 34 additions & 0 deletions src/Tables/Columns/TimezoneColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Tapp\FilamentTimezoneField\Tables\Columns;

use Filament\Tables\Columns\Column;
use Filament\Tables\Columns\TextColumn;
use Tapp\FilamentTimezoneField\Concerns\CanFormatTimezone;
use Tapp\FilamentTimezoneField\Concerns\HasTimezoneType;

class TimezoneColumn extends TextColumn
{
use CanFormatTimezone;
use HasTimezoneType;

public function formattedTimezone(): static
{
$this->defaultState = $this->formatStateUsing(static function (Column $column, $state): ?string {
return $column->getFormattedTimezoneName($state);
});

return $this;
}

public function formattedOffsetAndTimezone(): static
{
$this->defaultState = $this->formatStateUsing(static function (Column $column, $state): ?string {
$offset = $column->getOffset($state);

return $column->getFormattedOffsetAndTimezone($offset, $state);
});

return $this;
}
}
15 changes: 15 additions & 0 deletions src/Tables/Filters/TimezoneSelectFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Tapp\FilamentTimezoneField\Tables\Filters;

use Filament\Tables\Filters\SelectFilter;
use Tapp\FilamentTimezoneField\Concerns\CanFormatTimezone;
use Tapp\FilamentTimezoneField\Concerns\HasTimezoneOptions;
use Tapp\FilamentTimezoneField\Concerns\HasTimezoneType;

class TimezoneSelectFilter extends SelectFilter
{
use CanFormatTimezone;
use HasTimezoneOptions;
use HasTimezoneType;
}

0 comments on commit bf2e67b

Please sign in to comment.