[#3112] added options to pin collections
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<script>
|
||||
import { link } from "svelte-spa-router";
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
import tooltip from "@/actions/tooltip";
|
||||
import { hideControls } from "@/stores/app";
|
||||
import { collections, activeCollection, isCollectionsLoading } from "@/stores/collections";
|
||||
import CollectionUpsertPanel from "@/components/collections/CollectionUpsertPanel.svelte";
|
||||
|
||||
export let collection;
|
||||
export let pinnedIds;
|
||||
|
||||
$: isPinned = pinnedIds.includes(collection.id);
|
||||
|
||||
function toggleCollectionPin(collection) {
|
||||
if (pinnedIds.includes(collection.id)) {
|
||||
CommonHelper.removeByValue(pinnedIds, collection.id);
|
||||
} else {
|
||||
pinnedIds.push(collection.id);
|
||||
}
|
||||
|
||||
pinnedIds = pinnedIds;
|
||||
}
|
||||
</script>
|
||||
|
||||
<a
|
||||
href="/collections?collectionId={collection.id}"
|
||||
class="sidebar-list-item"
|
||||
title={collection.name}
|
||||
class:active={$activeCollection?.id === collection.id}
|
||||
use:link
|
||||
>
|
||||
<i class={CommonHelper.getCollectionTypeIcon(collection.type)} />
|
||||
<span class="txt m-r-auto">{collection.name}</span>
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<span
|
||||
class="btn btn-xs btn-circle btn-hint btn-transparent pin-collection"
|
||||
aria-label={"Pin collection"}
|
||||
use:tooltip={{ position: "right", text: (isPinned ? "Unpin" : "Pin") + " collection" }}
|
||||
on:click|preventDefault|stopPropagation={() => toggleCollectionPin(collection)}
|
||||
>
|
||||
{#if isPinned}
|
||||
<i class="ri-unpin-line" />
|
||||
{:else}
|
||||
<i class="ri-pushpin-line m-l-auto" />
|
||||
{/if}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<style lang="scss">
|
||||
.pin-collection {
|
||||
margin: 0 -5px 0 -15px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
i {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
a:hover .pin-collection {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,14 +1,22 @@
|
||||
<script>
|
||||
import { link } from "svelte-spa-router";
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
import tooltip from "@/actions/tooltip";
|
||||
import { hideControls } from "@/stores/app";
|
||||
import { collections, activeCollection, isCollectionsLoading } from "@/stores/collections";
|
||||
import CollectionUpsertPanel from "@/components/collections/CollectionUpsertPanel.svelte";
|
||||
import CollectionSidebarItem from "@/components/collections/CollectionSidebarItem.svelte";
|
||||
|
||||
const pinnedStorageKey = "@pinnedCollections";
|
||||
|
||||
let collectionPanel;
|
||||
let searchTerm = "";
|
||||
let pinnedIds = [];
|
||||
|
||||
loadPinned();
|
||||
|
||||
$: if ($collections) {
|
||||
syncPinned();
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
@@ -16,13 +24,18 @@
|
||||
|
||||
$: hasSearch = searchTerm !== "";
|
||||
|
||||
$: filtered = $collections.filter((collection) => {
|
||||
return (
|
||||
collection.id == searchTerm ||
|
||||
collection.name.replace(/\s+/g, "").toLowerCase().includes(normalizedSearch)
|
||||
);
|
||||
$: if (pinnedIds) {
|
||||
localStorage.setItem(pinnedStorageKey, JSON.stringify(pinnedIds));
|
||||
}
|
||||
|
||||
$: filtered = $collections.filter((c) => {
|
||||
return c.id == searchTerm || c.name.replace(/\s+/g, "").toLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
$: pinnedCollections = filtered.filter((c) => pinnedIds.includes(c.id));
|
||||
|
||||
$: unpinnedCollections = filtered.filter((c) => !pinnedIds.includes(c.id));
|
||||
|
||||
function selectCollection(collection) {
|
||||
$activeCollection = collection;
|
||||
}
|
||||
@@ -35,6 +48,21 @@
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function loadPinned() {
|
||||
pinnedIds = [];
|
||||
|
||||
try {
|
||||
const encoded = localStorage.getItem(pinnedStorageKey);
|
||||
if (encoded) {
|
||||
pinnedIds = JSON.parse(encoded) || [];
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
function syncPinned() {
|
||||
pinnedIds = pinnedIds.filter((id) => !!$collections.find((c) => c.id == id));
|
||||
}
|
||||
</script>
|
||||
|
||||
<aside class="page-sidebar collection-sidebar">
|
||||
@@ -66,22 +94,25 @@
|
||||
class:fade={$isCollectionsLoading}
|
||||
class:sidebar-content-compact={filtered.length > 20}
|
||||
>
|
||||
{#each filtered as collection (collection.id)}
|
||||
<a
|
||||
href="/collections?collectionId={collection.id}"
|
||||
class="sidebar-list-item"
|
||||
title={collection.name}
|
||||
class:active={$activeCollection?.id === collection.id}
|
||||
use:link
|
||||
>
|
||||
<i class={CommonHelper.getCollectionTypeIcon(collection.type)} />
|
||||
<span class="txt">{collection.name}</span>
|
||||
</a>
|
||||
{:else}
|
||||
{#if normalizedSearch.length}
|
||||
<p class="txt-hint m-t-10 m-b-10 txt-center">No collections found.</p>
|
||||
{#if pinnedCollections.length}
|
||||
<div class="sidebar-title">Pinned</div>
|
||||
{#each pinnedCollections as collection (collection.id)}
|
||||
<CollectionSidebarItem {collection} bind:pinnedIds />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if unpinnedCollections.length}
|
||||
{#if pinnedCollections.length}
|
||||
<div class="sidebar-title">Others</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{#each unpinnedCollections as collection (collection.id)}
|
||||
<CollectionSidebarItem {collection} bind:pinnedIds />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if normalizedSearch.length && !filtered.length}
|
||||
<p class="txt-hint m-t-10 m-b-10 txt-center">No collections found.</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !$hideControls}
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
let columnsTrigger;
|
||||
let hiddenColumns = [];
|
||||
let collumnsToHide = [];
|
||||
let hiddenColumnsKey = "";
|
||||
|
||||
$: if (collection?.id) {
|
||||
hiddenColumnsKey = collection.id + "@hiddenColumns";
|
||||
loadStoredHiddenColumns();
|
||||
clearList();
|
||||
}
|
||||
@@ -89,7 +91,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.setItem(collection?.id + "@hiddenCollumns", JSON.stringify(hiddenColumns));
|
||||
if (hiddenColumns.length) {
|
||||
localStorage.setItem(hiddenColumnsKey, JSON.stringify(hiddenColumns));
|
||||
} else {
|
||||
localStorage.removeItem(hiddenColumnsKey);
|
||||
}
|
||||
}
|
||||
|
||||
function loadStoredHiddenColumns() {
|
||||
@@ -100,8 +106,10 @@
|
||||
}
|
||||
|
||||
try {
|
||||
const encoded = localStorage.getItem(collection.id + "@hiddenCollumns");
|
||||
if (encoded) hiddenColumns = JSON.parse(encoded) || [];
|
||||
const encoded = localStorage.getItem(hiddenColumnsKey);
|
||||
if (encoded) {
|
||||
hiddenColumns = JSON.parse(encoded) || [];
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user