[#3112] added options to pin collections

This commit is contained in:
Gani Georgiev
2023-10-09 14:26:56 +03:00
parent eae16cc42c
commit 1f4bdfb867
36 changed files with 220 additions and 115 deletions
@@ -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}
+11 -3
View File
@@ -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 (_) {}
}
+2 -2
View File
@@ -112,7 +112,7 @@
padding: calc(var(--baseSpacing) - 5px) 0 var(--smSpacing);
border-right: 1px solid var(--baseAlt2Color);
& > * {
padding: 0 var(--smSpacing);
padding: 0 var(--xsSpacing);
}
.sidebar-content {
overflow-x: hidden;
@@ -162,7 +162,7 @@
align-items: center;
gap: 5px;
width: 100%;
margin: var(--baseSpacing) 0 var(--xsSpacing);
margin: var(--baseSpacing) 5px var(--xsSpacing);
font-weight: 600;
font-size: 1rem;
line-height: var(--smLineHeight);