Only offer pinned tags as the default tag

The default_tag dropdown was populated from every tag (type=1), but the
dashboard taglist only renders pinned tags. Selecting an unpinned tag as the
default therefore triggered a click on a taglist entry that does not exist,
silently doing nothing. Filter the option queries in both Setting accessors to
pinned tags so only selectable tags are offered, and assert an unpinned tag is
excluded.

Also drop the unused $data['default_tag'] assignment in ItemController: the
taglist partial reads the setting directly via Setting::fetch(), so the view
variable was never consumed.
This commit is contained in:
KodeStar
2026-07-08 18:26:19 +01:00
parent c0c202c5ff
commit ad9baffa62
3 changed files with 17 additions and 4 deletions
-1
View File
@@ -40,7 +40,6 @@ class ItemController extends Controller
$treat_tags_as = \App\Setting::fetch('treat_tags_as'); $treat_tags_as = \App\Setting::fetch('treat_tags_as');
$data["treat_tags_as"] = $treat_tags_as; $data["treat_tags_as"] = $treat_tags_as;
$data['default_tag'] = \App\Setting::fetch('default_tag');
if (config('app.auth_roles_enable')) { if (config('app.auth_roles_enable')) {
$roles = explode(config('app.auth_roles_delimiter'), $request->header(config('app.auth_roles_header'))); $roles = explode(config('app.auth_roles_delimiter'), $request->header(config('app.auth_roles_header')));
+2 -2
View File
@@ -125,7 +125,7 @@ class Setting extends Model
$options = Search::providers()->pluck('name', 'id')->toArray(); $options = Search::providers()->pluck('name', 'id')->toArray();
} elseif ($this->key === 'default_tag') { } elseif ($this->key === 'default_tag') {
$options = []; $options = [];
$tags = Item::where('type', 1)->where('id', '>', 0)->orderBy('title', 'asc')->get(); $tags = Item::where('type', 1)->where('id', '>', 0)->pinned()->orderBy('title', 'asc')->get();
foreach ($tags as $tag) { foreach ($tags as $tag) {
$options[$tag->tag_url] = $tag->title; $options[$tag->tag_url] = $tag->title;
} }
@@ -198,7 +198,7 @@ class Setting extends Model
$options = Search::providers()->pluck('name', 'id'); $options = Search::providers()->pluck('name', 'id');
} elseif ($this->key === 'default_tag') { } elseif ($this->key === 'default_tag') {
$options = ['' => 'app.options.none']; $options = ['' => 'app.options.none'];
$tags = Item::where('type', 1)->where('id', '>', 0)->orderBy('title', 'asc')->get(); $tags = Item::where('type', 1)->where('id', '>', 0)->pinned()->orderBy('title', 'asc')->get();
foreach ($tags as $tag) { foreach ($tags as $tag) {
$options[$tag->tag_url] = $tag->title; $options[$tag->tag_url] = $tag->title;
} }
@@ -43,12 +43,23 @@ class SettingsSeederTest extends TestCase
'title' => 'Home', 'title' => 'Home',
'url' => 'home-dashboard', 'url' => 'home-dashboard',
'type' => 1, 'type' => 1,
'pinned' => 1,
'user_id' => 0, 'user_id' => 0,
]); ]);
Item::factory()->create([ Item::factory()->create([
'title' => 'Media', 'title' => 'Media',
'url' => 'media', 'url' => 'media',
'type' => 1, 'type' => 1,
'pinned' => 1,
'user_id' => 0,
]);
// An unpinned tag is not rendered in the dashboard taglist, so it must
// not be offered as a default (selecting it would silently do nothing).
Item::factory()->create([
'title' => 'Archive',
'url' => 'archive',
'type' => 1,
'pinned' => 0,
'user_id' => 0, 'user_id' => 0,
]); ]);
@@ -59,10 +70,13 @@ class SettingsSeederTest extends TestCase
$this->assertStringContainsString('<option value="" ', $editValue); $this->assertStringContainsString('<option value="" ', $editValue);
$this->assertStringContainsString(__('app.options.none'), $editValue); $this->assertStringContainsString(__('app.options.none'), $editValue);
// One option per tag: the slug as the value, the raw title as the label. // One option per pinned tag: the slug as the value, the raw title as the label.
$this->assertStringContainsString('value="home-dashboard"', $editValue); $this->assertStringContainsString('value="home-dashboard"', $editValue);
$this->assertStringContainsString('>Home</option>', $editValue); $this->assertStringContainsString('>Home</option>', $editValue);
$this->assertStringContainsString('value="media"', $editValue); $this->assertStringContainsString('value="media"', $editValue);
$this->assertStringContainsString('>Media</option>', $editValue); $this->assertStringContainsString('>Media</option>', $editValue);
// The unpinned tag is excluded.
$this->assertStringNotContainsString('value="archive"', $editValue);
} }
} }