Skip to content

Commit e294e9d

Browse files
authored
Merge pull request #99 from govigilant/feature/notification-channel-name
Allow naming of notification channels
2 parents e705b2e + d2f46cd commit e294e9d

File tree

8 files changed

+127
-8
lines changed

8 files changed

+127
-8
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
public function up(): void
10+
{
11+
Schema::table('notification_channels', function (Blueprint $table): void {
12+
$table->string('name')->nullable()->after('channel');
13+
});
14+
}
15+
16+
public function down(): void
17+
{
18+
Schema::table('notification_channels', function (Blueprint $table): void {
19+
$table->dropColumn('name');
20+
});
21+
}
22+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Eloquent\Model;
4+
use Illuminate\Database\Migrations\Migration;
5+
use Vigilant\Notifications\Channels\NotificationChannel;
6+
use Vigilant\Notifications\Models\Channel;
7+
8+
return new class extends Migration
9+
{
10+
public function up(): void
11+
{
12+
Model::unguarded(function (): void {
13+
Channel::withoutEvents(function (): void {
14+
Channel::withoutGlobalScopes()
15+
->whereNull('name')
16+
->chunkById(100, function ($channels): void {
17+
/** @var \Illuminate\Support\Collection<int, Channel> $channels */
18+
$channels->each(function (Channel $channel): void {
19+
$channelType = $channel->channel;
20+
21+
if (! is_string($channelType) || ! class_exists($channelType) || ! is_subclass_of($channelType, NotificationChannel::class)) {
22+
return;
23+
}
24+
25+
$channel->forceFill(['name' => $channelType::$name])->save();
26+
});
27+
});
28+
});
29+
});
30+
}
31+
};

packages/notifications/resources/views/livewire/channels/form.blade.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div>
22
@if (!$inline)
33
<x-slot name="header">
4-
<x-page-header :title="$updating ? 'Edit Channel - ' . $channelModel->channel::$name : 'Add Channel'" :back="route('notifications.channels')">
4+
<x-page-header :title="$updating ? 'Edit Channel - ' . $channelModel->title() : 'Add Channel'" :back="route('notifications.channels')">
55
@if($updating)
66
<x-frontend::page-header.actions>
77
<x-form.button class="bg-red" @click="$dispatch('open-delete-modal')">
@@ -35,6 +35,10 @@
3535
@endforeach
3636
</x-form.select>
3737

38+
<x-form.text field="form.name" name="Internal Name"
39+
description="Give this channel a recognizable label for your team.">
40+
</x-form.text>
41+
3842
<h3 class="text-lg font-bold leading-7 sm:truncate sm:text-2xl sm:tracking-tight text-neutral-100">
3943
{{ __('Configuration') }}</h3>
4044

@@ -72,7 +76,7 @@
7276
</div>
7377
<div class="flex-1">
7478
<p class="text-sm text-base-300">
75-
<span class="font-semibold text-base-100">{{ $channelModel->channel::$name }}</span>
79+
<span class="font-semibold text-base-100">{{ $channelModel->title() }}</span>
7680
</p>
7781
<p class="text-sm text-base-400 mt-1">
7882
@lang('This action cannot be undone. All channel settings will be permanently deleted and notifications will no longer be sent to this channel.')

packages/notifications/src/Http/Livewire/ChannelForm.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,13 @@ public function save(bool $redirect = true): void
7474

7575
$this->validate();
7676

77+
$data = $this->form->all();
78+
$data['name'] = blank($data['name'] ?? null) ? null : $data['name'];
79+
7780
if ($this->channelModel->exists) {
78-
$this->channelModel->update($this->form->all());
81+
$this->channelModel->update($data);
7982
} else {
80-
$this->channelModel = Channel::query()->create(
81-
$this->form->all()
82-
);
83+
$this->channelModel = Channel::query()->create($data);
8384
}
8485

8586
if ($this->inline) {

packages/notifications/src/Http/Livewire/Forms/CreateChannelForm.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@ class CreateChannelForm extends Form
1010
#[Validate('required|max:255')]
1111
public string $channel = '';
1212

13+
#[Validate('nullable|string|max:255')]
14+
public ?string $name = null;
15+
1316
public array $settings = [];
1417
}

packages/notifications/src/Http/Livewire/Tables/ChannelTable.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ class ChannelTable extends BaseTable
2121
protected function columns(): array
2222
{
2323
return [
24-
Column::make(__('Channel'), 'channel')
24+
Column::make(__('Name'), 'name')
25+
->displayUsing(function (?string $name, Channel $channel): string {
26+
return $channel->title();
27+
}),
28+
29+
Column::make(__('Channel Type'), 'channel')
2530
->displayUsing(function (string $channel) {
2631
/** @var class-string<NotificationChannel> $channel */
2732

packages/notifications/src/Models/Channel.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
use Illuminate\Database\Eloquent\Relations\HasMany;
1010
use Illuminate\Support\Carbon;
1111
use Vigilant\Core\Scopes\TeamScope;
12+
use Vigilant\Notifications\Channels\NotificationChannel;
1213
use Vigilant\Notifications\Observers\ChannelObserver;
1314

1415
/**
1516
* @property int $id
1617
* @property int $team_id
1718
* @property string $channel
19+
* @property string|null $name
1820
* @property array $settings
1921
* @property ?Carbon $created_at
2022
* @property ?Carbon $updated_at
@@ -34,7 +36,18 @@ class Channel extends Model
3436

3537
public function title(): string
3638
{
37-
return $this->channel::$name;
39+
if (filled($this->name)) {
40+
return $this->name;
41+
}
42+
43+
if (is_string($this->channel) && class_exists($this->channel) && is_subclass_of($this->channel, NotificationChannel::class)) {
44+
/** @var class-string<NotificationChannel> $channel */
45+
$channel = $this->channel;
46+
47+
return $channel::$name;
48+
}
49+
50+
return (string) $this->channel;
3851
}
3952

4053
public function history(): HasMany
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Vigilant\Notifications\Tests\Models;
4+
5+
use PHPUnit\Framework\Attributes\Test;
6+
use Vigilant\Notifications\Channels\SlackChannel;
7+
use Vigilant\Notifications\Models\Channel;
8+
use Vigilant\Notifications\Tests\TestCase;
9+
10+
class ChannelTest extends TestCase
11+
{
12+
#[Test]
13+
public function it_returns_the_internal_name_when_available(): void
14+
{
15+
$channel = Channel::withoutEvents(function () {
16+
return Channel::query()->withoutGlobalScopes()->create([
17+
'team_id' => 1,
18+
'channel' => SlackChannel::class,
19+
'name' => 'Primary Slack',
20+
'settings' => [],
21+
]);
22+
});
23+
24+
$this->assertSame('Primary Slack', $channel->title());
25+
}
26+
27+
#[Test]
28+
public function it_falls_back_to_the_channel_display_name(): void
29+
{
30+
$channel = Channel::withoutEvents(function () {
31+
return Channel::query()->withoutGlobalScopes()->create([
32+
'team_id' => 1,
33+
'channel' => SlackChannel::class,
34+
'settings' => [],
35+
]);
36+
});
37+
38+
$this->assertSame(SlackChannel::$name, $channel->title());
39+
}
40+
}

0 commit comments

Comments
 (0)