Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ public function getListValueAttribute()
$options = (array) json_decode($this->options);
if ($this->key === 'search_provider') {
$options = Search::providers()->pluck('name', 'id')->toArray();
} elseif ($this->key === 'default_tag') {
$options = [];
$tags = Item::where('type', 1)->where('id', '>', 0)->pinned()->orderBy('title', 'asc')->get();
foreach ($tags as $tag) {
$options[$tag->tag_url] = $tag->title;
}
}
$value = (array_key_exists($this->value, $options))
? __($options[$this->value])
Expand Down Expand Up @@ -190,6 +196,12 @@ public function getEditValueAttribute()
$options = json_decode($this->options);
if ($this->key === 'search_provider') {
$options = Search::providers()->pluck('name', 'id');
} elseif ($this->key === 'default_tag') {
$options = ['' => 'app.options.none'];
$tags = Item::where('type', 1)->where('id', '>', 0)->pinned()->orderBy('title', 'asc')->get();
foreach ($tags as $tag) {
$options[$tag->tag_url] = $tag->title;
}
}
$value = '<select name="value" class="form-control">';
foreach ($options as $key => $opt) {
Expand Down
15 changes: 15 additions & 0 deletions database/seeders/SettingsSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -349,5 +349,20 @@ public function run(): void
$setting->label = 'app.settings.treat_tags_as';
$setting->save();
}

if (! $setting = Setting::find(15)) {
$setting = new Setting;
$setting->id = 15;
$setting->group_id = 4;
$setting->key = 'default_tag';
$setting->type = 'select';
$setting->label = 'app.settings.default_tag';
$setting->value = '';
$setting->save();
} else {
$setting->group_id = 4;
$setting->label = 'app.settings.default_tag';
$setting->save();
}
}
}
1 change: 1 addition & 0 deletions lang/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
'settings.custom_css' => 'Custom CSS',
'settings.custom_js' => 'Custom JavaScript',
'settings.treat_tags_as' => 'Treat Tags As:',
'settings.default_tag' => 'Default tag',
'settings.folders' => 'Folders',
'settings.tags' => 'Tags',
'settings.categories' => 'Categories',
Expand Down
8 changes: 8 additions & 0 deletions public/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4287,6 +4287,14 @@ $.when($.ready).then(function () {
alert("Something went wrong: ".concat(responseData.responseText.substring(0, 100)));
});
});
// Auto-select the configured default tag on load (tags mode only)
var taglist = document.getElementById("taglist");
if (taglist !== null) {
var defaultTag = taglist.getAttribute("data-default-tag");
if (typeof defaultTag === "string" && defaultTag !== "") {
$("#taglist .tag[data-tag=\"tag-".concat(defaultTag, "\"]")).trigger("click");
}
}
$("#pinlist").on("click", "a", function (e) {
e.preventDefault();
var current = $(this);
Expand Down
9 changes: 9 additions & 0 deletions resources/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,15 @@ $.when($.ready).then(() => {
);
});
});
// Auto-select the configured default tag on load (tags mode only)
const taglist = document.getElementById("taglist");
if (taglist !== null) {
const defaultTag = taglist.getAttribute("data-default-tag");
if (typeof defaultTag === "string" && defaultTag !== "") {
$(`#taglist .tag[data-tag="tag-${defaultTag}"]`).trigger("click");
}
}

$("#pinlist").on("click", "a", function (e) {
e.preventDefault();
const current = $(this);
Expand Down
2 changes: 1 addition & 1 deletion resources/views/partials/taglist.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
?>
@if( $treat_tags_as == 'tags')
@if($taglist->first())
<div id="taglist" class="taglist">
<div id="taglist" class="taglist" data-default-tag="{{ \App\Setting::fetch('default_tag') }}">
<div class="tag white current" data-tag="all">All</div>
@foreach($taglist as $tag)
<div class="tag link{{ title_color($tag->colour) }}" style="background-color: {{ $tag->colour }}" data-tag="tag-{{ $tag->tag_url }}">{{ $tag->title }}</div>
Expand Down
22 changes: 22 additions & 0 deletions tests/Feature/DashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Item;
use App\ItemTag;
use App\Setting;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

Expand Down Expand Up @@ -80,4 +81,25 @@ public function test_displays_tags_on_the_dash(): void
$response->assertSee('Tag 1');
$response->assertSee('Tag 2');
}

public function test_dash_exposes_the_configured_default_tag(): void
{
$this->seed();

Setting::where('key', 'treat_tags_as')->update(['value' => 'tags']);
Setting::where('key', 'default_tag')->update(['value' => 'home-dashboard']);

Item::factory()->create([
'title' => 'Home',
'url' => 'home-dashboard',
'type' => 1,
'pinned' => 1,
'user_id' => 0,
]);

$response = $this->get('/');

$response->assertStatus(200);
$response->assertSee('data-default-tag="home-dashboard"', false);
}
}
61 changes: 61 additions & 0 deletions tests/Unit/database/seeders/SettingsSeederTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

namespace Tests\Unit\database\seeders;

use App\Item;
use App\Setting;
use Database\Seeders\SettingsSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class SettingsSeederTest extends TestCase
{
use RefreshDatabase;

/**
* All language keys are defined in all languages based on the en language file.
*/
Expand All @@ -18,4 +23,60 @@ public function test_returns_a_jsonmap_with_same_amount_of_items_as_language_dir

$this->assertTrue(count($languageMap) === count($languageDirectories));
}

public function test_seeds_the_default_tag_setting(): void
{
$this->seed();

$setting = Setting::where('key', 'default_tag')->first();

$this->assertNotNull($setting);
$this->assertSame('select', $setting->type);
$this->assertSame(4, (int) $setting->group_id);
}

public function test_default_tag_edit_value_lists_all_tags_and_a_none_option(): void
{
$this->seed();

Item::factory()->create([
'title' => 'Home',
'url' => 'home-dashboard',
'type' => 1,
'pinned' => 1,
'user_id' => 0,
]);
Item::factory()->create([
'title' => 'Media',
'url' => 'media',
'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,
]);

$setting = Setting::where('key', 'default_tag')->first();
$editValue = $setting->edit_value;

// A "none" option with an empty value, using the shared translation key.
$this->assertStringContainsString('<option value="" ', $editValue);
$this->assertStringContainsString(__('app.options.none'), $editValue);

// One option per pinned tag: the slug as the value, the raw title as the label.
$this->assertStringContainsString('value="home-dashboard"', $editValue);
$this->assertStringContainsString('>Home</option>', $editValue);
$this->assertStringContainsString('value="media"', $editValue);
$this->assertStringContainsString('>Media</option>', $editValue);

// The unpinned tag is excluded.
$this->assertStringNotContainsString('value="archive"', $editValue);
}
}
Loading