diff --git a/src/Panel/Ui/Buttons/LanguagesButton.php b/src/Panel/Ui/Buttons/LanguagesButton.php new file mode 100644 index 0000000000..b077ce3d24 --- /dev/null +++ b/src/Panel/Ui/Buttons/LanguagesButton.php @@ -0,0 +1,79 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + * @since 5.0.0 + * @internal + */ +class LanguagesButton extends ViewButton +{ + protected App $kirby; + + public function __construct( + ) { + $this->kirby = App::instance(); + + parent::__construct( + component: 'k-view-languages-button', + class: 'k-view-languages-button', + icon: 'translate', + options: $this->options(), + responsive: 'text', + text: Str::upper($this->kirby->language()?->code()) + ); + } + + public function option(Language $language): array + { + return [ + 'text' => $language->name(), + 'code' => $language->code(), + 'current' => $language->code() === $this->kirby->language()?->code(), + ]; + } + + public function options(): array + { + $languages = $this->kirby->languages(); + $options = []; + + if ($this->kirby->multilang() === false) { + return $options; + } + + // add the primary/default language first + if ($default = $languages->default()) { + $options[] = $this->option($default); + $options[] = '-'; + $languages = $languages->not($default); + } + + // add all secondary languages after the separator + foreach ($languages as $language) { + $options[] = $this->option($language); + } + + return $options; + } + + public function render(): array|null + { + if ($this->kirby->multilang() === false) { + return null; + } + + return parent::render(); + } +} diff --git a/src/Panel/Ui/Buttons/PageStatusButton.php b/src/Panel/Ui/Buttons/PageStatusButton.php new file mode 100644 index 0000000000..e0a9690b09 --- /dev/null +++ b/src/Panel/Ui/Buttons/PageStatusButton.php @@ -0,0 +1,48 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + * @since 5.0.0 + * @internal + */ +class PageStatusButton extends ViewButton +{ + public function __construct( + Page $page + ) { + $status = $page->status(); + $blueprint = $page->blueprint()->status()[$status] ?? null; + $disabled = $page->permissions()->cannot('changeStatus'); + $title = I18n::translate('page.status') . ': ' . I18n::translate('page.status.' . $status); + + if ($disabled === true) { + $title .= ' (' . I18n::translate('disabled') . ')'; + } + + parent::__construct( + class: 'k-view-status-button k-page-status-button', + dialog: $page->panel()->url(true) . '/changeStatus', + disabled: $disabled, + icon: 'status-' . $status, + style: '--icon-size: 15px', + text: $blueprint['label'] ?? $status, + title: $title, + theme: match($status) { + 'draft' => 'negative-icon', + 'unlisted' => 'info-icon', + 'listed' => 'positive-icon' + } + ); + } +} diff --git a/src/Panel/Ui/Buttons/PreviewButton.php b/src/Panel/Ui/Buttons/PreviewButton.php new file mode 100644 index 0000000000..a858a64043 --- /dev/null +++ b/src/Panel/Ui/Buttons/PreviewButton.php @@ -0,0 +1,31 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + * @since 5.0.0 + * @internal + */ +class PreviewButton extends ViewButton +{ + public function __construct( + public string|null $link + ) { + parent::__construct( + class: 'k-view-preview-button', + icon: 'open', + link: $link, + target: '_blank', + title: I18n::translate('open') + ); + } +} diff --git a/src/Panel/Ui/Buttons/SettingsButton.php b/src/Panel/Ui/Buttons/SettingsButton.php new file mode 100644 index 0000000000..ba89c520bc --- /dev/null +++ b/src/Panel/Ui/Buttons/SettingsButton.php @@ -0,0 +1,32 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + * @since 5.0.0 + * @internal + */ +class SettingsButton extends ViewButton +{ + public function __construct( + ModelWithContent $model + ) { + parent::__construct( + component: 'k-view-settings-button', + class: 'k-view-settings-button', + icon: 'cog', + options: $model->panel()->url(true), + title: I18n::translate('settings'), + ); + } +} diff --git a/tests/Panel/Ui/Buttons/LanguagesButtonTest.php b/tests/Panel/Ui/Buttons/LanguagesButtonTest.php new file mode 100644 index 0000000000..914c428052 --- /dev/null +++ b/tests/Panel/Ui/Buttons/LanguagesButtonTest.php @@ -0,0 +1,93 @@ + 'Deutsch', 'code' => 'de']); + $button = new LanguagesButton(); + $this->assertSame([ + 'text' => 'Deutsch', + 'code' => 'de', + 'current' => false + ], $button->option($language)); + } + + /** + * @covers ::options + */ + public function testOptionsSingleLang() + { + $button = new LanguagesButton(); + $this->assertSame([], $button->options()); + } + + /** + * @covers ::options + */ + public function testOptionsMultiLang() + { + $this->enableMultilang(); + $this->installLanguages(); + + $button = new LanguagesButton(); + $this->assertSame([ + [ + 'text' => 'English', + 'code' => 'en', + 'current' => true + ], + '-', + [ + 'text' => 'Deutsch', + 'code' => 'de', + 'current' => false + ] + ], $button->options()); + } + + /** + * @covers ::render + */ + public function testRenderSingleLang() + { + $button = new LanguagesButton(); + $this->assertNull($button->render()); + } + + /** + * @covers ::props + * @covers ::render + */ + public function testRenderMultiLang() + { + $this->enableMultilang(); + $this->installLanguages(); + + $button = new LanguagesButton(); + $this->assertSame('k-view-languages-button', $button->component); + $this->assertSame('k-view-languages-button', $button->class); + $this->assertSame('translate', $button->icon); + $this->assertCount(3, $button->options); + $this->assertSame('text', $button->responsive); + $this->assertSame('EN', $button->text); + + $render = $button->render(); + $this->assertIsArray($render); + $this->assertSame('k-view-languages-button', $render['component']); + $this->assertIsArray($render['props']); + $this->assertIsArray($render['props']['options']); + } +} diff --git a/tests/Panel/Ui/Buttons/PageStatusButtonTest.php b/tests/Panel/Ui/Buttons/PageStatusButtonTest.php new file mode 100644 index 0000000000..eb19839a8d --- /dev/null +++ b/tests/Panel/Ui/Buttons/PageStatusButtonTest.php @@ -0,0 +1,50 @@ + 'test', 'isDraft' => true]); + $button = new PageStatusButton($page); + + $this->assertSame('k-view-button', $button->component); + $this->assertSame('k-view-status-button k-page-status-button', $button->class); + $this->assertSame('/pages/test/changeStatus', $button->dialog); + $this->assertTrue($button->disabled); + $this->assertSame('status-draft', $button->icon); + $this->assertTrue($button->responsive); + $this->assertSame('Draft', $button->text); + $this->assertSame('Status: Draft (Disabled)', $button->title); + $this->assertSame('negative-icon', $button->theme); + } + + /** + * @covers ::__construct + */ + public function testButtonUnlisted() + { + App::instance()->impersonate('kirby'); + $page = new Page(['slug' => 'test']); + $button = new PageStatusButton($page); + + $this->assertFalse($button->disabled); + $this->assertSame('status-unlisted', $button->icon); + $this->assertTrue($button->responsive); + $this->assertSame('Unlisted', $button->text); + $this->assertSame('Status: Unlisted', $button->title); + $this->assertSame('info-icon', $button->theme); + } +} diff --git a/tests/Panel/Ui/Buttons/PreviewButtonTest.php b/tests/Panel/Ui/Buttons/PreviewButtonTest.php new file mode 100644 index 0000000000..7bda57585e --- /dev/null +++ b/tests/Panel/Ui/Buttons/PreviewButtonTest.php @@ -0,0 +1,27 @@ +assertSame('k-view-button', $button->component); + $this->assertSame('k-view-preview-button', $button->class); + $this->assertSame('open', $button->icon); + $this->assertSame('https://getkirby.com', $button->link); + $this->assertSame('_blank', $button->target); + $this->assertSame('Open', $button->title); + } + +} diff --git a/tests/Panel/Ui/Buttons/SettingsButtonTest.php b/tests/Panel/Ui/Buttons/SettingsButtonTest.php new file mode 100644 index 0000000000..e1370be185 --- /dev/null +++ b/tests/Panel/Ui/Buttons/SettingsButtonTest.php @@ -0,0 +1,27 @@ + 'test']); + $button = new SettingsButton(model: $page); + + $this->assertSame('k-view-settings-button', $button->component); + $this->assertSame('k-view-settings-button', $button->class); + $this->assertSame('cog', $button->icon); + $this->assertSame('/pages/test', $button->options); + $this->assertSame('Settings', $button->title); + } +}