diff --git a/db/migrations/2020_12_26_000000_news_add_is_pinned.php b/db/migrations/2020_12_26_000000_news_add_is_pinned.php new file mode 100644 index 00000000..8c8c9f5e --- /dev/null +++ b/db/migrations/2020_12_26_000000_news_add_is_pinned.php @@ -0,0 +1,37 @@ +schema->table( + 'news', + function (Blueprint $table) { + $table->boolean('is_pinned')->default(false)->after('is_meeting'); + } + ); + } + + /** + * Reverse the migration + */ + public function down() + { + $this->schema->table( + 'news', + function (Blueprint $table) { + $table->dropColumn('is_pinned'); + } + ); + } +} diff --git a/resources/lang/de_DE/default.po b/resources/lang/de_DE/default.po index 40fcf1f0..87461bed 100644 --- a/resources/lang/de_DE/default.po +++ b/resources/lang/de_DE/default.po @@ -2885,6 +2885,9 @@ msgstr "Betreff" msgid "news.edit.is_meeting" msgstr "Treffen" +msgid "news.edit.is_pinned" +msgstr "Oben anpinnen" + msgid "news.edit.message" msgstr "Nachricht" diff --git a/resources/lang/en_US/default.po b/resources/lang/en_US/default.po index c5b7c777..b63f882a 100644 --- a/resources/lang/en_US/default.po +++ b/resources/lang/en_US/default.po @@ -171,6 +171,9 @@ msgstr "Subject" msgid "news.edit.is_meeting" msgstr "Meeting" +msgid "news.edit.is_pinned" +msgstr "Pin to top" + msgid "news.edit.message" msgstr "Message" diff --git a/resources/views/pages/news/edit.twig b/resources/views/pages/news/edit.twig index 777d1d39..0e10b883 100644 --- a/resources/views/pages/news/edit.twig +++ b/resources/views/pages/news/edit.twig @@ -42,6 +42,7 @@
{{ f.checkbox('is_meeting', __('news.edit.is_meeting'), is_meeting) }} + {{ f.checkbox('is_pinned', __('news.edit.is_pinned'), is_pinned) }}
diff --git a/resources/views/pages/news/overview.twig b/resources/views/pages/news/overview.twig index 3822f81d..b3198427 100644 --- a/resources/views/pages/news/overview.twig +++ b/resources/views/pages/news/overview.twig @@ -53,6 +53,7 @@

+ {% if news.is_pinned %}{{ m.glyphicon('pushpin') }}{% endif %} {% if news.is_meeting %}{{ __('news.is_meeting') }}{% endif %} {{ news.title }} diff --git a/src/Controllers/Admin/NewsController.php b/src/Controllers/Admin/NewsController.php index b7f36940..a1b0e11c 100644 --- a/src/Controllers/Admin/NewsController.php +++ b/src/Controllers/Admin/NewsController.php @@ -96,7 +96,8 @@ class NewsController extends BaseController 'pages/news/edit.twig', [ 'news' => $news, - 'is_meeting' => $news ? $news->is_meeting : $isMeetingDefault + 'is_meeting' => $news ? $news->is_meeting : $isMeetingDefault, + 'is_pinned' => $news ? $news->is_pinned : false, ] + $this->getNotifications(), ); } @@ -116,6 +117,7 @@ class NewsController extends BaseController 'title' => 'required', 'text' => 'required', 'is_meeting' => 'optional|checked', + 'is_pinned' => 'optional|checked', 'delete' => 'optional|checked', 'preview' => 'optional|checked', ]); @@ -146,6 +148,7 @@ class NewsController extends BaseController $news->title = $data['title']; $news->text = $data['text']; $news->is_meeting = !is_null($data['is_meeting']); + $news->is_pinned = !is_null($data['is_pinned']); if (!is_null($data['preview'])) { return $this->showEdit($news); @@ -154,11 +157,12 @@ class NewsController extends BaseController $news->save(); $this->log->info( - 'Updated {type} "{news}": {text}', + 'Updated {pinned}{type} "{news}": {text}', [ - 'type' => $news->is_meeting ? 'meeting' : 'news', - 'news' => $news->title, - 'text' => $news->text, + 'pinned' => $news->is_pinned ? 'pinned ' : '', + 'type' => $news->is_meeting ? 'meeting' : 'news', + 'news' => $news->title, + 'text' => $news->text, ] ); diff --git a/src/Controllers/NewsController.php b/src/Controllers/NewsController.php index 4d0b6cb8..2d9b540d 100644 --- a/src/Controllers/NewsController.php +++ b/src/Controllers/NewsController.php @@ -149,6 +149,7 @@ class NewsController extends BaseController $news = $query ->with('user') ->withCount('comments') + ->orderByDesc('is_pinned') ->orderByDesc('updated_at') ->limit($perPage) ->offset(($page - 1) * $perPage) diff --git a/src/Models/News.php b/src/Models/News.php index 19a3208c..4de04cd0 100644 --- a/src/Models/News.php +++ b/src/Models/News.php @@ -15,6 +15,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder; * @property string $title * @property string $text * @property bool $is_meeting + * @property bool $is_pinned * @property Carbon|null $created_at * @property Carbon|null $updated_at * @@ -25,6 +26,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder; * @method static QueryBuilder|LogEntry[] whereTitle($value) * @method static QueryBuilder|LogEntry[] whereText($value) * @method static QueryBuilder|LogEntry[] whereIsMeeting($value) + * @method static QueryBuilder|LogEntry[] whereIsPinned($value) * @method static QueryBuilder|LogEntry[] whereCreatedAt($value) * @method static QueryBuilder|LogEntry[] whereUpdatedAt($value) */ @@ -38,6 +40,7 @@ class News extends BaseModel /** @var array */ protected $casts = [ 'is_meeting' => 'boolean', + 'is_pinned' => 'boolean', ]; /** @var array */ @@ -45,6 +48,7 @@ class News extends BaseModel 'title', 'text', 'is_meeting', + 'is_pinned', 'user_id', ]; diff --git a/tests/Unit/Controllers/Admin/NewsControllerTest.php b/tests/Unit/Controllers/Admin/NewsControllerTest.php index 7edee5ae..8f443116 100644 --- a/tests/Unit/Controllers/Admin/NewsControllerTest.php +++ b/tests/Unit/Controllers/Admin/NewsControllerTest.php @@ -214,6 +214,7 @@ class NewsControllerTest extends ControllerTest 'title' => 'New title', 'text' => 'New text', 'is_meeting' => '1', + 'is_pinned' => '1', 'preview' => '1', ]); $this->response->expects($this->once()) @@ -225,6 +226,7 @@ class NewsControllerTest extends ControllerTest $news = $data['news']; // Contains new text $this->assertTrue($news->is_meeting); + $this->assertTrue($news->is_pinned); $this->assertEquals('New title', $news->title); $this->assertEquals('New text', $news->text); @@ -242,6 +244,7 @@ class NewsControllerTest extends ControllerTest $this->assertEquals('Foo', $news->title); $this->assertEquals('foo', $news->text); $this->assertFalse($news->is_meeting); + $this->assertFalse($news->is_pinned); } /** diff --git a/tests/Unit/Controllers/NewsControllerTest.php b/tests/Unit/Controllers/NewsControllerTest.php index 822d398b..e63abe50 100644 --- a/tests/Unit/Controllers/NewsControllerTest.php +++ b/tests/Unit/Controllers/NewsControllerTest.php @@ -44,12 +44,14 @@ class NewsControllerTest extends TestCase 'title' => 'Bar', 'text' => 'bar', 'is_meeting' => false, + 'is_pinned' => true, 'user_id' => 1, ], [ 'title' => 'baz', 'text' => 'baz', 'is_meeting' => true, + 'is_pinned' => true, 'user_id' => 1, ], [ @@ -62,6 +64,7 @@ class NewsControllerTest extends TestCase 'title' => 'Ipsum', 'text' => 'ipsum', 'is_meeting' => true, + 'is_pinned' => true, 'user_id' => 1, ], [ @@ -111,6 +114,8 @@ class NewsControllerTest extends TestCase $this->assertTrue($news->isNotEmpty()); $this->assertEquals(3, $data['pages']); $this->assertEquals(2, $data['page']); + $this->assertTrue($news[0]->is_pinned); + $this->assertEquals('Ipsum', $news[0]->title); break; case 2: // Show meetings diff --git a/tests/Unit/Models/NewsTest.php b/tests/Unit/Models/NewsTest.php index 40177560..d99a470e 100644 --- a/tests/Unit/Models/NewsTest.php +++ b/tests/Unit/Models/NewsTest.php @@ -78,7 +78,7 @@ class NewsTest extends ModelTest public function testCreate(): void { $news = (new News())->create( - $this->newsData + ['is_meeting' => true] + $this->newsData + ['is_meeting' => true, 'is_pinned' => true] ); $news = $news->find($news->id); @@ -86,5 +86,6 @@ class NewsTest extends ModelTest $this->assertSame($this->newsData['title'], $news->title); $this->assertSame($this->newsData['text'], $news->text); $this->assertTrue($news->is_meeting); + $this->assertTrue($news->is_pinned); } }