Add list of vault tags and their total counts

This commit is contained in:
brufdev
2025-09-17 10:47:48 +01:00
parent e298af2907
commit c06f3f3559
3 changed files with 85 additions and 49 deletions
+19
View File
@@ -11,6 +11,7 @@ use App\Actions\ResolveTwoPaths;
use App\Actions\UpdateVault;
use App\Events\VaultFileSystemUpdatedEvent;
use App\Livewire\Forms\VaultNodeForm;
use App\Models\Tag;
use App\Models\User;
use App\Models\Vault;
use App\Models\VaultNode;
@@ -18,7 +19,9 @@ use Carbon\CarbonImmutable;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Renderless;
@@ -85,6 +88,22 @@ final class Show extends Component
->first();
}
/**
* @return Collection<int, Tag>
*/
#[Computed]
public function tags(): Collection
{
/** @var Collection<int, Tag> $tags */
$tags = ($this->selectedFile ? $this->selectedFile->tags() : $this->vault->tags())
->select(DB::raw('tags.id, tags.name, count(*) as total'))
->groupBy('tags.id')
->orderBy('tags.name')
->get();
return $tags;
}
public function checkPermission(): void
{
try {
+14
View File
@@ -10,12 +10,16 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
final class Vault extends Model
{
/** @use HasFactory<\Database\Factories\VaultFactory> */
use HasFactory;
use HasRelationships;
/**
* Get the associated user.
*
@@ -36,6 +40,16 @@ final class Vault extends Model
return $this->hasMany(VaultNode::class);
}
/**
* Get the tags for the vault.
*
* @return HasManyDeep<Model, $this>
*/
public function tags(): HasManyDeep
{
return $this->hasManyDeepFromRelations($this->nodes(), new VaultNode()->tags());
}
/**
* Get the associated templates node.
*
+52 -49
View File
@@ -160,61 +160,64 @@
:class="{ 'translate-x-0': isRightPanelOpen, '-translate-x-full hidden': !isRightPanelOpen }"
>
<div class="flex flex-col gap-4 px-4 overflow-y-auto">
<div class="flex flex-col w-full gap-2">
<h3>{{ __('Links') }}</h3>
<div class="flex flex-col gap-2 text-sm">
@if ($this->selectedFile && $this->selectedFile->links->count())
@foreach ($this->selectedFile->links as $link)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
@click.prevent="openFile({{ $link->id }})"
wire:key="file-link-{{ $link->id }}"
>
{{ $link->name }}
</a>
@endforeach
@else
<p>{{ __('No links found') }}</p>
@endif
@if ($this->selectedFile)
<div class="flex flex-col w-full gap-2">
<h3>{{ __('Links') }}</h3>
<div class="flex flex-col gap-2 text-sm">
@if ($this->selectedFile && $this->selectedFile->links->count())
@foreach ($this->selectedFile->links as $link)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
@click.prevent="openFile({{ $link->id }})"
wire:key="file-link-{{ $link->id }}"
>
{{ $link->name }}
</a>
@endforeach
@else
<p>{{ __('No links found') }}</p>
@endif
</div>
</div>
</div>
<div class="flex flex-col w-full gap-2">
<h3>{{ __('Backlinks') }}</h3>
<div class="flex flex-col gap-2 text-sm">
@if ($this->selectedFile && $this->selectedFile->backlinks->count())
@foreach ($this->selectedFile->backlinks as $link)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
wire:key="file-backlink-{{ $link->id }}"
@click.prevent="openFile({{ $link->id }})"
>
{{ $link->name }}
</a>
@endforeach
@else
<p>{{ __('No backlinks found') }}</p>
@endif
<div class="flex flex-col w-full gap-2">
<h3>{{ __('Backlinks') }}</h3>
<div class="flex flex-col gap-2 text-sm">
@if ($this->selectedFile && $this->selectedFile->backlinks->count())
@foreach ($this->selectedFile->backlinks as $link)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
wire:key="file-backlink-{{ $link->id }}"
@click.prevent="openFile({{ $link->id }})"
>
{{ $link->name }}
</a>
@endforeach
@else
<p>{{ __('No backlinks found') }}</p>
@endif
</div>
</div>
</div>
@endif
<div class="flex flex-col w-full gap-2">
<h3>{{ __('Tags') }}</h3>
<div class="flex flex-col gap-2 text-sm">
@if ($this->selectedFile && $this->selectedFile->tags->count())
@foreach ($this->selectedFile->tags as $tag)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
wire:key="file-tag-{{ $tag->id }}"
@click.prevent="$wire.dispatchTo('modals.search-node', 'open-modal', { search: 'tag:{{ $tag->name }}' })"
>
{{ $tag->name }}
</a>
@endforeach
@else
@forelse ($this->tags as $tag)
<a
class="text-primary-400 dark:text-primary-500 hover:text-primary-300 dark:hover:text-primary-600"
href=""
wire:key="file-tag-{{ $tag->id }}"
@click.prevent="$wire.dispatchTo('modals.search-node', 'open-modal', { search: 'tag:{{ $tag->name }}' })"
>
<span class="flex items-center justify-between w-full">
<span class="flex-grow overflow-hidden whitespace-nowrap text-ellipsis" title="{{ $tag->name }}">#{{ $tag->name }}</span>
<span class="pl-2 text-xs text-light-base-700 dark:text-base-400">{{ $tag->total }}</span>
</span>
</a>
@empty
<p>{{ __('No tags found') }}</p>
@endif
@endforelse
</div>
</div>
</div>