mirror of
https://github.com/brufdev/many-notes.git
synced 2026-05-25 04:39:07 -05:00
Add list of vault tags and their total counts
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user